Input Validation
Unit ID: M06-U03 Estimated active time: 25-35 minutes
Validation enforces a contract
Suppose accepted hours may be:
- an exact integer from 0 to 40; or
- text containing an integer from 0 to 40 after outside whitespace is removed.
Booleans, missing values, decimal text, words, and out-of-range values are rejected.
Validate by type before operation
def parse_hours(raw_hours):
if type(raw_hours) is int:
hours = raw_hours
elif type(raw_hours) is str:
hours = int(raw_hours.strip())
else:
raise TypeError("hours must be an integer or integer text")
if not 0 <= hours <= 40:
raise ValueError("hours must be from 0 to 40")
return hours
The type branches prevent calling .strip() on an integer. Exact type rejects booleans.
Conversion is not validation by itself
int(3.8) produces 3, which silently changes the value. If decimal input is not allowed, reject floats instead of converting them.
int(True) produces 1, but a boolean is not an hour count under this contract.
Preserve raw input
Do not overwrite raw_hours. Store the validated result in hours. This keeps the transformation inspectable.
Validate at a clear boundary
Parse and validate when data enters the trusted part of the program. Downstream calculations can then rely on the documented result type and range.
Do not repeat inconsistent partial checks throughout the notebook.
Practice
Write expected results for 0, 40, -1, 41, " 8 ", "8.5", True, and None. Then run parse_hours() and record returned values or exception types.
Takeaway
Validation defines accepted representations, types, and ranges before unsafe operations. Conversion must not silently change disallowed input. Next, we will handle only the expected per-record exceptions while keeping useful details.
