12.2. Exception Raise¶
Used when error occurs
You can catch exception and handles erroneous situation
If file does not exists
If no permissions to read file
If function argument is invalid type (ie.
int('one')
)If value is incorrect (ie. negative Kelvin temperature)
If network or database connection could not be established
12.2.1. Raising Exceptions¶
Exceptions can have message
You choose which exception best represent error
Raise Exception without message:
>>> raise RuntimeError
Traceback (most recent call last):
RuntimeError
Exception with additional message:
>>> raise RuntimeError('Some message')
Traceback (most recent call last):
RuntimeError: Some message
12.2.2. Example¶
We want to check if Kelvin temperature given by user is not negative.
Note that Kelvin temperatures below zero doesn't exist, hence it's an
absolute scale. In order to do so, we need to ask user to input value.
Let's assume user input -1
.
>>> temperature = -1 # User input this value
Now we need to check if the temperature is not negative. If temperature is 0 or above we can proceed with program execution. However if the temperature is below zero... Then we should warn user about problem and exit the program. This is why we have exceptions. We can break execution of a program in erroneous situations.
>>> if temperature > 0.0:
... print('Temperature is valid')
... else:
... raise ValueError('Kelvin cannot be negative')
Traceback (most recent call last):
ValueError: Kelvin cannot be negative
Good software communicates well with programmer. Exceptions are common language to talk about problems and not-nominal (abnormal) situations in your code.
>>> def check(temperature):
... if type(temperature) not in {float, int}:
... raise TypeError('Temperature must be int or float')
... if temperature < 0:
... raise ValueError('Kelvin temperature cannot be negative')
... return temperature
12.2.3. Use Case - 0x01¶
>>> def apollo13():
... raise RuntimeError('Oxygen tank explosion')
>>>
>>>
>>> apollo13()
Traceback (most recent call last):
RuntimeError: Oxygen tank explosion
>>> def apollo18():
... raise NotImplementedError('Mission dropped due to budget cuts')
>>>
>>>
>>> apollo18()
Traceback (most recent call last):
NotImplementedError: Mission dropped due to budget cuts
12.2.4. Assignments¶
"""
* Assignment: Exception Raise One
* Required: yes
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min
English:
1. Validate value passed to a `result` function:
a. If `value` is less than zero, raise `ValueError`
2. Non-functional requirements:
a. Write solution inside `result` function
b. Mind the indentation level
3. Run doctests - all must succeed
Polish:
1. Sprawdź poprawność wartości przekazanej do funckji `result`:
a. Jeżeli `value` jest mniejsze niż zero, podnieś wyjątek `ValueError`
2. Wymagania niefunkcjonalne:
a. Rozwiązanie zapisz wewnątrz funkcji `result`
b. Zwróć uwagę na poziom wcięć
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `if`
* `raise`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> result(1)
>>> result(0)
>>> result(-1)
Traceback (most recent call last):
ValueError
"""
def result(value):
...
"""
* Assignment: Exception Raise Many
* Required: yes
* Complexity: easy
* Lines of code: 6 lines
* Time: 3 min
English:
1. Validate value passed to a `result` function
2. If `value` is:
a. other type than `int` or `float` raise `TypeError`
b. less than zero, raise `ValueError`
c. below `ADULT`, raise `PermissionError`
3. Non-functional requirements:
a. Write solution inside `result` function
b. Mind the indentation level
4. Run doctests - all must succeed
Polish:
1. Sprawdź poprawność wartości przekazanej do funckji `result`
2. Jeżeli `age` jest:
a. innego typu niż `int` lub `float`, podnieś wyjątek `TypeError`
b. mniejsze niż zero, podnieś wyjątek `ValueError`
c. mniejsze niż `ADULT`, podnieś wyjątek `PermissionError`
3. Wymagania niefunkcjonalne:
a. Rozwiązanie zapisz wewnątrz funkcji `result`
b. Zwróć uwagę na poziom wcięć
4. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `not in`
* `raise`
* `if`
* `isinstance()`
* `type()`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> result(18)
>>> result(17.9999)
Traceback (most recent call last):
PermissionError
>>> result(-1)
Traceback (most recent call last):
ValueError
>>> result('one')
Traceback (most recent call last):
TypeError
>>> result(True)
Traceback (most recent call last):
TypeError
"""
ADULT = 18
def result(age):
...
"""
* Assignment: Exception Raise PermissionError
* Required: yes
* Complexity: easy
* Lines of code: 4 lines
* Time: 3 min
English:
1. Check username and password passed to a `login` function
2. If `username` is 'mwatney' and `password` is 'myVoiceIsMyPassword'
then print 'logged in'
3. If any value is other than mentioned, raise an exception
PermissionError with message 'Invalid username and/or password'
4. Non-functional requirements:
a. Write solution inside `result` function
b. Mind the indentation level
5. Run doctests - all must succeed
Polish:
1. Sprawdź username i password przekazane do funckji `login`
2. Jeżeli username jest 'mwatney' i hasło jest 'myVoiceIsMyPassword'
to wyświetl na ekranie napis 'logged in'
3. Jeżeli którakolwiek wartość jest inna, to podnieś wyjątek
PermissionError z komunikatem 'Invalid username and/or password'
4. Wymagania niefunkcjonalne:
a. Rozwiązanie zapisz wewnątrz funkcji `result`
b. Zwróć uwagę na poziom wcięć
5. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `not in`
* `raise`
* `if`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> login('mwatney', 'myVoiceIsMyPassword')
logged in
>>> login('badusername', 'myVoiceIsMyPassword')
Traceback (most recent call last):
PermissionError: Invalid username and/or password
>>> login('mwatney', 'badpassword')
Traceback (most recent call last):
PermissionError: Invalid username and/or password
>>> login('admin', 'admin')
Traceback (most recent call last):
PermissionError: Invalid username and/or password
"""
# Username must be 'mwatney'
# Password must be 'myVoiceIsMyPassword'
# type: Callable[[str,str], Exception|None]
def login(username, password):
...