Intermediate · Errors, modules and the standard library · topic 22 of 50 · 20 min
Errors and exceptions
Explanation
Two kinds of mistakes
A SyntaxError means the code is not valid Python at all, like a missing bracket. Python finds it before running anything. An exception is different: the code is valid, but something goes wrong while it runs, like dividing by zero or reading a key that is not in a dictionary.
Reading a traceback
Traceback (most recent call last):
File "shop.py", line 3, in <module>
print(total / count)
ZeroDivisionError: division by zeroStart at the last line: it names the error type (ZeroDivisionError) and gives a message (division by zero). The lines above it show the file, the line number and the exact code that failed. Most of the time, the last two lines tell you everything you need.
| Error | When it happens | Example that causes it |
|---|---|---|
| SyntaxError | The code is not valid Python | print("hi" |
| NameError | A name was never defined (often a typo) | print(totl) |
| TypeError | An operation gets the wrong type | "5" + 3 |
| ValueError | The type is right but the value is not | int("abc") |
| ZeroDivisionError | Dividing by zero | 10 / 0 |
| KeyError | A dictionary key is missing | marks["Ravi"] when there is no Ravi |
| IndexError | A list position does not exist | [10, 20][5] |
try and except
def to_number(text):
try:
return int(text)
except ValueError:
return None
print(to_number("42"))
print(to_number("forty"))Python runs the try block. If an exception happens there, it jumps to the matching except block. You can have several except blocks for different errors, and except ... as e gives you the error object so you can read its message.
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return "cannot divide by zero"
except TypeError as e:
return "bad input: " + str(e)
print(safe_divide(10, 4))
print(safe_divide(10, 0))
print(safe_divide(10, "2"))else and finally
else runs only when the try block finished with no exception. finally runs every time, error or not; it is the place for clean-up work such as closing a file or a connection.
def read_age(text):
try:
age = int(text)
except ValueError:
print("Not a number:", text)
else:
print("Age saved:", age)
finally:
print("Checked", text)
read_age("21")
read_age("twenty")Raising your own errors
def withdraw(balance, amount):
if amount <= 0:
raise ValueError("amount must be more than 0, got " + str(amount))
if amount > balance:
raise ValueError("not enough balance")
return balance - amount
try:
withdraw(500, 800)
except ValueError as e:
print("Error:", e)Watch the lesson
Errors and exceptions · 1/7
Every programmer sees errors every day. In this lesson you will learn to read them and to handle them calmly.
Prefer a video by a teacher? Find free videos on “python try except exceptions tutorial” on YouTube ↗
In real life: Adding up a messy sales register
Meena keeps her shop sales in a spreadsheet. Some cells are empty and some say NA. A program that calls int() on every cell would crash on the first bad one. With try and except it adds the good numbers and simply counts the bad cells, so she can fix them later.
entries = ["450", "1200", "NA", "", "300"]
total = 0
skipped = 0
for item in entries:
try:
total += int(item)
except ValueError:
skipped += 1
print("Total:", total, "| skipped cells:", skipped)Practice (0/3 done)
Write safe_int(text, default=0) that returns int(text), but returns default when the text is not a whole number. safe_int("42") gives 42, safe_int("abc") gives 0 and safe_int("", -1) gives -1.
Write average(nums) that returns the average of a list of numbers. If the list is empty, raise ValueError with a message that contains the word "empty" (do not let a ZeroDivisionError escape).
Write stock_of(stock, item) that returns stock[item], or 0 when the item is not in the dictionary. Use try and except KeyError.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.