Errors and Exceptions #
- Errors: Issues in the syntax or runtime of a program that cause it to stop.
- Exceptions: Errors detected during execution.
Handling errors/exceptions is essential!
Types of Errors #
Below you’ll find some types of errors. Please spot and fix them.
Syntax Errors #
print("Hello World
Runtime Errors #
x = 10 / 0
Difficult to handle beforehand.
Logical Errors #
Also called bugs. Here is a program to sum up to numbers 1 to 5 inclusively.
total = 0
for i in range(1, 5):
total += i
print(total)
The program prints 10 even though I’m expecting 15!
Exceptions and Handling them #
try-except
block
#
try:
num = int(input("Enter a number: "))
print(10 / num)
except ZeroDivisionError:
print("You cannot divide by zero.")
except ValueError:
print("Please enter a valid number.")
using except
and finally
#
except:
will catch any exception, regardless of its type.
>>> try:
... 1 / 0
... except:
... print("Error happened")
...
Error happened
>>> try:
... int("string here")
... except:
... print("Error happened")
...
Error happened
>>>
Using plain except
is not recommended for error handling, as it may catch exceptions you don’t intent to catch.
Using except
(with the exception type specified) you can also catch the object representing the exception and then use it in the error handling block:
try:
{}['Invalid key']
except Exception as e:
type = e.__class__.__name__
message = e.args[0]
print(f"{type}: {message} occurred. Exiting...")
finally
will be executed in any case, regardless if an exception happens in the try block or not:
try:
file = open("example.txt", "r")
content = file.read()
print(content)
except FileNotFoundError:
print("File not found.")
finally:
print("Execution complete.")
Exercise (10 min) #
Given the following hashtable:
capitals = {
"Tokyo": 13960000, # Japan
"Ottawa": 1016000, # Canada
"Brasilia": 3055149, # Brazil
"Cairo": 10230350, # Egypt
"Helsinki": 658864 # Finland
}
city = input("What's the city? ")
population = capitals[city]
print(f"{city} has the population of {population}")
write code that lets the user ask for the city name for which it will display the population. Safely handle KeyError
exception letting the user know that there is no data for given city.
Debugging basics #
- Print statements
- IDE tools (debugger)
- Common errors to look for: indentation, incorrect data types, off-by-one errors.
def sum_list(numbers):
result = 0
for num in numbers:
result += num
return result
print(sum_list([1, 2, 3, "4"])) # Debug this!
Clean Code Basics #
Some basic rules:
- No Dead Code
- No Useless Comments
- Good Formatting
- Use meaningful variable names.
- No Magic Constants -> extract then into named constants at the top of the file
- No Copy & Paste code -> DRY (Don’t Repeat Yourself), and/or use functions
- Make sure there is a Main (
main()
) Function
When refactoring, even before applying these rules, you must first understand the program. Only then you can proceed.
Run the program and capture its behaviour for all valid/required/important inputs. This will guide you showing you whether your refactored program still works as it used to.
Example: Refactor the following code:
import random
a = []
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
a.append(int(random.random() * 100))
c = 0
# last = None
# for new in a:
# if last == new:
# a.remove(new)
# last = new
for i in range(0,10): # here we loop
if (a[i]%7== 0):
c += 1
if (a[i]%11==0):
c += 1
if (a[i] % 7 == 0):
print(a[i], "is divisible by 7 or 11")
if (a[i] % 11 == 0):
print(a[i], "is divisible by 7 or 11")
print("found", c, "numbers divisible by 7 or 11")
Homework (graded) #
Exception Handling #
Replicate the UNIX wc
command in Python:
- Prompt the user for a file name.
- Try to open the file and print the number of sentences (newlines), words and characters in the file.
- Handle exception if the file is not found (FileNotFoundError).
Illustrative behaviour of wc
:
$ wc /etc/passwd
56 97 3258 /etc/passwd
$ wc does_not_exist
wc: does_not_exist: No such file or directory
Refactoring #
Refactor the following program:
import datetime
# Ask user for birth year
a = input("Enter your age: ")
a = int(a)
# Check if user is an adult
if a >= 18:
print("You are an adult.")
if a < 18:
print("You are not an adult.")
z = 100
# Check if user is a child
if a < 13:
print("You are a child.")
if a >= 13:
print("You are not a child.")
# Check if user is a teenager
if a >= 13 and a < 18:
print("You are a teenager.")
if a < 13 or a >= 18:
print("You are not a teenager.")
# Check if user is a senior citizen
if a >= 65:
print("You are a senior citizen.")
if a < 65:
print("You are not a senior citizen.")
x = a * 2 - a
Make sure to follow the refactoring (clean code) rules highlighted above.