Statement of Completion#7940c263
Control Flow
medium
Master Advanced Exception Handling: Your Next-Level Python Power!
Resolution
Activities
Project.ipynb
Control Flow Management for Exception Handling¶
Activities¶
Activity 1: Define a Custom Exception¶
In [14]:
# Write your code here...
class InvalidNameError(Exception):
pass
def validate_name(user):
if not user.get("name"):
raise InvalidNameError("Name cannot be empty")
return None
validate_name({"name": "JJ"})
In [15]:
validate_name({"name": ""})
--------------------------------------------------------------------------- InvalidNameError Traceback (most recent call last) Cell In[15], line 1 ----> 1 validate_name({"name": ""}) Cell In[14], line 7, in validate_name(user) 5 def validate_name(user): 6 if not user.get("name"): ----> 7 raise InvalidNameError("Name cannot be empty") 8 return None InvalidNameError: Name cannot be empty
In [17]:
try:
user = {'name': ''}
validate_name(user)
except InvalidNameError as e:
print(f"Validation Error: {e}")
Validation Error: Name cannot be empty
Activity 2: Raise a Custom Exception - InvalidMarksError¶
In [18]:
class InvalidMarksError(Exception):
pass
def positive_marks(marks):
if marks < 0:
raise InvalidMarksError("Marks cannot be negative")
return None
In [19]:
positive_marks(3)
In [20]:
try:
positive_marks(-10)
except InvalidMarksError as e:
print(f"Error: {e}")
Error: Marks cannot be negative
Activity 3: Use Custom Exception in a Function¶
In [42]:
class InvalidMarksError(Exception):
pass
def validate_marks(marks):
if marks < 0 or marks > 100:
raise InvalidMarksError("Marks assigned is out of range")
return None
In [43]:
try:
validate_marks(-2)
except InvalidMarksError as e:
print(f"Error: {e}")
Error: Marks assigned is out of range
Activity 4: Raise Custom Exception for Missing Data¶
In [48]:
class IncompleteDataError(Exception):
pass
def incomplete_data_check(marks):
if marks is None:
raise IncompleteDataError("The data is incomplete!")
return None
In [50]:
try:
incomplete_data_check(None)
except IncompleteDataError as e:
print(f"Error: {e}")
Error: The data is incomplete!
Activity 5: Raise Custom Exception for Wrong Data Type¶
In [54]:
class WrongDataType(Exception):
pass
def validate_marks(marks):
if not isinstance(marks, int):
raise WrongDataType("Invalid marks type assigned")
return None
In [55]:
try:
validate_marks(3.2)
except WrongDataType as e:
print(f"Error: {e}")
Error: Invalid marks type assigned
Activity 6: Using try-except
with Error Message¶
In [66]:
def division_by_zero():
try:
result = 100 / 0
except ZeroDivisionError as e:
return f"Caught Exception {e}"
In [67]:
division_by_zero()
Out[67]:
'Caught Exception division by zero'
Activity 7: Using finally Without except¶
In [81]:
def finally_without_except():
try:
msg1 = "Welcome to the system."
finally:
msg2 = "Goodbye."
return msg1 + msg2
In [82]:
finally_without_except()
Out[82]:
'Welcome to the system.Goodbye.'
Activity 8: Raise Multiple Custom Exceptions¶
In [86]:
class MarksError(Exception):
pass
class GradeError(Exception):
pass
def validatemarks(student):
try:
if student["marks"] < 0 or student["marks"] > 100:
raise MarksError("Invalid marks Error")
if student["grade"] is None:
raise GradeError("Grade not assigned")
except (MarksError, GradeError) as e:
return f"Exception caught {e}"
validatemarks({"grade": None, "marks": 100})
Out[86]:
'Exception caught Grade not assigned'
Activity 9: Implement Nested Try-Except Blocks¶
In [88]:
def zero_division():
try:
try:
result = 100 / 0
except ZeroDivisionError:
print("Handled inside inner block")
except:
print("Outer block")
In [89]:
zero_division()
Handled inside inner block
Activity 10. Chain Exceptions Using raise from
¶
In [93]:
def chain_exceptions():
try:
raise ValueError()
except ValueError as e:
raise TypeError("High-level error") from e
chain_exceptions()
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[93], line 3, in chain_exceptions() 2 try: ----> 3 raise ValueError() 4 except ValueError as e: ValueError: The above exception was the direct cause of the following exception: TypeError Traceback (most recent call last) Cell In[93], line 7 4 except ValueError as e: 5 raise TypeError("High-level error") from e ----> 7 chain_exceptions() Cell In[93], line 5, in chain_exceptions() 3 raise ValueError() 4 except ValueError as e: ----> 5 raise TypeError("High-level error") from e TypeError: High-level error
Activity 11. Raise the Custom Exception for Missing Grade¶
In [98]:
class InvalidGradeType(Exception):
pass
def check_character(grade):
if not (isinstance(grade, str) and len(grade) == 1):
raise InvalidGradeType("Invalid grade type")
check_character("aa")
--------------------------------------------------------------------------- InvalidGradeType Traceback (most recent call last) Cell In[98], line 9 5 if len(grade) != 1: 6 raise InvalidGradeType("Invalid grade type") ----> 9 check_character("aa") Cell In[98], line 6, in check_character(grade) 4 def check_character(grade): 5 if len(grade) != 1: ----> 6 raise InvalidGradeType("Invalid grade type") InvalidGradeType: Invalid grade type
Activity 12. Handle Missing File¶
In [103]:
def read_grades_header(file):
try:
with open(file, "r") as f:
header = f.readline()
except FileNotFoundError:
print("File not found.")
except Exception as e:
print("An unexpected error occurred: {e}")
In [ ]:
Author-.ipynb
Master the art of robust code by learning to handle errors like a pro!¶
Errors are inevitable in programming, but great developers anticipate, handle, and learn from them! In this lab, you’ll work with a User Profile Validation System to practice exception handling techniques.
By the end, you’ll be able to write code that:
- Fails gracefully instead of crashing
- Provides clear error messages
- Maintains reliability under unexpected conditions
Cheers to your journey ahead!🎉
Custom Exceptions & Basic Error Handling¶
Activity 1. Define a Custom Exception¶
Define a custom exception class InvalidNameError
that create
Create InvalidNameError
inherited from Exception
.
Solution:
class InvalidNameError(Exception):
pass
def validate_name(user):
if not user["name"]:
raise InvalidNameError("Name cannot be empty")
In [ ]:
class InvalidNameError(Exception):
pass
def validate_name(user):
if not user["name"]:
raise InvalidNameError("Name cannot be empty")
temp = {"id": 1, "age":16, "name":""}
validate_name(temp)
In [ ]:
# Assertion
temp = {"id": 1, "age":16, "name":""}
try:
validate_name(temp)
except InvalidNameError as e:
assert str(e) == "Name cannot be empty", "Test failed for InvalidNameError handling"
finally:
del temp
assert 'InvalidNameError' in globals(), "Function 'my_global_function' is not declared globally."
Activity 2. Raise a Custom Exception - InvalidMarksError¶
Assign a negative number to the marks variable. Check if the value is negative, and if so, raise InvalidMarksError
with a custom error message.
In [ ]:
class InvalidMarksError(Exception):
pass
def positive_marks(marks):
if marks < 0:
raise InvalidMarksError("Marks cannot be negative")
In [ ]:
# Assertion:
try:
positive_marks(-1)
except InvalidMarksError as e:
assert str(e) == "Marks cannot be negative", "Test failed for Invalid error handling"
Activity 3. Use Custom Exception in a Function¶
Define a function called validate_marks(name, marks)
that checks whether marks are less than 0 or more than 100. If they are, raise the InvalidMarksError
. This helps encapsulate validation logic.
In [ ]:
# Solution
class InvalidMarksError(Exception):
pass
def validate_marks(name, marks):
if marks < 0 or marks > 100:
raise InvalidMarksError(name, marks)
validate_marks("Alice", -10)
Activity 4. Raise Custom Exception for Missing Data¶
Simulate missing data by assigning None to the marks variable. Write a condition that raises InvalidMarksError
if marks is None, indicating that the data is incomplete.
In [ ]:
class InvalidMarksError(Exception):
pass
marks = None
if marks is None:
raise InvalidMarksError("The data is incomplete!")
Activity 5. Raise Custom Exception for Wrong Data Type¶
Assign a string to the marks variable to simulate a data type error. Use isinstance()
to check if the value is not an integer. If so, raise the InvalidMarksError
with the student name and invalid value.
In [ ]:
class WrongDataType(Exception):
pass
def validate_marks(marks):
if not isinstance(marks, int):
raise WrongDataType("StudentX", marks)
Activity 6. Using try-except
with Error Message¶
Implement a try-except block to handle a division operation. Inside the try block, attempt to divide 100 by 0, which will raise a ZeroDivisionError
. In the except block, catch the ZeroDivisionError
and print the message Caught Exception:
followed by the exception details.
In [ ]:
def division_by_zero():
try:
result = 100 / 0
except ZeroDivisionError as e:
print("Caught Exception:", e)
Activity 7. Using finally Without except¶
Implement a function named finally_without_except
. Inside this function, use a try-finally block. In the try block, print Welcome to the system
The finally block should always execute afterward, ensuring that Goodbye
is printed regardless of any exceptions that may occur in the try block.
In [ ]:
def finally_without_except():
try:
print("Welcome to the system.")
finally:
print("Goodbye.")
Activity 8. Raise Multiple Custom Exceptions¶
Define custom InvalidMarksError
and MissingGradeError
exceptions. Create a validatemarks()
function that takes a student dictionary as input. Inside a try
block, raise InvalidMarksError
if marks are less than 0
or more than 100
, And raise MissingGradeError
if student grade is None
. At the end, using except
block catch these specific errors and prints the exception message as Exception caught: {e}
with e as the exception object.
In [ ]:
class InvalidMarksError(Exception):
pass
class MissingGradeError(Exception):
pass
def validatemarks(student):
try:
if student["marks"] < 0 or student["marks"] > 100:
raise InvalidMarksError("Invalid marks for " + student["name"])
if student["grade"] is None:
raise MissingGradeError("Grade not assigned for " + student["name"])
except (InvalidMarksError, MissingGradeError) as e:
print("Exception caught:", e)
Using try-except-else-finally and Chain Exception¶
Activity 9. Nesting try-except Blocks¶
Create a nested try-except
block. Inside the outer try, define an inner try that divides by zero. Catch the ZeroDivisionError
in the inner except, and print a message Handled inside inner block
. Print the message in Outer block
in outer except block.
In [ ]:
# Solution
def zero_division():
try:
try:
result = 100 / 0
except ZeroDivisionError:
print("Handled inside inner block")
except:
print("Outer block")
Activity 10. Chain Exceptions Using raise from¶
Manually raise a ValueError
, and then raise a TypeError
from it using raise from. This simulates chaining low-level errors into higher-level ones.
In [ ]:
def chain_exceptions():
try:
raise ValueError("Low-level error")
except ValueError as e:
raise TypeError("High-level error") from e
Activity 11. Raise the custom Exception for Missing Grade¶
Define the custom exception InvalidGradeType
. Then, create a function check_character()
that accepts a grade
. Within the function, verify if the input grade is not a single character string. If this validation fails, raise the InvalidGradeType
exception indicating an Invalid grade type
.
In [ ]:
class InvalidGradeType(Exception):
pass
grade = "A"
def check_character(grade):
if not (isinstance(grade, str) and len(grade) == 1):
raise InvalidGradeType("Invalid grade type")
Activity 12. Handling a Missing File¶
Implement a function, read_grades_header()
, that attempts to open a specified file and read its header. Use a try block to handle the FileNotFoundError
by printing an error message if the file does not exist. Handle any other unexpected errors with a generic exception message as An unexpected error occurred: {e}
, here e
is the exception occured. The goal is to ensure that the program does not crash and provides meaningful feedback to the user.
In [ ]:
def read_grades_header(filepath):
try:
with open(filepath, 'r') as f:
header = f.readline().strip()
print(f"File found. Header: {header}")
except FileNotFoundError:
print(f"Error: File not found at {filepath}")
except Exception as e: # Catch other potential errors
print(f"An unexpected error occurred: {e}")
# Use function assertion and provide test cases to check
In [ ]:
read_grades_header("file/folder.csv")
Activity 7. Using finally Without except¶
Implement a function named finally_without_except
. Inside this function, use a try-finally block. In the try block, print Welcome to the system
The finally block should always execute afterward, ensuring that Goodbye
is printed regardless of any exceptions that may occur in the try block.
Solution:
def finally_without_except():
try:
print("Welcome to the system.")
finally:
print("Goodbye.")