Error handling in python: part 3
Thinking of where our program might go wrong is never ending. However, there are situations where you can predict the most common types of errors and plan for their occurrence. In this post we will learn how to test for specific error exceptions in Python.
Different types of errors
As part of this series of tutorials (1, 2), we have been working on a program called
bmi_calc.py. This program takes the weight and height of the user and returns their body mass index (BMI). One of the lines in this program is:
weight = float(sys.argv) # in kg
There are two errors that typically occur with this type of statement. First, the user may forgot to provide command-line arguments when using our program, which would mean
sys.argv is indexing a non-existent value. This is similar to having
x = [1.2, 42.2, 24.3, 39.0] and then trying to access the value at
x. This is an
IndexError in Python.
Second, the command-line argument provided by the user may not be a numerical value that can be converted to a floating point number. For example,
float('sixty') both return an error. This is called a
ValueError in Python.
In the previous version of our program, we jumped to the
except block of code regardless of what type of error occurred. This means that
bmi_cal.py 60kg 1.7m would get the error
This program needs two inputs, weight (kg) and height (m), which would be confusing given that two inputs were provided. Let’s fix this situation by testing for, and responding to, specific errors.
Testing for specific exceptions
Here is a new version of our program where we handle
ValueError in dedicated exception blocks:
import sys try: weight = float(sys.argv) # in kg height = float(sys.argv) # in meters except IndexError: print('This program needs two inputs, weight (kg) and height (m)') print('example: python bmi_calc.py 75 1.7') sys.exit(1) # Abort program except ValueError: print ('Weight (kg) and height (m) must be pure numbers.') sys.exit(1) bmi = weight/height**2 print(bmi)
If the program is run without 2 command-line arguments,
sys.argv will generate an
IndexError and cause our program to jump to the code in the first exception block. However, if the program is run with non-numerical command-line arguments,
float() will generate a
ValueError and our program will jump to the code in the second exception block.
In addition to the possibility of creating your own error types (see section 8.5 of the Python docs), Python has many built-in error types. Some of the most common are listed below:
IndexError: Indexing out of range (e.g.,
x=['me', 'you', 'them'],
ValueError: Invalid conversion (e.g.,
NameError: Using an uninitialized variable (e.g.,
xdoes not exist).
ZeroDivisionError: Dividing by zero (e.g.,
x = 42.0/0).
SyntaxError: Illegal use of Python key word or grammatical mistake (e.g.,
forr i in range(10)).
TypeError: Operation between two incompatible data types (e.g.,
Here is the output of the new version of our program:
$ python bmi_calc.py This program needs two inputs, weight (kg) and height (m) example: python bmi_calc.py 75 1.7 $ python bmi_calc.py 75kg 1.7 Weight (kg) and height (m) must be a pure number. $ python bmi_calc.py 75 1.7 25.95155709342561
Testing for specific errors allows us to provide more appropriate error messages to the users of our program. In the next post, we will learn how to
raise exceptions and gain complete control over how our program handles errors.