When mentioning debugging, this means there may be a bug in the middle. Well, I don't mean a bug one might find in a house—what I mean here is a programming bug!
Before moving further with this tutorial, let's get some terms out of the way. Let's briefly define what we mean by a bug and debugging.
A bug in computing could occur both in software and hardware, but our focus here is on software. Let me quickly mention a belief on where the term bug might have originated. It is believed that the first use of the term bug in computing was when a real bug (moth) was found in one of the relays of the Mark II computer. The term bug was also used at the end of the 19th century to describe technical glitches.
Bugs in software cause the program to produce unintended behavior. It is a term commonly used to refer to an error with unknown location and reason, and they can cause severe issues (i.e. crashing a program).
In this situation, debugging comes into play.
Well, one may say that the best way to avoid any issues is not to generate bugs in the first place. But this is unfortunately rather rare, and it's not easy to generate a clean program from the beginning. Having bugs is a normal situation you would fall into.
Debugging is the process of locating, analyzing, and correcting any bug (error) you might encounter. The ultimate goal of debugging is to remove such bugs, and to produce a program that runs and behaves as intended. It is important to note here that most of the time will be spent on locating the bug since, as we mentioned above, it originally has an unknown location.
To have an idea of how difficult debugging could be, see what Brian W. Kernighan had to say:
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?
Handling Python Exceptions
An exception is an object which indicates that we have a bug (error). In other words, Python uses exceptions in order to communicate that there are bugs in the program. This would be the localization part of the debugging process. Receiving the exception object and performing the necessary actions for dealing with the bug refers to handling the exception. This would be the analyzing and correcting steps in the debugging process.
The try Statement
try statement is used for exception handling and has two forms:
try/finally. In the first case, the
try clause can be followed by one or more
except clauses, while in the latter case, it can only be followed by only one
try/except syntax is as follows:
try: # try block code except: # except block code
The body of the
try clause will contain code that might generate an exception, provided that if an exception was generated, all the statements in the block are skipped. On the other hand, the body of the
except clause is called the exception handler, as it is used to catch the exception. The
except block code will only be executed if an exception has been generated, otherwise the block will be skipped. You can use built-in exceptions as shown in the Python Standard Library.
Let's take an example to make things clearer. Say we were asked to enter a denominator in a division formula. Since dividing by zero is not allowed, let's write a
try/except statement that checks if there is a division by zero, and prints a message if this error occurred.
denominator = input('Enter a denominator value: ') try: formula = 15/denominator print 'The result is ' + str(formula) except ZeroDivisionError: print 'You attempted to divide by zero which is not allowed'
If you input the value
5, for instance, you would get the following output:
The result is 3
Now, try to enter the value
0 as input. What output will you get in this case?
try/finally is another way to write the try statement in Python.
finally clauses are called clean-up/termination clauses since they always have to be run regardless of whether an exception occurred in the
Let's try the example in the above section, but with the
denominator = input('Enter a denominator value: ') try: formula = 15/denominator print 'The result is ' + str(formula) finally: print 'You attempted to divide by zero which is not allowed'
Notice that when you enter the value
5 as input, for instance, you would get the following output:
The result is 3 You attempted to divide by zero which is not allowed
The raise Keyword
raise keyword is another way to handle exceptions in Python. In this case, you will be able to raise your own exceptions—that is exceptions that are raised when an issue outside the scope of expected errors occurs.
Let's look at an example of using the
raise keyword to understand the concept more.
try: x = input('Enter a number in the range 1-10: ') if x<1 or x>10: raise Exception print 'Great! You listened to me and entered a valid number' except: print 'Your number seems to be outside the range 1-10'
In this example, if you enter a number outside the allowed range, the
except block will be executed.
Go ahead, try some values and check the output.
The traceback Module
traceback module is another way to handle exceptions in Python. It is basically used to print stack traces of a program after an exception occurs. The
traceback contains the error message, the number of the line that caused the error, and the call stack, that is the sequence of the function calls that led to the error.
Let's take an example that generates a
def createException(name): raise Exception('It seems that ' + name + ' raised an exception') createException('Abder')
If you run this script, you will get an output that looks as follows:
Traceback (most recent call last): File "test.py", line 4, in <module> createException('Abder') File "test.py", line 2, in createException raise Exception('It seems that ' + name + ' raised an exception') Exception: It seems that Abder raised an exception
Notice that the bug (error) happened on
line 2 in the
createException function. Notice also that the call stack can help us in tracking which call led to the error, which in this case is the call which occurred in
The tutorial is getting longer, and I would like to stop at this point. As you have seen, debugging programs is really a natural and regular thing to do, and I believe that the types of errors you saw in this tutorial sound familiar, don't they?
There are other ways of debugging a Python program and handling exceptions. A well-known way, for instance, is the