Module 10 - Exception Handling Header

Module 10 - Exception Handling

Introducing Exception Handling

try and except:

Exception handling is a crucial aspect of writing robust and reliable code. It allows you to gracefully handle and recover from runtime errors or exceptional situations that may occur during program execution. Without it, as you may have already discovered, the Python program will crash (stop running) when it encounters all kinds of errors.  Python provides the try and except statements to implement exception handling.

The general structure of a try and except block in Python is as follows:

try:
# Code that might raise an exception
except ExceptionType:
# Code to handle the exception

The try block encloses the code that might raise an exception. If an exception occurs within the try block, it is caught by the corresponding except block. The except block specifies the type of exception it can handle. You can have multiple except blocks to handle different types of exceptions.

Notice that in the try and except block, the code is indented as with loops and if…else statements.

else:

The else block is an optional block that follows the try-except block. It is executed only if no exception occurs in the try block. It allows you to specify code that should run when the try block executes successfully.

Example:

try:
result = 10 / 2 # No exception
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
else:
print("Result:", result)

In this example, since no exception occurs during the division, the code in the else block is executed, printing the result.

finally:

The finally block is an optional block that follows the try-except or try-except-else blocks. It is executed regardless of whether an exception occurs or not. It is typically used to define cleanup code that must be executed, such as closing files or releasing resources.

Example:

try:
file = open("data.txt", "r")
# Code to read the file
except FileNotFoundError:
print("Error: File not found.")
finally:
file.close() # Close the file regardless of exception occurrence

In this example, the finally block ensures that the file is closed, even if an exception occurs while reading the file.

raise:

The raise statement is used to manually raise an exception in Python. It allows you to create custom exceptions or handle exceptional cases that may not be caught by existing exception types.

Example:

def validate_age(age):
if age < 0:
raise ValueError("Age cannot be negative.")
elif age > 120:
raise ValueError("Invalid age.")
else:
print("Valid age.")

try:
validate_age(150)
except ValueError as ve:
print("Error:", str(ve))
 

In this example, the validate_age function raises a ValueError if the age is negative or exceeds 120. The corresponding except block catches the exception and prints an error message.

These are the main statements associated with try and except in Python. Understanding their usage and knowing when to use each statement is essential for effective exception handling in your programs.



Two Strategies for Exception Handling

Introducing Data Validation:

Data validation is the process of ensuring that data meets specific requirements or constraints before using it in a program. It helps prevent errors and ensures the correctness and integrity of the data.

There are two common strategies for data validation:

  1. Look Before You Leap (LBYL): This strategy involves checking the validity of data before performing an operation. It typically uses conditional statements or boolean expressions to validate the data upfront. LBYL follows the principle of "checking first" to avoid potential errors.
  2. Easier to Ask for Forgiveness than Permission (EAFP): This strategy assumes that valid data will be provided, and errors will be handled through exception handling. EAFP follows the principle of "trying first" and relying on exception handling to address exceptional situations.

Combining LBYL and EAFP:

In practice, a combination of both strategies is often used to achieve comprehensive data validation and exception handling.

First, use LBYL techniques, such as conditional statements, to check for simple and straightforward validation conditions. These conditions could include checking data types, range bounds, or basic formatting requirements.

Next, rely on EAFP techniques, using try and except blocks, to handle more complex validation scenarios or situations where LBYL checks may not be sufficient. Exception handling allows you to catch and handle unexpected errors or exceptional cases that could not be anticipated with LBYL checks alone.

Example:

Let's consider an example where we have to divide two numbers entered by the user. We'll use a combination of LBYL and EAFP techniques to handle data validation and exception handling:

def divide_numbers():
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))

if denominator == 0:
raise ValueError("Denominator cannot be zero.")

result = numerator / denominator
print("Result:", result)
except ValueError as ve:
print("Value Error:", str(ve))
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
except Exception as e:
print("An error occurred:", str(e))

# Testing the divide_numbers function
divide_numbers()
 


