Read Type Hints at Boundaries
Interpret parameter, collection-item, optional, and return hints without treating them as runtime conversion or validation.
A function boundary tells us what enters a function and what comes back. Type hints add the expected kinds of values to that boundary. They help us read a function before following every statement in its body.
Read the Parameter Hint
The measurement program's mean function accepts readings that may include an
unavailable value:
Read the parameter from the inside outward:
float | None one reading may be a float or None
list[float | None] readings is expected to be a list of those values
The vertical bar means or in a type hint. It does not perform a Boolean operation when the function runs. The hint describes the values that the loop is written to handle.
For the familiar input,
readings = [18.5, None, 24.0, 21.5, 19.0, 23.5]
the loop skips None and computes from five floating-point values. The hint
makes that possibility visible at the call boundary rather than leaving a
reader to discover it only inside the loop.
Q1. Interpret the collection hint
What does readings: list[float | None] say about the expected argument?
Select one choice, then check.
HintRead from the inside outward
First interpret float | None. Then place that item type inside list[...].
SolutionEach list item has two allowed forms
The argument is expected to be a list. Each item in that list may be a
floating-point number or None.
Read the Return Hint
The arrow introduces the expected return type:
-> float | None
The function returns a float when at least one numerical reading is available.
It returns None when the list is empty or every item is None.
The return hint tells callers to consider both outcomes. It does not say that
the result is always a number merely because the function is named mean.
Code that formats or adds the result should first decide what None means in
that context.
Q2. Account for the optional result
Which call is expected to return None under this function's contract?
Select one choice, then check.
HintCount available numbers
The function returns None only when count remains zero.
SolutionNo available value produces no mean
mean([None, None]) skips both items, leaving count == 0, so the function
returns None.
Hints Describe; the Function Still Decides
Ordinary Python does not use these hints to convert or validate arguments. If a caller passes a string, the hint does not turn it into a float:
mean(["18.5"])
The function still runs its ordinary statements. Eventually total += reading
tries to add a float and a string, so the program fails. The annotation made the
expected input clear, but it did not enforce that expectation.
The same limit applies to return hints. Python does not inspect every return statement and force it to match the annotation. Tests, validation, and careful implementation still have their own jobs.
A hint can describe a list of optional floats, but it does not capture every fact a later numerical program may need. For example, an array's axis meanings or complete shape require separate documentation and runtime inspection. Do not read those claims into a short type hint.
| Part | What it communicates | What it does not do |
|---|---|---|
| `readings: list[float | None]` | expected argument and item values |
| `-> float | None` | expected possible results |
Q3. Add hints without changing behavior
Add the parameter and return hints to the working function. Keep its total,
count, skip-None, and empty-result behavior unchanged.
Editable Python
Ready to run.
HintAnnotate only the signature
Replace the first line with
def mean(readings: list[float | None]) -> float | None:.
SolutionState the existing boundary
def mean(readings: list[float | None]) -> float | None:
No statement in the body needs to change. The hints describe the behavior already implemented by the total and count loop.
Type hints make expected parameter, collection-item, and return values visible
at a boundary. X | None names a legitimate optional value; it does not
convert, validate, or enforce one. The next lesson uses the same annotation
syntax to declare the fields of a plain result record.