Python

Let's take as our example tf.py, which counts words, lines, and paragraphs in a text file, as with our Perl example above.

Perl debugging screen

Figure 8-5. Perl debugging screen


 1  class textfile:
 2     ntfiles = 0 # count of number of textfile objects
 3     def __init__(self,fname):
 4        textfile.ntfiles += 1
 5        self.name = fname # name
 6        self.fh = open(fname)
 7        self.nlines = 0 # number of lines
 8        self.nwords = 0 # number of words
 9        self.npars = 0 # number of words
10       self.lines = self.fh.readlines()
11       self.wordlineparcount()
12    def wordlineparcount(self):
13       "finds the number of lines and words in the file"
14       self.nlines = len(self.lines)
15       inparagraph = 0
16       for l in self.lines:
17          w = l.split()
18          self.nwords += len(w)
19          if l == '\n':
20           if inparagraph:
21              inparagraph = 0
22      elif not inparagraph:
23         self.npars += 1
24         inparagraph = 1
25
26  def grep(self,target):
27     "prints out all lines in the file containing target"
28     for l in self.lines:
29        if l.find(target) >= 0:
30           print l
31        print i
32
33  def main():
34     t = textfile('test.txt')
35     print t.nwords, t.nlines, t.npars
36
37  if __name__ == '__main__':
38     main()

Be sure to include in your source code the two lines shown at the end of the program:

if __name__ == '__main__':
   main()

Note

If you are an experienced Python programmer, you are probably well aware of this pattern. If you are unfamiliar with Python, a brief explanation of these lines is that you need to test whether your Python program is being invoked on its own or being imported as a module into some other program. This is an issue that arises when running the program via a debugger.

Python's basic debugger is PDB (pdb.py), a text-based tool. Its utility is greatly enhanced by using DDD as a GUI frontend.

There is a bit of business to take care of before starting, though. In order to enable DDD to access PDB properly, Richard Wolff wrote PYDB (pydb.py), a slightly modified version of PDB. You would then run DDD with the -pydb option. But Python evolved, and the original PYDB stopped working correctly.

A nice solution has been developed by Rocky Bernstein. As of this writing, in summer 2007, his modified (and greatly extended) PYDB is slated to be included in the next release of DDD. Alternatively, you can use the patch that Richard Wolff kindly provided. You will need the following files:

Place the files in some directory, say /usr/bin, give them execute permission, and create a file named pydb consisting of a single line

/usr/bin/pydb.py

Make sure you give the file pydb execute permission too. Once this has been done, you can use DDD for Python programs. Then fire up DDD:

$ ddd --pydb

Then bring in the source file tf.py, either by selecting File | Open Source and double-clicking the filename or by typing

file tf.py

in the Console. The (Pdb) prompt may not show up initially, but type your command anyway.

Your source code will appear in the Source Text window, and you can then set breakpoints as usual. Suppose that you set a breakpoint at the line

w = l.split()

To run the program, click Program | Run, set any command-line arguments in the Run pop-up window, and then click Run. After clicking Run, you will need to click Continue twice. This is due to the workings of the underlying PDB/PYDB debugger. (If you forget to do this, PDB/PYDB will remind you in the DDD Console.)

If you make a change to the source code, issue the file command in the Console, or select Source | Reload Source. Your breakpoints from the last run will be retained.

Once again, the procedures for Python are similar to those of the other languages. This of course illustrates the value of having a single tool to use on multiple languages—once you learn how to use the tool in one language, it is quite easy to use it for another one. The main Python-specific points to keep in mind are:

One major advantage of Eclipse over DDD is that PDB, the underlying debugging engine used by DDD, does not work on threaded programs, whereas Eclipse does.