In this example:

  • We use LBYL techniques by checking if the denominator is zero before performing the division.
  • If the denominator is zero, we raise a ValueError using the raise statement.
  • We use EAFP techniques by using try and except blocks to handle potential exceptions, such as ValueError (raised by us) and ZeroDivisionError (raised by the division operation).
  • If any other unexpected exception occurs, the final except block catches and handles it.
  • By combining LBYL and EAFP strategies, we ensure that the data is validated and exceptions are handled appropriately, providing a more robust and reliable program.

Remember, it's important to choose the appropriate strategy based on the specific data validation requirements and potential exceptions that may occur in your program.

Videos for Module 10 - Exception Handling

10-1: Introduction to Error Handling (1:40)

10-2: LBYL - Look Before You Leap Error Handling (2:44)

10-3: EAFP - Easier to Ask Forgiveness Error Handling (1:48)

10-4: LBYL vs EAFP Code Explanation (3:34)

10-5: Named Exceptions (3:36)

10-6: Else and Finally With Try / Except (2:36)

10-7: S10 Explanation (2:09)

10-8: A10 Explanation (2:13)

10-9 Where Do I Add Error Handling (9:01)

Key Terms for Module 10 - Exception Handling

No terms have been published for this module.

Quiz Yourself - Module 10 - Exception Handling

Test your knowledge of this module by choosing options below. You can keep trying until you get the right answer.

Skip to the Next Question 

Activities for this Module

S10 - Error Pokemon

Note: Sandbox assignments are designed to be formative activities that are somewhat open-ended. To get the most value, spend some time playing around as you code.

I call this assignment “Error Pokemon” because it in, you’ve gotta catch ‘em all. (See what I did there?) Ok, but actually – one of the best ways to learn about errors, error messages and erro types is to cause them ON PURPOSE.  That’s right. We are going to crash our program this week in all the ways we can think of.

Read, and then run the following code in PyCharm:

strName = "Bill"
intAge = 48
strSentence = strName + " is " + intAge + " years old."

You should have gotten the following error message:

TypeError: can only concatenate str (not "int") to str

Below are the 10 most common error types in Python, along with an explanation of each type and some example code that will produce the error.

SyntaxError
This error occurs when Python can't understand what you wrote because of a typo or mistake in the order of your code, like missing punctuation or incorrect spelling.

if x == 1 
    print("x is 1") 



NameError
This happens when you try to use a variable or function name that Python doesn't recognize because it hasn't been defined earlier in your code.

print(age) 



TypeError
You see this error when you try to do something with a data type that doesn't make sense, like adding a number to a piece of text.

'1' + 2 
# Trying to add a string to an integer 



IndexError
This error pops up when you try to look at a position in a list that doesn't exist. For example, if a list has 3 items, but you ask for the 4th.

mylist = [1, 2, 3] 
print(mylist[3]) 



KeyError
This occurs when you try to access a dictionary item with a key that isn't part of the dictionary.

mydict = {'name': 'John'}
print(mydict['age']) 



AttributeError
You get this error when you request an attribute or method on an object that doesn't support it, like trying to use a function that doesn't exist for that type of object.

mylist = [1, 2, 3]
mylist.addItem(4) 



ValueError
This error happens when you give a function a value that it can understand in terms of type, but it's not a valid value, like trying to turn a text that isn't a number into an integer.

int('xyz') 



ZeroDivisionError
This one is straightforward: it happens any time you try to divide a number by zero.

x = 1 / 0



ImportError
This error happens when Python can't find the module or library that you've tried to import.

import nonExistentModule 



IndentationError
Python uses spaces at the start of lines to organize code, and if these spaces are off, you'll see this error.

def new_function():
print("Hello") 


For this sandbox challenge, pick any 5 of the above types of errors, and write your own code that would produce that kind of error.

A10 - Robust Employee Database

The Challenge

Take the Employee Database application you developed in Module 7, and make it crash proof using both LBYL and EAFP techniques.

Constraints / Success Criteria

  • You must use both LBYL and EAFP type error handling.
  • Your code should be functional without errors, regardless of user input.
  • Your UI should recover and redirect the user when bad input is provided.
  • All code must be commented.
  • Use only what we have covered in this class up to this point

Submission Type

Please submit the complete program as a .py file.