Errors and Exceptions:¶
When Python encounters a problem during code execution, this may or may not lead to a program crash. The technique that avoids a program crash is called error catching and handling. It is possible to build code that anticipates and tolerates errors and gives the user or the program a chance to keep going.
Python has a class of errors called Exceptions. Exceptions trigger specific messages that let the user understand what went wrong.
Exceptions are manageable errors that can be caught and reported without resulting in a program crash.¶
Exceptions in base python:¶
- SyntaxError - The written code doesn't conform to Python formatting standard.
- TypeError - The data type is not compatible with the operation (e.g. text string in arithmetic).
- ValueError - An exception caused when the data type is correct, but the value is incompatible. (e.g. a negative age).
- OSError - An unspecified error at the system level (hard disk is full, network connection is broken, etc.
- FileNotFoundError - File was not found in the location specified.
- PermissionError - Unable to enter the directory, read the file, or run the program because its permissions are controlled by another user.
Some material taken from: Miguel Grinberg blog
# TypeError
'a'/2
1/0
# Why does this trigger a NameError?
4 + x*3
# Example of ValueError with int()
num = int("hello")
#num = int("9")
We want to avoid unhandled errors, because they stop code execution.¶
In the example below, the variables result2
and result3
never come into existence, even though they do not depend on result1
. This is because the cell stops execution with the unhandled exception.
# Example of ValueError with math.factorial()
result = math.factorial(-5)
# The problem with unhandled exceptions is that the rest of the code is not executed.
result2 = math.acos(2)
result3 = math.erf(25)
How to handle exceptions?¶
- 'Look before you leap' error handling.
- 'Easier to ask for forgiveness than permission' with try/except blocks.
Python docs
The try statement works as follows.
- First, the try clause (the statement(s) between the try and except keywords) is executed.
- If no exception occurs, the except clause is skipped and execution of the try statement is finished.
- If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then, if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try/except block.
- If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with an error message.
# Example of ValueError with int()
try:
#num = int("hello")
num = int("9")
except ValueError as e:
print(f"Error: {e}")
# Example of ValueError with math.factorial()
import math
try:
result = math.factorial(-5)
except ValueError as e:
print(f"Error: {e}")
No exception handling¶
# No exception handling:
def div(num,denom):
nbyd = num/denom;
return nbyd
results = div(8,2);
print(results)
Look before you leap exception handling:¶
# Look before you leap exception handling:
def div(num,denom):
if denom != 0: # Avoid the case where zero is in the deominator
nbyd = num/denom;
else:
nbyd = np.nan; #Assign NaN if division fails.
return nbyd
#results = div(8,2);
#results = div(8,0);
#results = div('a',9);
print(results)
Easier to 'ask forgiveness than permission' exception handling.¶
# Easier to 'ask forgiveness than permission'
def div(num,denom):
try: # See if this will work, otherwise
nbyd = num/denom;
return nbyd
except RuntimeError as e:
print(f"this is the error: {e}")
except ValueError as e:
print(f"this is the error: {e}")
except ZeroDivisionError as e:
print(f"this is the error: {e}")
except:
print("Something went wrong");
results = div(8,0);
print(results). #If this print statement still executes, that means the program kept going.
Types of NumPy Errors¶
When working with NumPy, you might encounter the following types of errors:
- ValueError: Occurs when incorrect parameters are passed to a function.
- TypeError: This happens when the data type of an input doesn’t match what is expected.
- IndexError: Raised when an index is out of the array’s range.
- MemoryError: Triggered when memory allocation fails.
- RuntimeError: Occurs when unexpected issues arise during runtime.
Sources: Medium blog by Meng Li
import numpy as np
a = np.array([1, 2, 3], dtype=np.float64)
# Attempt to add a string to the array
try:
a += 'a'
except TypeError as e:
print(f"Error: {e}")
#print("Ensure all operands have consistent data types.")
import numpy as np
a = [1, 2, '3']
# Attempt to add a string to the array
s=0
for A in a:
try:
s += A
except TypeError as e:
print(f"Error: {e}")
else:
print(s)
import numpy as np
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5])
# Attempt to add two arrays
try:
c = a + b
except IndexError as e:
print(f"Error E1: {e}")
except ValueError as e:
print(f"Error E2: {e}")
# Use try and except to look for and handle an IndexError with numpy operations.
# Use try and except to look for and handle a TypeError using list array operations.
# Use try and except to look for and handle a ValueError with numpy operations.