Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Thursday, June 7, 2012

Pdb: Interactive Python Debugger

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! 





Friday, December 30, 2011

Python package installation

Since few days I was thinking about the difference between the various python package installation procedures so, I have decided to share my findings with you.My first topic will be the well known setup.py installation method and where it installs the packages/files in our OS.so, I got this nice documentation from the official python documentation:

http://docs.python.org/install/index.html

Any query or suggestion is most welcomed !

Wednesday, December 7, 2011

Friday, July 15, 2011

Count your typing speed in Linux

Tools
  • bash shell (obvious)
  • wc (Linux utility command, counts the number of words)
  • cat (To get the user input)
  • date +%s (time since 1970 in number of seconds elapsed)
  • | (pipe to insert the output to the wc utility)
  1. start=date +%s note the current time.
  2. cat | wc -w (now start typing)
  3. do ctrl+d to stop typing
  4. stop=date +%s note the stop time.
  5. calculate:(cat | wc -w)*60/(stop-stop)
We get the typing speed per minute!
(Now its obvious that these command should be in the script)