Handling errors with try and except

Last lesson was about reading errors. This one is about planning for them. Some errors are bugs you should fix. Others are things that will happen no matter how good your code is: someone types "twelve" when you asked for a number, or divides by a friend count that turns out to be zero.

For those, Python lets you say "try this, and if it goes wrong in this specific way, do that instead":

text = "twelve"
try:
    age = int(text)
    print("Next year you will be", age + 1)
except ValueError:
    print("That was not a whole number.")

Python runs the try block. The moment a line inside it raises an error, it stops right there and jumps to the matching except block. If nothing goes wrong, the except block is skipped completely. Either way, the program keeps going afterwards instead of crashing.

Always name the error you expect. except ValueError: catches exactly the "that is not a number" problem. A bare except: catches everything, including your own typos, which turns a clear NameError into a silent mystery. Catch what you can actually deal with, and let the rest crash loudly so you can fix it.

You can have more than one except, and you can grab the error message with as:

try:
    result = 10 / int(text)
except ValueError:
    print("Not a number")
except ZeroDivisionError as e:
    print("Maths problem:", e)

Two optional extras: else runs only when the try block had no error, and finally runs no matter what. You will see finally used to tidy up, like closing a file.

A handy pattern is a function that returns a safe default when the input is bad, so the code that calls it never has to worry.

Try it yourself

Edit it. Break it. Run it again.
answers = ["14", "fifteen", "16", "", "17.5"]

for text in answers:
    try:
        age = int(text)
    except ValueError:
        print(repr(text), "is not a whole number, skipping it")
    else:
        print(repr(text), "is fine, next year:", age + 1)

try:
    print(10 / 0)
except ZeroDivisionError as e:
    print("Caught it:", e)
finally:
    print("This line always runs")
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

Your turn

Type it yourself. That is the whole trick.

1Safe number

Write to_int(text) that returns the text converted to a whole number, or returns 0 if the text is not a whole number. It must not crash.

def to_int(text):
    return int(text)
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

2Share the pizza

Write slices_each(slices, people) that returns how many whole slices each person gets (use //). If people is 0, return 0 instead of crashing. Catch only the error that dividing by zero raises.

def slices_each(slices, people):
    return slices // people
Ctrl/Cmd + Enter runs. Esc, then Tab, leaves the editor.

Code editor. Press Control or Command plus Enter to run the code. Tab indents; to move focus out of the editor, press Escape and then Tab.