Tuesday 20 July 2021

Python crash course part 6: basic exceptions.

Another basic language feature I'll cover in this tutorial is exception handling (which I wrote about in Kotlin a few days ago.

Traditionally, I'll show some examples. Let's begin with simple code, asking user for two numbers and dividing them. Of course, such program may encounter probably the most basic exception: division by 0. But also another one: if we put something not being a number, it cannot be converted to float and some other exception would be expected.

First, the code without any exeption handling would look like this:

# !/usr/bin/python3

def divide(ab):
    return a/b

def main():
    a = float(input('a = '))
    b = float(input('b = '))
    c = divide(a,b)
    print(c)

We create a function divide(ab) , returning division result. Then we get two numbers from user, a and b using input('... ') function and converting them to float using float() function (as input('a = ') returns simply a string).

If given two numbers which we can divide by eachother, the result is not surprising:

a = 10
b = 3
3.3333333333333335

But if we put 0 as b...

a = 10
b = 0
Traceback (most recent call last):
  File "d:\Projekty\Python\controlflow.py", line 13, in <module>
    main()
  File "d:\Projekty\Python\controlflow.py", line 9, in main     
    c = divide(a,b)
  File "d:\Projekty\Python\controlflow.py", line 4, in divide   
    return a/b
ZeroDivisionError: float division by zero

... we get a cute stacktrace. Well, division by 0 is not possible, and therefore results in an exception. Quite obvious :)

Before we try to deal with this proble, let's put another strange data as input to program: try to divide 10 by horse. Well, this also shouldn't be possible, right?

a = 10
b = horse
Traceback (most recent call last):
  File "d:\Projekty\Python\controlflow.py", line 17, in <module>
    main()
  File "d:\Projekty\Python\controlflow.py", line 9, in main
    b = float(input('b = '))
ValueError: could not convert string to float: 'horse'

... as expected. Of course, here another exception is caught (and in other place: not when trying to divide, but when trying to get float from quite horse-like input...)

What can we do with exception? We can catch it. First, a general exception:

# !/usr/bin/python3


def divide(ab):
    return a/b

def main():
    
    try:
        a = float(input('a = '))
        b = float(input('b = '))
        c = divide(a,b)
        print(c)
    except:
        print("Some exception caught!")

if __name__ == "__main__":
    main()

...which handles both division by 0:

a = 10
b = 0
Some exception caught!

... and division by horse :) 

a = 10
b = horse
Some exception caught!

The exception handling in Python is done using try except instruction. In the case above, no specific exception has been specified to be caught, so we get the same result in case of any exception (also known as Pokemon exception handling... Catch them all ;) ).

So what if we wanted to catch some specific exception? 

# !/usr/bin/python3


def divide(ab):
    return a/b

def main():
    
    try:
        a = float(input('a = '))
        b = float(input('b = '))
        c = divide(a,b)
        print(c)
    except ZeroDivisionError:
        print("Division by 0? Blasphemy!")

if __name__ == "__main__":
    main()

Result:

a = 10
b = 0
Division by 0? Blasphemy!

What if we want to catch more specific exceptions?

We can specify more except blocks:

# !/usr/bin/python3


def divide(ab):
    return a/b

def main():
    
    try:
        a = float(input('a = '))
        b = float(input('b = '))
        c = divide(a,b)
        print(c)
    except ZeroDivisionError:
        print("Division by 0? Blasphemy!")
    except ValueError:
        print("Some strange value...")

if __name__ == "__main__":
    main()

Division by 0 is then detected separately from division by horse:

a = 10
b = 0
Division by 0? Blasphemy!

and

a = 10
b = horse
Some strange value...

That's all for now - the custom exceptions and throwing them "by hand" will be one of our next topics in the nearest future :)



No comments:

Post a Comment

Python crash course part 10: inheritance and polymorphism

In the last part we've shown how to create and use a class in Python. Today we're going to talk about inheritance: wchich means cre...