8.1. Exception Raise

8.1.1. Rationale

  • Used when error occurs

  • You can catch exception and handles erroneous situation

  • Exception example situations:

    • File does not exists

    • No permissions to read file

    • Function argument is invalid type (ie. int('one'))

    • Value is incorrect (ie. negative Kelvin temperature)

    • Network or database connection could not be established

8.1.2. Raising Exceptions

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

8.1.3. 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. Remember, input() function always returns str and you have to convert it manually.

We need to check if the temperature is not negative. If temperature is 0 or above, it is ok, and we can proceed with program execution. However if the temperature is below zero... Then we should warn user about problem and exit program. This is why we have exceptions. We can break execution of a program in erroneous situations.

>>> temperature = input('Type temperature: ')  # User inputs: -1
>>> temperature = float(temperature)
>>>
>>> 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

8.1.4. Use Case

>>> 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

8.1.5. Assignments

Code 8.1. Solution
"""
* 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ść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> result(1)
    >>> result(0)
    >>> result(-1)
    Traceback (most recent call last):
    ValueError
"""

def result(value):
    ...


Code 8.2. Solution
"""
* Assignment: Exception Raise Many
* Required: yes
* Complexity: easy
* Lines of code: 6 lines
* Time: 5 min

English:
    1. Validate value passed to a `result` function
    2. If `value` is:
        a. other type than `int` or `float` raise `TypeError`
        a. less than zero, raise `ValueError`
        a. 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:
        b. 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ść

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):
    ...