Chapter 2 · Apprentice

Reading errors and debugging

When Python can't run a line, it stops and raises an exception — an error with a name and a message. This is help, not punishment: the message usually tells you exactly what and where.

Read a traceback from the bottom up. The last line is the error type and message; the lines above show the chain of calls that led there, with the file and line number. Common early types:

  • TypeError — an operation on the wrong type, e.g. adding a number to a string.
  • NameError — using a name that doesn't exist (typo, or used before defined).
  • ValueError — right type, wrong value, e.g. int("abc").
  • IndexError / KeyError — reaching for a list position or dict key that isn't there.
  • SyntaxError — the code isn't valid Python at all (often a missing : or bracket).

Debugging is just: read the error, find the line, check what type each value actually is (a quick print(type(x), x) works wonders), fix the mismatch.

Syntax

# A traceback looks like this — read the LAST line first:
#   Traceback (most recent call last):
#     File "app.py", line 2, in <module>
#       return subtotal + tax
#   TypeError: unsupported operand type(s) for +: 'int' and 'str'

Worked examples

A TypeError from mixing types — and the fix

def order_total(subtotal, tax):
    return subtotal + int(tax)   # tax arrived as "3"; convert it

print(order_total(10, "3"))      # 13

Diagnosing with print(type(...))

tax = "3"
print(type(tax), tax)   # <class 'str'> 3  → it's text, not a number

ValueError vs TypeError

int("3")      # 3      — fine
# int("abc")  # ValueError: invalid literal for int()
# 1 + "1"     # TypeError: unsupported operand type(s)

Common mistakes & gotchas

Reading the traceback top-down

The most useful line is the last one (the error type + message). The frames above are the path that got there. Beginners often read the first line and miss the actual error at the bottom.

The line reported isn't always where the bug is

Python reports where it *failed*, but the cause might be earlier — e.g. a variable was set to the wrong type ten lines up. The traceback is the start of the hunt, not always the answer.

SyntaxError points just AFTER the problem

A SyntaxError caret often sits at the token after the real mistake (a missing : or ) on the line above). If the flagged line looks fine, check the end of the previous line.

Why it matters

You will read far more errors than you write features. Developers who are fluent at reading tracebacks fix bugs in seconds that leave others stuck for an hour — it's one of the highest-leverage skills in the whole craft.