Lecture 22
Chapter 11:
Exceptions
1
while True:
try:
weight = int(input("Enter weight (in pounds):
"))
height = int(input("Enter height (in inches):
"))
Example: bmi = (float(weight) / float(height * height)) *
try and except 703
print(f'BMI: {bmi}')
except ValueError:
print('Could not calculate health info.\n')
except ZeroDivisionError:
print('Invalid height entered. Must be > 0.')
break
while True:
try:
weight = int(input("Enter weight (in pounds):
"))
height = int(input("Enter height (in inches):
"))
bmi = (float(weight) / float(height * height)) *
Example: 703
try and except
and else except ValueError:
print('Could not calculate health info.\n')
except ZeroDivisionError:
print('Invalid height entered. Must be > 0.')
else:
print(f'BMI: {bmi}')
break
Using “finally” to clean up
• A programmer wants to execute code regardless of whether or not an exception
has been raised in a try block.
• Ex: If an exception occurs while reading data from a file, the file should still be closed using the
file.close() method, no matter if an exception interrupted the read operation.
• The finally clause of a try statement allows a programmer to specify clean-up
actions that are always executed.
try:
# some code that might raise an exception
except SomeException:
# handle the exception
finally:
# code that should always run, regardless of
whether an exception was raised
try:
file = open('example.txt', 'r')
# do some processing with the file
except IOError:
print('An error occurred while reading the file')
finally:
Example: file.close()
Using finally
to clean up • In this example, we're using finally to ensure that the file object is closed,
regardless of whether an exception occurred or not.
• If an IOError is raised while reading the file, the error message is printed,
and then the finally block is executed to close the file.
• If no exception is raised, the finally block is still executed to close the file.
• The finally block is a good way to ensure that important cleanup code is
always executed, even if an exception occurs.
nums = []
rd_nums = -1
my_file = input('Enter file name: ')
try:
print('Opening', my_file)
rd_nums = open(my_file, 'r') # Might cause IOError
Example: for line in rd_nums:
nums.append(int(line)) # Might cause ValueError
Using finally except IOError:
print(f'Could not find {my_file}')
to clean up except ValueError:
print(f'Could not read number from {my_file}')
finally:
print(f'Closing {my_file}')
if rd_nums != -1:
rd_nums.close()
print(f'Numbers found: {" ".join([str(n) for n in
nums])}')
What is raise?
• In programming, a "raise" statement is used to intentionally generate
an exception, or error, during the execution of a program.
Example: raise ValueError("Cannot divide by zero!")
How raising exceptions work?
• With raising exceptions method, the normal code is enclosed in a try
block.
• Code that detects an error can execute a raise statement, which
causes immediate exit from the try block and the execution of an
exception handler.
• The exception handler prints the argument passed by the raise
statement that brought execution.
Why do you need to raise an
exception?
• There are several reasons why a
programmer might choose to use a while True:
x = int(input("Enter the first integer:"))
raise statement: y = int(input("Enter the second integer:"))
1. Error handling: When a program try:
encounters an error or exception that if y == 0:
raise ZeroDivisionError("Cannot divide by
it cannot handle, it can use a raise zero!")
statement to generate an exception result = x/y
and halt the program's execution. print(result)
This can help the programmer identify break
the source of the error and take except ZeroDivisionError as e:
corrective action. print(e)
Why do you raise an
exception?
2. Control flow: A raise statement can be used to interrupt the normal flow of a
program and redirect it to a specific exception handler.
items = [1, 2, 'stop', 4, 5, 6, 7]
for item in items:
if item == 'stop':
raise StopIteration
# process the item here
Why do you raise an
exception?
3. Debugging: A raise statement can be used to intentionally trigger an
exception during the testing and debugging phase of software
development. This can help the programmer identify and isolate
problems in the code.
try:
x = int(input("Enter a number: "))
if x < 0:
raise ValueError("Sorry, no negative numbers allowed.")
except ValueError as e:
print(e)
Example:
Raising • In this example, if the user enters a negative number, a
exceptions ValueError exception will be raised with a custom error
message "Sorry, no negative numbers allowed.
• as keyword: When you catch an exception using a try-except
block, you can assign the exception instance to a variable (e.g.
e) using the as keyword.
• This allows you to access information about the exception, such as its
message, type, and traceback.
raising exceptions in BMI
example
• If in the BMI example, the programmer want to ensure that a user
enters only valid heights and weights (ex.: greater than 0).
• Thus, the programmer must introduce error-checking code.
• A naive approach to adding error-checking code is to intersperse if-
else statements throughout the normal code.
user_input = ''
while user_input != 'q':
weight = int(input('Enter weight (in pounds): '))
if weight < 0:
print('Invalid weight.')
else:
Example: '))
height = int(input('Enter height (in inches):
Raising if height <= 0:
exceptions print('Invalid height')
if (weight < 0) or (height <= 0):
print('Cannot compute info.')
else:
bmi = (float(weight) / float(height * height))
* 703
print(f'BMI: {bmi}')
user_input = input("Enter any key ('q' to quit): ")
user_input = ''
while user_input != 'q':
try:
weight = int(input('Enter weight (in pounds): '))
if weight < 0:
raise ValueError('Invalid weight.')
Example: height = int(input('Enter height (in inches): '))
Raising if height <= 0:
raise ValueError('Invalid height.')
exceptions
bmi = (float(weight) * 703) / (float(height * height))
print(f'BMI: {bmi}')
except ValueError as excpt:
print(excpt)
print('Could not calculate health info.\n')
user_input = input("Enter any key ('q' to quit): ")
Exceptions with functions
• The power of exceptions becomes even def division(x, y):
more clear when used within functions. if y == 0:
raise ValueError("Cannot divide by
zero!")
result = x/y
• If an exception is raised within a function return result
and is not handled within that function,
try:
then the function is immediately exited
division(10, 0)
and the calling function is checked for a except ValueError as e:
handler, and so on up the function call print(e)
else:
hierarchy.
print(result)
def get_weight():
weight = int(input('Enter weight (in pounds): '))
if weight < 0:
raise ValueError('Invalid weight.')
return weight
def get_height():
height = int(input('Enter height (in inches): '))
if height <= 0:
Example:
raise ValueError('Invalid height.')
return height
Exceptions user_input = ''
while user_input != 'q':
with try:
weight = get_weight()
functions height = get_height()
bmi = (float(weight) / float(height * height)) * 703
print(f'BMI: {bmi}')
except ValueError as excpt:
print(excpt)
print('Could not calculate health info.\n')
user_input = input("Enter any key ('q' to quit): ")
Custom exception types
• Custom exception types are user-defined exceptions that can be created in addition to the built-in
exceptions in a programming language.
• They allow you to define your own exception hierarchy with a specific set of exceptions that relate to
your program or application.
• A programmer creates a custom exception class CustomException(Exception):
type by creating a class that inherits from the pass
built-in Exception class:
• We can then raise this exception in our code if x < 0:
like any other exception: raise CustomException('x should be non
negative')
class LessThanZeroError(Exception):
def __init__(self, value):
self.value = value
Example: my_num = int(input('Enter number: '))
Custom
if my_num < 0:
exception raise LessThanZeroError('my_num must be greater than
types 0')
else:
print(f'my_num: {my_num}')
Problem
• Write a program that prompts the user to enter two integers and calculates their sum.
• However, if the user enters a non-integer input or a negative integer, the program should display an
error message and prompt the user to try again.
Hint: use raise statement to raise exceptions and then use try and except to handle those exceptions.
• Input: 2, -1 or -2, 3
• Output: Error: Integer must be non-negative
• Input: 2, 2
• Output: Result: 4
Solution
while True:
try:
x = int(input("Enter the first integer: "))
if x < 0:
raise ValueError("Integer must be non-negative")
y = int(input("Enter the second integer: "))
if y < 0:
raise ValueError("Integer must be non-negative")
result = x + y
print("Result:", result)
break
except ValueError as e:
print("Error:", str(e))
print("You can try again")