Hi,
Since few days I was thinking about if there is any way by which I could dive into my running program and see what is going on behind the seen so, I started searching for some tool but as usual python comes with a huge set of libraries and batteries included and after some searching I got this very interesting module Pdb.
Really If you are serious programmer then you need to have it. I will take all of you to this interesting journey and I will explain one feature a day so that it doesn't become difficult to digest. For the inpatients I am providing some links where you can find its complete documentation.
1) Python official documentation page:
http://docs.python.org/library/pdb.html
2) A very good documentation by Hellman:
http://www.doughellmann.com/PyMOTW/pdb/
ok!
First the easy way.
# -*- coding: utf-8 -*-
"""
This script shows the working of the pdb module.
First you have to import the pdb module. Its
available in the default python installation.
"""
import sys
import pdb
def check_even(alist=None):
res = []
if alist and isinstance(alist, (list,)):
for number in alist:
res.append(number) if not number%2 else []
return res
if __name__ == '__main__':
if len(sys.argv) < 2:
print "Too few argument!"
print "Usage: python check_even.py <'numbers'>."
else:
res = check_even(sys.argv[1].split(','))
print "Result:"
print res
Ok! above is a simple module to take all the even numbers in a given sequence and discard the odd ones(Although its not a good way to do it but we are learning debugging not optimizing ;)).
You can see that I have imported the module pdb but not used it, but you will see its use just now.
If you run the script first time you will get some error message something like: "TypeError: not all arguments converted during string formatting". Hmm, if you are smart enough then you know what happened but we will try to do it pythonic way, for that I will modify my code a little bit.
def check_even(alist=None):
res = []
if alist and isinstance(alist, (list,)):
pdb.set_trace()
for number in alist:
res.append(number) if not number%2 else []
return res
Now, you can see that I put the statement pdb.set_trace() in my function definition. The point here is you have to guess which lines are causing problem or to be safe you can put it in the start of function definition. Now, run the code again. You will see that your interpreter just stops and prints out something like this:
-> if alist and isinstance(alist, (list,)):
(Pdb)
Now, it means you are in the interactive debugger and ready to play. Now before moving forward I must tell you some commands which are important for using the debugger.
1. 'n', continue execution until next line is reached.
2. 'c', continue execution until the next breakpoint.
3. 'q', quit from the debugger, the program being executed is aborted.
4. 'a', to see the argument list of the current function.
5. 'l', list the source code for the current line, by default it show you 11 lines around the current line. To change the default value you can do: l [first, [last]]
One important thing to note that pdb allows you to access any variable in the interpreter. You can also run some code while staying in the debugger.
Ok! so returning to our code, press 'n' to move to the next line.
-> for number in alist:
(Pdb) n
-> res.append(number) if not number%2 else []
(Pdb) number
Hmm, now type 'number'! and there you can see the problem.
-> res.append(number) if not number%2 else []
(Pdb) number
'1'
The number was supposed to be int! to confirm that its a string type: type(number).
(Pdb) type(number)
<type 'str'>
Exit the debugger, type 'q'.
Now, we know what to do, right?
change the code:
def check_even(alist=None):
res = []
if alist and isinstance(alist, (list,)):
pdb.set_trace()
for number in alist:
res.append(int(number)) if not int(number)%2 else []
return res
Run, the script again. You will see the pdb prompt again, simply press 'c'.
python check_even.py "1,2,3,4"
-> if alist and isinstance(alist, (list,)):
(Pdb) c
Result:
[2, 4]
Ok! now its working as expected. Now, you can remove the "pdb.set_trace()" statement, mind it I have not followed proper programming practices in my code. But If I had followed that then there would have been less chances of debugging.
Cheers!