An exception is an action that disrupts the normal flow of a program. This action is often representative of an error being thrown. Exceptions are ways that we can elegantly recover from errors
import sys
def sqrt(x):
if x < 0:
sys.stderr.write("Error Input < 0\n")
sys.exit(1)
return x**0.5
if __name__ == '__main__':
print("Please enter a number: ",)
inputNum = int(sys.stdin.readline())
print(sqrt(inputNum))
The simplest way to deal with problems...
Just crash
exception_1.py
import sys
def sqrt(x):
if x < 0:
raise Exception(f"Error, sqrt input {x} < 0")
return x**0.5
if __name__ == '__main__':
print("Please enter a number: ",)
inputNum = int(sys.stdin.readline())
print(sqrt(inputNum))
Now instead, let's raise an exception
However, this just gives us more information, and doesn't help us handle it
exception_2.py
import sys
def sqrt(x):
if x < 0:
raise Exception(f"Error, sqrt input {x} < 0")
return x**0.5
if __name__ == '__main__':
try:
print("Please enter a number: ",)
inputNum = int(sys.stdin.readline())
print(sqrt(inputNum))
except Exception as e:
print(f"Error when inputting! {e}. Please try again:")
inputNum = int(sys.stdin.readline())
print(sqrt(inputNum))
If we catch the exception, we can better handle it
exception_3.py
import sys
def sqrt(x):
if x < 0:
raise Exception(f"Error, sqrt input {x} < 0")
return x**0.5
if __name__ == '__main__':
print("Please enter a number: ",)
while True:
try:
inputNum = int(sys.stdin.readline())
print(sqrt(inputNum))
break
except Exception as e:
print(f"Error when inputting! {e}. Please try again:")
Or we could make this even more robust
exception_4.py
import sys
def sqrt(x):
if x < 0:
raise Exception(f"Input {x} is less than 0. Cannot sqrt a number < 0")
return x**0.5
if __name__ == '__main__':
if len(sys.argv) == 2:
try:
print(sqrt(int(sys.argv[1])))
except Exception as e:
print(f"Got an error: {e}")
Key points:
throw_catch.py
Examples with pytest (very important for project)
import pytest
def sqrt(x):
if x < 0:
raise Exception(f"Input {x} is less than 0. Cannot sqrt a number < 0")
return x**0.5
def test_sqrt_ok():
assert sqrt(1) == 1
assert sqrt(4) == 2
assert sqrt(9) == 3
assert sqrt(16) == 4
def test_sqrt_bad():
with pytest.raises(Exception):
sqrt(-1)
sqrt(-2)
sqrt(-3)
sqrt(-4)
sqrt(-5)
pytest_except_1.py
Other basic exceptions can be caught with the "Exception" type
import pytest
def sqrt(x):
if x < 0:
raise ValueError(f"Input {x} is less than 0. Cannot sqrt a number < 0")
return x**0.5
def test_sqrt_ok():
assert sqrt(1) == 1
assert sqrt(4) == 2
assert sqrt(9) == 3
assert sqrt(16) == 4
def test_sqrt_bad():
with pytest.raises(Exception):
sqrt(-1)
sqrt(-2)
sqrt(-3)
sqrt(-4)
sqrt(-5)
pytest_except_2.py