Rather than simply list all of the commonly useful PDB commands, we're going to instead debug a simple function. Our function – is_palindrome() – takes in an integer and determines if the digits of the integer are a palindrome or not. A palindrome is a sequence which is the same both forwards and backwards.
The first thing we'll do is create a new file, palindrome.py, with this code:
import unittest
def digits(x):
"""Convert an integer into a list of digits.
Args:
x: The number whose digits we want.
Returns: A list of the digits, in order, of ``x``.
>>> digits(4586378)
[4, 5, 8, 6, 3, 7, 8]
"""
digs = []
while x != 0:
div, mod = divmod(x, 10)
digs.append(mod)
x = mod
return digs
def is_palindrome(x):
"""Determine if an integer is a palindrome.
Args:
x: The number to check for palindromicity.
Returns: True if the digits of ``x`` are a palindrome,
False otherwise.
>>> is_palindrome(1234)
False
>>> is_palindrome(2468642)
True
"""
digs = digits(x)
for f, r in zip(digs, reversed(digs)):
if f != r:
return False
return True
class Tests(unittest.TestCase):
"""Tests for the ``is_palindrome()`` function."""
def test_negative(self):
"Check that it returns False correctly."
self.assertFalse(is_palindrome(1234))
def test_positive(self):
"Check that it returns True correctly."
self.assertTrue(is_palindrome(1234321))
def test_single_digit(self):
"Check that it works for single digit numbers."
for i in range(10):
self.assertTrue(is_palindrome(i))
if __name__ == '__main__':
unittest.main()
As you can see, our code has three main parts:
- The first is the digits() function which converts an integer into a list of digits.
- The second is the is_palindrome() function which first calls digits() and then checks if the resulting list is a palindrome.
- The third part is a set of unit tests. We'll use these tests to drive the program.
As you might expect, this being a section on debugging, there's a bug in this code. We're going to first run the program and notice the bug, and then we'll see how to use PDB to find the bug.