Errors and Exceptions
When an operation cannot be completed, Python raises an exception. An exception that is not handled propagates up the call stack and terminates the program, printing a traceback that lists the call sequence leading to the failure. Read a traceback from the bottom: the last line names the exception and its message, and the lines above show where it occurred.
The exceptions encountered most often are:
| Exception | Cause |
|---|---|
ValueError |
Correct type, unusable value. int("abc") |
TypeError |
Wrong type. "a" + 1 |
KeyError |
Dictionary key not present |
IndexError |
Sequence index out of range |
FileNotFoundError |
Opening a file that does not exist |
ZeroDivisionError |
Division by zero |
AttributeError |
Attribute or method not defined on the object |
Handling exceptions
A try block runs code that may fail; an except clause names the exception
to handle and the action to take. Only the named exception is caught, and only
within the try block.
120 skipping abc 45
Catch the narrowest exception that covers the expected failure. A bare except:
catches everything, including KeyboardInterrupt and genuine defects such as a
misspelled variable name, converting a visible failure into silent incorrect
behaviour. If several exception types warrant the same response, name them as a
tuple: except (ValueError, TypeError):.
Binding the exception with as gives access to its message, which is worth
including in any diagnostic.
ValueError - invalid literal for int() with base 10: 'abc'
else and finally
An else block runs only if the try block raised nothing. It separates the
code that might fail from the code that depends on its success, keeping the
try block as small as possible. A finally block runs unconditionally and is
used for cleanup.
parsed 120 done
Raising exceptions
Raise an exception when a function receives input it cannot process. Failing immediately, at the point where the problem is detectable, produces a far more useful traceback than allowing an invalid value to propagate and fail later.
Choose the type that describes the problem: ValueError for an unusable value,
TypeError for the wrong type.
error: sequence is empty
Task
Write safe_ratio(values). It receives a list of strings. Convert each to an
integer, and return the mean of those that convert, rounded to two decimal
places. Strings that do not represent a whole number are skipped. If none
convert, return the string "no valid values".
Collect the valid numbers first and decide what to return afterwards; computing a mean requires knowing the count, which is not available until the loop ends.
Test cases · 3
| # | via | input | expected stdout |
|---|---|---|---|
| 1 | stdin | 120 abc 45 | 82.5 |
| 2 | stdin | abc def | no valid values |
| 3 | stdin | 10 20 30 | 20.0 |
Hints · 2
01Hint
Collect the valid numbers in a list first, then decide what to return.
02Hint
Catching ValueError around int() is enough; no other exception applies.