date: 2024-05-11
title: python-exceptions
status: UNFINISHED
author:
- Dr. Eric Zhao
tags:
- Python
- NOTE
created: 2024-05-11T13:40
updated: 2024-06-11T01:15
publish: True
python-exceptions
With thanks to Dr. Eric Zhao from the Finance Mathematics Program, BNU-HKBU United International College
An exception is an event, which occurs during the execution of a program that disrupts the normal flow of the program's instructions. In general, when a Python script encounters a situation that it cannot cope with, it raises an exception.
An exception is a Python object that represents an error.
When a Python script raises an exception, it must either handle the exception immediately otherwise it terminates and quits.
fileDir = ''
f = open(fileDir, 'r')
f.close()
Explanation: Since Python cannot find the file under fileDir
, it will raise IOError
immediately. The program will terminate and Python will quit.
Python has many built-in Exceptions. You can check here.
In some cases, you would know that some suspicious code may raise an exception (e.g. irregular user input), you can defend your program by placing the suspicious code in a try block, and handles the potential exceptions explicitly in except block.
This is very helpful to write strong and reliable code.
try: # You do your error prone operations here;
#statement2
#statement3
except Exception1:
#If there is Exception1, then execute this block.
except Exception2:
#If there is Exception2, then execute this block.
else:
#If there is no exception then execute this block.
Workflow
It works in the following way:
First all lines between try and except statements.
If ExceptionName happens during execution of the statements then except clause statements execute
If no exception happens then the statements inside except clause does not execute.
If the Exception is not handled in the except block then it goes out of try block.
Attention
Here are few important points about the above-mentioned syntax:
A single try
statement can have multiple except
statements. This is useful when the try
block contains statements that may throw different types of exceptions.
You can also provide a generic except
clause, which handles any exception.
After the except
clause(s), you can include an else
clause. The code in the else
block executes if the code in the try
block does not raise an exception.
The else
block is a good place for code that does not need the try
block's protection.
fh = open('testfile.txt', 'r')
s = fh.read()
fh.close()
print(s)
try:
fh = open('testfile.txt', 'r')
s = fh.read()
fh.close()
print(s)
except FileNotFoundError:
print ("Error: can't find file")
else:
print ("Read succeeded!")
print ("Haha") # Always printed
Output
Error: can't find file
Haha
The result depends on whether your current directory contains the testfile.txt
. If exists, the file will be read and then the else
statement will be executed. If not, except FileNotFoundError
will be executed.
def get_number():
#"Returns a float number"
number = float(input("Enter a float number: "))
return number
i = 0.0
while i != 8.0:
try:
i = get_number()
except ValueError:
print ("You entered a wrong value.")
else:
print ('There is no error. i is:', i)
print ('haha') # Always printed every time around the loop
print('after loop') # Always printed
Output
Enter a float number: 8.0
There is no error. i is: 8.0
haha
after loop
except
statement with no exceptions defined as followstry:
#You do your operations here;
except:
#If there has exception, then execute this block.
else:
#If no exception then execute this block.
try-except
statement catches all the exceptions that occur. Using this kind of try-except
statement is not considered a good programming practice though, because it catches all exceptions but does not make the programmer identify the root cause of the problem that may occur.try:
assert int(input('Input a value: ')) == 3
except ValueError:
print ('Input type is not appropriate')
except:
print ('Other errors like assertion error')
print ('If the error is handled, then you can see this.')
Output
Input a value: 3
If the error is handled, then you can see this.
finally
block along with a try
block. The finally
block is a place to put any code that must execute, whether the try
block raised an exception or not. The syntax of the try-finally
statement is:try:
#You do your operations here;
except <expeciton>:
#Due to any exception, this may be skipped.
finally:
#This would always be executed.
def testFunc():
try:
f = open('test.txt', 'w') # Succeeds
f.dummyFunction() # Exception here
except AttributeError:
print ('Exception appears happening here')
return # no matter what, "finally" will be executed
finally:
print ('I am finally here')
f.close() # We always close the file, even when doing return
testFunc()
Output
Exception appears happening here
I am finally here
You can create your own exception by inheriting the Python built-in Exception
class.
When certain condition meets, you can raise
the exception object which is defined.
class ShortInputException(Exception): # inherit from the "Exception" class
'''A user-defined exception class containing two variables.'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
def shortInputExceptionAction(self):
print ('shortInputException can do many operations here')
print ('Your input length %d, but the length should be at least %d'% (self.length, self.atleast))
try:
s = input('Enter Something: ')
if len(s) < 3:
raise ShortInputException(len(s), 3) # create and raise (activate) your own Exception object
except KeyboardInterrupt: # When using the Kernel -> Interrupt menu
print ('Why did you do interrupt me?')
except ShortInputException as x: # x is now the name for the exception object which is handled in this block
x.shortInputExceptionAction()
else:
print ('No exception was raised.')
Enter Something: 3333
No exception was raised.
class ShortInputException(Exception):
'''A user-defined exception class.'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
def shortInputExceptionAction(self):
print ('shortInputException can do many operations here')
print ('Your input length %d, but the length should be at least %d'% (self.length, self.atleast))
class LongInputException(Exception):
'''A user-defined exception class.'''
def __init__(self, length, atmost):
Exception.__init__(self)
self.length = length
self.atmost = atmost
def longInputExceptionAction(self):
print ('longInputExceptionAction can do many operations here')
print ('Your input length %d, but the length should be at most %d'% (self.length, self.atmost))
try:
s = input('Enter Something: ')
if len(s) < 3:
raise ShortInputException(len(s), 3) # raise your own Exception object
if len(s) > 7:
raise LongInputException(len(s), 7)
except KeyboardInterrupt: # When using the Kernel -> Interrupt menu
print ('Why did you do interrupt me?')
except ShortInputException as x: # x is the "ShortInputException" object
x.shortInputExceptionAction()
except LongInputException as x:
x.longInputExceptionAction()
else:
print ('No exception was raised.')
Enter Something: 33333
No exception was raised.
The assert
statement will help you check the validity of an expression. If the expression is false, Python raises an AssertionError
exception.
Programmers often place assertions to check whether the input or the result obtained fulfills the expectation.
assert Expression[, ArgumentExpression]
ArgumentExpression
as the argument for the AssertionError
. AssertionError
exceptions can be caught and handled like any other exception using the try-except
statement, but if not handled, they will terminate the program and produce a traceback.
def KelvinToFahrenheit(Temperature):
# assert Temperature >= 0, "So cold, temperature below zero"
return (Temperature - 273) * 1.8 + 32
print (KelvinToFahrenheit(273))
print (int(KelvinToFahrenheit(505.78)))
print (KelvinToFahrenheit(-5))
32.0
451
-468.40000000000003
def KelvinToFahrenheit(Temperature):
try:
assert Temperature >= 0
return (Temperature - 273) * 1.8 + 32
except AssertionError:
print ('So cold, temperature below zero')
KelvinToFahrenheit(-10)
So cold, temperature below zero
Task 1: Complete the function divide
which takes two strings, m
and n
as the arguments. The function should return m/n
as the result.
Note that
if m
or n
are not numbers, the function should return 'Error: Not numbers'
;
if n
is zero, the function should return 'Error: Zero divisor'
.
You program should not crash in any of the cases above.
Note: You are NOT allowed to use any if-branches!
def divide(m, n):
try:
# Attempt to convert strings to floats
m = float(m)
n = float(n)
result = m / n # This can raise a ZeroDivisionError
return result
except ZeroDivisionError: # Handle division by zero
return 'Error: Zero divisor'
except ValueError: # Handle non-numeric values
return 'Error: Not numbers'
assert divide('2', 'haha') == 'Error: Not numbers'
assert divide('haha', '0') == 'Error: Not numbers'
assert divide('2','0') == 'Error: Zero divisor'
assert divide(10, 2) == 5.0
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!
Task 2: Complete the function robustLog
which takes two strings, b
and x
as the arguments. The function should first convert b
and x
to real numbers and then return
Note that
if b
or x
are not real numbers, the function should return 'Error: Not real'
;
if b
or x
are not positive, the function should return 'Error: Non-positive values'
;
if b
equals to 1, the function should return 'Error: Zero divisor'
.
You program should not crash in any of the cases above.
Hint: To compute the logarithm, You can import math and use math.log().
Note: You are NOT allowed to use any if-branches!
import math
def robustLog(b, x):
try:
b = float(b)
x = float(x)
# Check for errors using assertions which will raise an AssertionError if conditions fail
assert b > 0 and x > 0, 'Error: Non-positive values'
assert b != 1, 'Error: Zero divisor'
return math.log(x, b)
except ValueError: # Handle conversion errors
return 'Error: Not real'
except AssertionError as error: # Handle assertions
return str(error)
assert robustLog('haha','10') == 'Error: Not real'
assert robustLog('1','haha') == 'Error: Not real'
assert robustLog('2','0') == 'Error: Non-positive values'
assert robustLog('-1','3') == 'Error: Non-positive values'
assert robustLog('1','-3') == 'Error: Non-positive values'
assert robustLog('1','3') == 'Error: Zero divisor'
assert robustLog('2','8') == 3
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!
# This cell contains hidden tests, do NOT delete!