A list of marks with one typing mistake
Reading a file in Python means opening a text file and working on the lines inside it. Handling an error means the program carries on when the data is bad. Real data always has a typing mistake somewhere.
A teacher keeps marks in a text file. One line says "x" where a number should be. A good program skips that line and reports it. A careless one crashes.
By the end of this lesson
Note
I can read and write text files and handle an error.
Key words
| Word | What it means | Example |
|---|---|---|
| File | a named store of data on a disk | marks.txt |
| Line | one row of a text file, ended by a newline | |
| Split | to cut a string into a list at a chosen character | "ana,8".split(",") |
| Exception | an error that stops a program while it runs | |
| Handle | to catch an exception and carry on | |
| with | a keyword that opens a file and closes it for you |
The cells students fill in are left blank in this preview.
open reads a text file
A text file holds lines of text. open("marks.txt") opens it, and a for loop over it gives one line at a time. Each line still ends with a newline, which strip() removes.
Write with open("marks.txt") as file: and Python closes the file for you when the indented block ends. It is the safe way to open a file.
Make a small marks file
printf 'ana,8\nben,x\ncara,6\n' > marks.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read it with cat
cat marks.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read it with Python
python3 -c "for line in open('marks.txt'): print(line.strip())"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Mode w writes and erases the old file
A second word in open sets the mode. "r" reads and is the default. "w" writes, and it erases the old contents first. "a" appends to the end and keeps what is there.
Use file.write("text") to put text in. It adds no newline, so end each line with \n.
Save a program that writes a file
printf 'with open("hello.txt", "w") as f:\n f.write("Hello from Python\\n")\n' > writer.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run the program
python3 writer.pyShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read the file it wrote
cat hello.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
split and int turn a line into data
A line from a file is one string. line.split(",") cuts it at each comma and gives a list. The marks line ana,8 becomes ["ana", "8"].
The 8 is still text. int("8") turns it into the number 8, and then you can add it up.
Worked example: from a line to a number
| Step | Code | Result |
|---|---|---|
| Read a line | line | "ana,8\n" |
| Remove the newline | line.strip() | "ana,8" |
| Cut at the comma | line.strip().split(",") | ["ana", "8"] |
| Take the score | parts[1] | "8", still text |
| Make it a number | int(parts[1]) | 8 |
The cells students fill in are left blank in this preview.
Split three lines of marks
data = "ana,8\nben,x\ncara,6"
for line in data.splitlines():
parts = line.strip().split(",")
print(parts[0], "scored", parts[1])
# The 8 is still text. int(parts[1]) turns it into a number.
try and except catch an error
When something goes wrong, Python raises an exception and stops. int("x") raises ValueError: invalid literal for int() with base 10: 'x'.
Put the risky line in a try block. Add except ValueError: below, and the lines under it run instead of the crash. The program then carries on.
Skip the bad line and total the rest
lines = ["ana,8", "ben,x", "cara,6"]
total = 0
for line in lines:
parts = line.split(",")
try:
total = total + int(parts[1])
except ValueError:
print("Skipping bad line:", line)
print("Total:", total)
# Change "ben,x" to "ben,7" and run again.
A common mistake
Warning
Many people think a bare except: is the safe choice, because it catches everything. It also hides mistakes in your own code. Name the error you expect, such as except ValueError:, so any other fault still shows.
Going further
Change writer.py to open hello.txt with mode "a" instead of "w", and run it twice. Then read the file with cat and say how many lines you expect.
Try mode "w" again and compare. The difference between the two modes is one of the most common causes of lost data.