10 minutes a day Python crash course

This is a series of short 10 minute Python articles helping you to boost your knowledge of Python. I try to post an article each day (no promises), starting from the very basics, going up to more complex idioms. Feel free to contact me on LinkedIn for questions or requests on particular subjects of Python you want to know about.

When you write code in Python, you will (most probably) make mistakes. Some lead to syntax errors, which are errors because you most probably misspelled some word which results in invalid Python code. These mistakes are not to difficult to fix. The other type of error in Python are exceptions. These are errors which are totally fine when translating your Python code to byte code (no syntax errors), but when trying to execute something, there is something invalid. For example, you cannot divide a string by pi. It does not really makes sense to us and also Python does not know what to do and Raises an Exception. Some of these exceptions are quite clear. For example, opening a file for reading which does not exist, raises the FileNotFound exception. Not all exceptions are that clear or even your fault. For example, trying to contact a restAPI that is down can also result in an Exception. Of course it is best to try to avoid all errors and exceptions, however one idiom in Python has always amazed me:

It is easier to ask for forgiveness than permission (EAFP)

None
Meme found on Reddit which was spot-on.

Python has a structure to catch exceptions, namely the try/except block. As the name implies, it will try to perform all statements in the try block. If it is successful, all is done. If for any reason an exception is raised, it will execute the except block, and all errors are suppressed. While we can discuss if this is a nice way of programming, it is a very effective one, as it is much faster than trying to check for all possible errors first. The try-except block can check for many specific exceptions by providing the exception type, or catch any exception by leaving the exception type empty. An exception is actually an object of type Exception (are you surprised?). Lets start with an example on how to use this construct.

In the example we have a valid function to divide two numbers. This will work fine, except if you have the second number equal to zero. We have all heard that dividing be zero is undefined, you cannot divide five cookies among zero friends as we have learned from Siri. As the code above demonstrates, dividing by zero results in a ZeroDivisionError:

None
Whoops….

The ZeroDivisionError is an object and using the try-except construct we can Catch the error and stop our script from crashing. In the example we have created the secure_divide which will try to divide the value. In the first except statement, we will specifically catch the ZeroDivisionError. If we divide by zero, Python will end up executing the statements in this block. Would there be another problem, for example if we reference a variable that does not exist, it will end up in the second except block, which catches all (other) exceptions. We can test for as many exceptions as we require, or just catch them all, without providing the exception.

If you see an error (or exception), I find it easiest to read the error from bottom to top. The last line shows the Exception and a very short description of the error. Then, the error messages shows code blocks around a line with an error in front. The line with the error shows in which line the error has happened. If the error happened in a function, each code section above is a level higher, until the first block is the top level of the code. This can be confusing sometimes as parts of these code blocks are from imported libraries, i.e. code that you have not created. The trick is to ignore these and move higher until you are at the level of your own code. While the error could technically be in a package, it is far more common that we used the code wrong and inputted the wrong parameters in the imported function.

The try-except construct is a great method for specific cases, but I would advice to use it at a minimum. One thing that is however very useful is the try-(except)-finally construct. The except is between parenthesis as it is optional. A short example:

In this example, the first code snippet shows the try-finally construct. It will try to execute all the code in the try-block and regardless if the code is successful or failed, it will always execute the part in the finally block. This is demonstrated in the second part in which we on purpose make the try block fail. In both cases, the 'done' string is printed.

The try-finally construct is extremely useful and is used a lot in Python, but maybe not directly visible. For example, when working with files, we have to make sure that we close the file after we are done. This can be done with a try-finally construct:

The try-finally always makes sure that the file is closed, regardless of success or failure. This was such a great concept, that Guido decided to create a special construct to make it more compact (and not have one ore more finally-clauses dangling on the bottom of the script), namely the with keyword. The with keyword opens (or connects, or …) an object and connects it to an identifier. In the next indented code-block, the variable is available and we can perform as many statements as we like. When we exit the code-block, or when an error occurs, the file (or connection, or …) is closed, identical to our previously created try-finally construct (just in a shorter fashion). This syntax in Python is called a context manager and is not only available for files. It is also used regularly together with for example databases. Changes to databases are often collected until you commit them. A context manager can make sure that these lines are committed and the database connection is closed normally, regardless of errors. Try to remember, that a context manager (using the with keyword) makes sure that a final part of code is always executed at the end of the code section. The easiest way to remember is the open file + close file example.

Practice for today:

In Python, the easiest way to get interactive user input is by using the input() function. The user can type a value and press enter to submit the value. The value is a string.

input_value = input()  # this also works in a  Jupyter Notebook

Assignment: Ask the user for their age and test if it is less than 42. As the input value is a string you need to convert it to a integer. Use the EAFP principle to catch invalid input, i.e. if a user for example inputs a string instead of a number.

If you have any questions, feel free to contact me through LinkedIn.