Practical 13: Exception Handling Exercises
Objective
In this lab, you will look at exception handling exercises.
Submission Date:
Prerequisites
- Basic knowledge of Python syntax
- Understanding of lists and functions in Python
- Familiarity with time complexity concepts (optional, but helpful)
Lab Steps
Step 1: Simple Python Exception Handling Errors
In this example, dividing number by 0 raises a ZeroDivisionError. The try block contains the code that might cause an exception and the except block handles the exception, printing an error message instead of stopping the program.
# Simple Exception Handling Example
n = 10
try:
res = n / 0 # This will raise a ZeroDivisionError
except ZeroDivisionError:
print("Can't be divided by zero!")
Value Error
float('z')
Index Error
x = []
print(x[2])
Invalid operations TypeError, NameError, AttributeError
a = 1
print('a = ' + a, length(a), a._x)
Step 2: Catching Specific Exceptions
Exception Handling with try, except, else and finally blocks.
def dividefunction(x, y):
try:
z = x/y
except TypeError:
print("Type Error: Cannot divide number by string")
except ZeroDivisionError:
print("Zero Division Error: Cannot divide by zero")
except:
print("Unknown Error")
else:
print(z)
finally:
print("End of the program")
dividefunction(10, 0)
dividefunction(10, "hello")
Step 3: Raising Exceptions
We raise an exception in Python using the raise keyword followed by an instance of the exception class that we want to trigger. We can choose from built-in exceptions or define our own custom exceptions by inheriting from Python’s built-in Exception class.
def set(age):
if age < 0:
raise ValueError("Age cannot be negative.")
print(f"Age set to {age}")
try:
set(-5)
except ValueError as e:
print(e)
Step 4: User defined exceptions
Create your own Exception classes to handle application specific exceptions caused by business rule violations. All user-defined exception classes inherit from Exception class.
class InvalidAgeError(Exception): # Step 1: Subclass the Exception class
'''Raises InvalidAgeError when age is invalid '''
def __init__(self, age, msg="Age must be between 0 and 120", error_code=1001):
self.age = age # Custom attributes
self.msg = msg
self.error_code = error_code
super().__init__(self.msg) # Call the base class constructor
def __str__(self): # Step 2: Customize the string representation of the exception
return f"[Error Code {self.error_code}] {self.age} -> {self.msg}"
def set_age(age):
if age < 0 or age > 120:
raise InvalidAgeError(age) # Step 3: Raising the custom exception
else:
print(f"Age set to: {age}")
try: # Step 4: Handling the custom exception with further info
set_age(150) # This will raise the custom exception
except InvalidAgeError as e:
print(e)
Step 5: Unit test example
Steps to write test case:
- Import unittest
- Create a class that inherits from the TestCase class
- Add methods inside the class by adding self as the first argument
- Use the self.assertEqual() method on the TestCase class
- Execute the test case using unittest.main()
import unittest
def triangle(height):
pattern = ''
for i in range(1, height + 1):
for j in range(i):
pattern += "* "
pattern += '\n'
return pattern
class testTriangle(unittest.TestCase):
def test_triangle_positive_height(self):
self.assertEqual(triangle(5), "* \n* * \n* * * \n* * * * \n* * * * * \n", 'Height must be a positive integer')
def test_triangle_zero_height(self):
self.assertEqual(triangle(0),'', 'Height must be a positive integer')
def test_triangle_negative_height(self):
self.assertEqual(triangle(-5),'', 'Height must be a positive integer')
unittest.main()
1. Either run the code with
python3 <script_name.py>
2. Or comment out the unittest.main() line
# unittest.main()
And run the following section of the code with
python3 -m unittest <script_name.py>
Step 6: Unit test example on testing raising of exception
The code can be modified to handle checking of exception raising upon receiving invalid parameters.
import unittest
def triangle(height):
pattern = ''
if type(height) not in [int, float]:
raise TypeError("The height must be a real number")
if height < 0:
raise ValueError("The height cannot be a negative number")
for i in range(1, height + 1):
for j in range(i):
pattern += "* "
pattern += '\n'
return pattern
class testTriangle(unittest.TestCase):
def test_triangle_positive_height(self):
self.assertEqual(triangle(5), "* \n* * \n* * * \n* * * * \n* * * * * \n", 'Height must be a positive integer')
def test_values(self):
self.assertRaises(ValueError, triangle, -2)
def test_types(self):
self.assertRaises(TypeError, triangle, 3+5j)
self.assertRaises(TypeError, triangle, True)
self.assertRaises(TypeError, triangle, "radius")
unittest.main()
Exercises for Students
- Implement exception handling and unit tests
Conclusion
In this lab, you've implemented some exception handling and unit testing.