Skip to content

ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ

Reading a traceback

4 min read

You've met error messages since your first programs. Most people glance at one, feel a jolt, and start changing code at random. An error message isn't a verdict on you or your program: it's Python telling you where to look. By the end of this lesson you'll read one in the right order and know, in seconds, what went wrong and where.

Read from the bottom

a() calls b(), and b() divides by zero. Predict the last line this prints, then reveal it.

ውጤቱን ገምቱ

Decide before you look. Guessing wrong is how this sticks.

def a():
    return b()

def b():
    return 1 / 0

a()

Python prints

Traceback (most recent call last):
  File "<your code>", line 7, in <module>
    a()
    ~^^
  File "<your code>", line 2, in a
    return b()
  File "<your code>", line 5, in b
    return 1 / 0
           ~~^~~
ZeroDivisionError: division by zero

The last line says what went wrong: ZeroDivisionError: division by zero. Most people read from the top and stop at 'Traceback (most recent call last):', or take the first File line (line 7) as the place it happened. It happened on line 5, in b, the last File line.

When something goes wrong while a program runs, Python raises an . Nothing here handles it, so the program stops and prints a . It looks long, but it has three parts, and you read them from the bottom up:

  1. The last line says what went wrong. Before the colon is the ; after it, the .
  2. The lines just above it say where: line 5, in b, then the code on that line. Under it, ~~^~~ underlines the part that failed: the ^ is under the /.
  3. The lines above that say how the program got there: line 7 called a(), and line 2, inside a, called b().

Those File lines are the from lesson 5.7, oldest call first. That's what "most recent call last" means: the newest call, where the error happened, is at the bottom.

The error travels up the stack

Step through the same program. When b raises the error, its frame stops and the error goes to a, the call that was waiting for it. a doesn't deal with it either, so a stops too, and the error reaches the global code. Nothing there deals with it, so the program stops.

An error leaves b, then a

Press Next to run one line at a time. Each arrow shows the object a name refers to. Each call gets its own frame of names, below the frame that called it.

def a():
return b()
def b():
return 1 / 0
a()

Frames, oldest first: global.

Step 1 of 7

Step 1 of 7. Line 1: def a():. Nothing in memory changed.

The diagram and the traceback show the same stack: global at the top, the newest frame at the bottom. Lesson 7.2 shows how a frame can catch an error on its way up.

Here's a program with three calls. Run it and read the traceback bottom-up:

def price_of(item):
    prices = {"tea": 15, "coffee": 45}
    return prices[item]

def report(order):
    for item in order:
        print(item, price_of(item))

report(["tea", "tibs"])

In the editor, press Escape then Tab to move on.

ጥያቄ

Which function had the line that failed?

Now change "tibs" to "coffee" and run it again: both prices print, and there's no traceback.

Errors you've met so far

Each type means one kind of problem. Its message tells you the details.

Error typeExample, then its message
NameErrorprint(totl) when the name is total: name 'totl' is not defined. Did you mean: 'total'?
TypeError"Age: " + 25: can only concatenate str (not "int") to str
ValueErrorint("five"): invalid literal for int() with base 10: 'five'
IndexError[1, 2, 3][3]: list index out of range
KeyError{"tea": 15}["coffee"]: 'coffee'
ZeroDivisionError10 / 0: division by zero
AttributeError"abc".push("d"): 'str' object has no attribute 'push'
SyntaxErrorprint("Selam": '(' was never closed
IndentationErroran if with no indented line under it: expected an indented block after 'if' statement on line 1

A SyntaxError or IndentationError has no Traceback line: Python found it before running anything, so no line ran and no call was made.

The last File line shows where Python noticed the problem. That isn't always where you made the mistake:

መልመጃ

Three errors, one at a time

This order total has three mistakes. Before each run, predict the error type and the line. Run it, read the traceback bottom-up, fix that one mistake, and run again. When all three are fixed, it prints:

Output
Items: 3
Total: 75 birr

Your code

prices = {"tea": 15, "coffee": 45}
order = ["tea", "coffe", "tea"]
total = 0
for item in order:
    total = total + prices[item]
print("Items: " + len(order))
print(f"Total: {totl} birr")

In the editor, press Escape then Tab to move on.

መፍትሄውን አሳይ

This is one way to solve it, not the only one. If yours prints the same thing, it works.

prices = {"tea": 15, "coffee": 45}
order = ["tea", "coffee", "tea"]
total = 0
for item in order:
    total = total + prices[item]
print("Items: " + str(len(order)))
print(f"Total: {total} birr")

ዋና ዋና ነጥቦች

  • A traceback is the call stack, printed, oldest call first: "most recent call last".
  • Read it from the bottom: the last line has the error type and message; the line above says where.
  • The lines above that show the calls that led there.
  • Where Python noticed isn't always where the mistake is: follow the value back.