Rocket's fuel report works fine for three days. On the fourth day the report is for a brand new ship with no fuel tanks yet. The shell fills with a long red traceback.
"Three different line numbers," he says. "Which one is the real problem?"
Raven reads the traceback from the top, then from the bottom. "What do you notice?" she asks. "Each line is one step of a trail. It goes from the line you ran, into a function, into another function."
Nova projects the trail as glowing footprints. "Let's debug together," she says. "Python lists the calls in order, oldest first. The last footprint is where it finally stopped."
Rocket starts at the bottom and follows the trail back up.
# average_fuel.py
def average(numbers):
return sum(numbers) / len(numbers)
def report(tanks):
print("Average fuel:", average(tanks))
report([80, 60, 70])
report([]) The first report works. The second one stops with this traceback. Newer versions of Python also add lines of ^ marks under the trouble spot:
Average fuel: 70.0
Traceback (most recent call last):
File "average_fuel.py", line 9, in <module>
report([])
File "average_fuel.py", line 6, in report
print("Average fuel:", average(tanks))
File "average_fuel.py", line 3, in average
return sum(numbers) / len(numbers)
ZeroDivisionError: division by zero Here is a second trail to follow. This time the error is a KeyError, three calls deep.
# probe_battery.py
def battery_of(probe):
return probe["battery"]
def show(probe):
print(probe["name"], "battery:", battery_of(probe))
show({"name": "Probe 7", "battery": 87})
show({"name": "Probe 9"}) Probe 7 battery: 87
Traceback (most recent call last):
File "probe_battery.py", line 9, in <module>
show({"name": "Probe 9"})
File "probe_battery.py", line 6, in show
print(probe["name"], "battery:", battery_of(probe))
File "probe_battery.py", line 3, in battery_of
return probe["battery"]
KeyError: 'battery' | Statement | True or false? |
|---|---|
| The last line of a traceback names the error. | ? |
| The first File line is where the error finally happened. | ? |
| Lines printed before the error still appear. | ? |
| A traceback can mention more than one function. | ? |
A long traceback is just a trail of calls, and the bottom tells you where to start. Tomorrow you will meet the most common errors and a bug that has no error message at all.