14.4 Handling exceptions
Learning objectives
By the end of this section you should be able to
Describe two exceptions that may occur when reading files. Write try/except statements that handle built-in exceptions.
Runtime errors
Various errors may occur when reading a file:
FileNotFoundError: The filename or path is invalid.IndexError/ValueError: The file's format is invalid.Other errors caused by invalid contents of a file.
When an error occurs, the program terminates with an error message.
Example 1 Typo in a file
A file named food_order.txt has the following contents:
5 sandwiches
4 chips
1 pickle
soft drinks
The following program expects each line of the file to begin with an integer:
for line in open("food_order.txt"):
space = line.index(" ")
qty = int(line[:space])
item = line[space+1:-1]
print(qty, item)
Unfortunately, the line "soft drinks" does not begin with an integer. As a result, the program terminates and displays an error message:
Traceback (most recent call last):
File "food_order.py", line 3
qty = int(line[:space])
ValueError: invalid literal for int() with base 10: 'soft'
Try and except
Programs can be designed to handle exceptions, rather than terminate. A try statement runs code that might raise an exception. An except clause runs code in response to the exception.
Example 2 Try to open a file
The following program, named try_open.py , asks the user for a filename and counts the number of lines in the file.
name = input("Enter a filename: ")
try:
file = open(name)
lines = file.readlines()
count = len(lines)
print(name, "has", count, "lines")
except FileNotFoundError:
print("File not found:", name)
print("Have a nice day!")
When running this program with the input try_open.py , the name of the program file, the output is:
Enter a filename: try_open.py
try_open.py has 9 lines
Have a nice day!
If the filename does not exist, a FileNotFoundError is raised on line 3. The program then jumps to the except clause on line 7 and continues to run. The resulting output is:
Enter a filename: try_open.txt
File not found: try_open.txt
Have a nice day!
Note
Predicting output with exceptions
For each code snippet, what is the output?
Note
Type analyzer
Analysis programs often need to find numbers in large bodies of text. How can a program tell if a string like "123.45" represents a number? One approach is to use exceptions:
Try converting the string to an integer. If no ValueError is raised, then the string represents an integer. Otherwise, try converting the string to a float. If no ValueError is raised, then the string represents a float. Otherwise, the string does not represent a number.
Implement the get_type function using this approach. The provided main block calls get_type for each word in a file. get_type should return either "int", "float", or "str", based on the word. The output for the provided data.txt is:
str: Hello
int: 100
str: times!
float: 3.14159
str: is
str: pi.
def get_type(word):
# TODO return "int", "float", or "str"
if __name__ == "__main__":
for line in open("data.txt"):
for word in line.split():
print(get_type(word), word, sep=": ")
Note
United countries
Write a program that prompts the user to input a word and a filename. The program should print each line of the file that contains the word. Here is an example run of the program (user input in bold):
Enter a word: United
Enter a filename: countries.csv
United Arab Emirates,9890402,83600,118
United Kingdom,67886011,241930,281
United States of America,331002651,9147420,36
This example uses a file named countries.csv based on the alphabetical list of countries from Worldometer. Each line of the file includes a country's name, population, land area, and population density, separated by commas.
The user might incorrectly type the filename (Ex: countries.txt instead of countries.csv ). Your program should output an error message if the file is not found, and keep prompting the user to input a filename until the file is found:
...
Enter a filename: countries
File not found: countries
Enter a filename: countries.txt
File not found: countries.txt
Enter a filename: countries.csv
...
Hint: Try to open the file specified by the user. A FileNotFoundError is raised if the filename is invalid.
word = input("Enter a word: ")
# Step 1: Prompt for a filename until the file is found.
# Step 2: Look for the word on each line of the file.