- Recognise the most common exceptions
- Catch an error with
tryandexceptand keep the program running - Use
else,finallyandraise
You have written a calculator. The user types “twelve” instead of a number, or divides by zero — and the program stops with a red error message. Nobody likes a program like that! A good program is ready for mistakes: it recognises the problem, explains it clearly to the user and carries on.
What are exceptions?
There are two kinds of errors. Syntax errors (SyntaxError) are mistakes in how the code is written, and the program does not even start. When the code is written correctly but something goes wrong while it runs, Python raises an exception. If the exception is not caught, the program stops and Python shows a “traceback” — an error report:
Traceback (most recent call last):
File "main.py", line 2, in <module>
print(10 / count)
ZeroDivisionError: division by zero| Exception | When it happens | Example |
|---|---|---|
ValueError | the type is right but the value is unsuitable | int('abc') |
TypeError | the operation is not possible for this type | '5' + 5 |
ZeroDivisionError | division by zero | 10 / 0 |
IndexError | there is no such index | [1, 2][5] |
KeyError | the dictionary has no such key | {}['a'] |
NameError | no variable has this name | print(scor) |
try and except
We put code that might fail inside a try block. If an exception happens, Python skips the rest of the try block and jumps to the matching except block. After that, the program continues normally.
text = 'abc'
try:
number = int(text)
print('Number:', number)
except ValueError:
print('That is not a number!')
print('The program continues.')▸ Expected output
That is not a number! The program continues.
text to '25' and compare the result.One try can have several except blocks — each catches its own type of exception. Writing except ... as e stores the exception itself in the variable e; if you print it, you see Python's explanation.
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
print('Cannot divide by zero!')
except TypeError as e:
print('Wrong type:', e)
return None
print(safe_divide(10, 2))
print(safe_divide(5, 0))
print(safe_divide(5, 'x'))▸ Expected output
5.0 Cannot divide by zero! None Wrong type: unsupported operand type(s) for /: 'int' and 'str' None
else and finally
- The
elseblock runs only if thetryblock finished without an error — put the work with the successful result there. - The
finallyblock always runs — whether there was an error or not. It is usually used to wrap things up: closing a file, writing a message.
for value in ['42', 'seven']:
try:
n = int(value)
except ValueError:
print(f'{value}: not a number')
else:
print(f'{value}: doubled is {n * 2}')
finally:
print('checked', value)▸ Expected output
42: doubled is 84 checked 42 seven: not a number checked seven
raise: raising your own exception
Sometimes everything is fine for Python but not for your program: for example, an age cannot be negative. In such cases you can raise an exception yourself with raise. The code below imitates a user's answers and accepts the first valid age:
answers = ['abc', '-3', '14']
for answer in answers:
try:
age = int(answer)
if age <= 0:
raise ValueError('age must be positive')
except ValueError as e:
print(f'Bad input {answer}: {e}')
else:
print('Accepted age:', age)
break▸ Expected output
Bad input abc: invalid literal for int() with base 10: 'abc' Bad input -3: age must be positive Accepted age: 14
Convert the strings in data to numbers with int() and add them up. The program must not stop on an item that cannot be converted: catch the error with try/except ValueError and print Skipped: followed by that item. At the end print Total: and the sum.
data = ['12', 'seven', '30', '4.5', '8']
total = 0
# for each item: try to add int(item) to total,
# on ValueError print Skipped: and the item
# print Total: and total▸ Expected output
Skipped: seven Skipped: 4.5 Total: 50
A warehouse has 100 notebooks. Write a function sell(stock, count) that raises ValueError('count must be positive') if count is zero or negative, raises ValueError('not enough in stock') if it is more than the stock, and otherwise returns how many are left. The loop in the starter code tries every sale with try/except — do not change it.
# define sell(stock, count) here
stock = 100
for count in [30, -5, 90, 50]:
try:
stock = sell(stock, count)
print('Sold', count, '- left:', stock)
except ValueError as e:
print('Error:', e)▸ Expected output
Sold 30 - left: 70 Error: count must be positive Error: not enough in stock Sold 50 - left: 20
Key points
- An exception is an error that happens while the program runs; if it is not caught, the program stops.
tryholds the risky code, andexceptcatches a specific exception.elseruns only when there was no error;finallyalways runs.- You can raise your own exception with
raise:raise ValueError('...'). - The last line of a traceback shows the exception type and the reason.
Check yourself
10 questions. Every correct answer earns XP.
int('hello') raise?