Writing Defensive Code with Input Validation
Input validation is therefore the step of treating incoming data as something that must be checked or handled before the rest of the program depends on it.
One Error, Two Outcomes
An invalid value can produce two very different experiences depending on where Python is running. In the interactive interpreter, an error message is followed by a new prompt, so you can enter another command. In a script, the same kind of error causes the program to stop, and Python displays a traceback. This difference is the reason defensive programs must account for invalid input instead of assuming every value will be acceptable.
Following the Failure
A Fahrenheit Conversion Fails
A script reads a Fahrenheit temperature, converts the input to a floating-point number, calculates Celsius, and prints the result. What happens when the input is the string 'fred'?
- 1Read the input
The script receives the string 'fred' as the input value.
- 2Attempt conversion
The statement fahr =
float(inp)asks Python to convert the string to a floating-point number. - 3Raise the exception
The string 'fred' does not represent a valid floating-point number, so Python raises a
ValueError. - 4Stop execution
The calculation and print statements that follow the conversion do not execute.
- 5Read the traceback
The traceback identifies line 2 in
fahren.py, displays the statement that failed, and reports that 'fred' could not be converted to a float.
The script terminates immediately with a traceback before it calculates or prints the Celsius result.
The important control-flow fact is that the traceback is not merely a warning printed alongside a continuing program. In this situation, the traceback accompanies termination. Once the conversion raises the ValueError, Python does not continue to the later calculation or output statements in the script.
Understanding ValueError
A ValueError occurs when a function receives an argument of the correct type but an inappropriate value. During conversion, a string is an acceptable kind of argument for int() or float(), but the characters inside that string may not represent a valid number. For example, int('hello') raises a ValueError because the value cannot be interpreted as an integer. Likewise, attempting to convert a string containing letters, such as 'fred', to a floating-point number raises a ValueError.
Reading a Traceback
A traceback is a detailed report of the failure. It shows the sequence of function calls that led to the exception and narrows that sequence down to the line where the error occurred. In the fahren.py example, the message begins with 'Traceback (most recent call last)'. The entry 'File "fahren.py", line 2, in <module>' identifies the file, line number, and top-level script context. Python then displays the statement fahr = float(inp), followed by the exception type and explanation: ValueError: could not convert string to float: 'fred'.
| Traceback detail | What it tells you |
|---|---|
| Traceback (most recent call last) | The following information describes the call chain leading to the error. |
| File "fahren.py", line 2 | The failure occurred in fahren.py on line 2. |
| in <module> | The failing statement was at the top level of the script. |
| fahr = float(inp) | This is the statement where the failure occurred. |
| ValueError | The exception is a value-related conversion error. |
| could not convert string to float: 'fred' | The supplied value does not have a valid floating-point format. |
Reading the source example's traceback from general context to specific cause.
When a script fails, read the traceback from its context toward its final error message. First locate the file and line, then inspect the displayed statement, and finally use the exception type and message to understand why that statement failed.
Recovering at the Prompt
The interactive interpreter provides a forgiving environment for experimentation. If a conversion raises a ValueError there, Python displays the error message and returns to a new prompt. You can then try another command or provide a different value. This recovery applies to the interpreter session; it does not mean that the same unhandled error will allow a script to continue.
| Interactive interpreter | Python script |
|---|---|
| Shows an error message | Shows a traceback |
| Returns to a new prompt | Terminates immediately |
| Allows another command to be entered | Does not execute later statements |
The same unhandled error has different immediate consequences in an interactive session and a script.
Designing for Invalid Input
Defensive programming begins with recognizing that input can be invalid. A program that reads a temperature cannot assume that every input represents a number. If it sends an invalid value directly into float(), the script may terminate before performing its calculation. Input validation is therefore the step of treating incoming data as something that must be checked or handled before the rest of the program depends on it.
Mistakes to Avoid
Common mistake Assuming that an error in the interpreter means the program will continue when run as a script.
What it looks likeAn interactive session displays a ValueError and then shows a new prompt.
Why it failsA script does not return to an interactive prompt after an unhandled exception. It terminates with a traceback.
Do this insteadTest how the complete script responds to invalid input and plan explicit error handling.
Common mistake Treating every conversion failure as a type mismatch.
What it looks likePassing the string 'fred' to float().Why it failsThe argument is a string, but its value does not represent a valid floating-point number. This is a
ValueError.Do this insteadDistinguish the type of an argument from whether its value is appropriate for the requested conversion.
Common mistake Reading only the final exception name and ignoring the traceback location.
What it looks likeSeeing ValueError without checking the file, line number, or displayed statement.
Why it failsThe traceback provides the path to the failing statement and helps locate the source of the error.
Do this insteadRead the file and line information, inspect the displayed statement, and then interpret the exception message.
Common mistake Expecting statements after a failed conversion to run.
What it looks likeExpecting a temperature calculation and print operation to execute after fahr = float(inp) fails.
Why it failsThe script stops immediately when the exception occurs, so later statements are not executed.
Do this insteadTreat the failing statement as the point where normal control flow ends unless the exception is handled.
Practice the Diagnosis
A script receives the string 'hello' and attempts to convert it to an integer. Explain which exception you expect, whether the script continues to its next statement, and which parts of the traceback you would inspect first.
Hints
- Ask whether the value represents a valid integer.
- Separate the behavior of the interactive interpreter from the behavior of a script.
- Look for the file name, line number, failing statement, exception type, and explanatory message.
What do you think happens?
A script attempts a numeric conversion, the conversion raises a ValueError, and the next statement prints a message. Does the print statement execute?
Reveal answer
No, because the script terminates at the unhandled exception.
An unhandled ValueError in a script stops execution immediately. Python prints a traceback, and later statements do not execute.
Key Takeaways
- 1The interactive interpreter reports an error and returns to a prompt, while a script with an unhandled exception terminates.
- 2A
ValueErroroccurs when a function receives an argument whose value is inappropriate, including a string that cannot be converted to the requested numeric type. - 3A traceback identifies the call sequence, file, line, failing statement, exception type, and explanatory message.
- 4Statements after an unhandled exception in a script do not execute.
- 5Understanding termination motivates input validation and exception handling with try and except blocks.
At a glance
- The interpreter recovers to a new prompt after an error, but a script terminates with a traceback.
ValueErrordescribes an inappropriate value, such as a non-numeric string passed toint()orfloat().- A traceback is a roadmap from the call sequence to the exact failing line and exception message.
- Input validation and exception handling are necessary because real program input cannot be assumed to be valid.