E-Scribe : a programmer’s blog

About Me

PBX I'm Paul Bissex. I build web applications using open source software, especially Django. Started my career doing graphic design for newspapers and magazines in the '90s. Then wrote tech commentary and reviews for Wired, Salon, Chicago Tribune, and others you never heard of. Then I built operations software at a photography school. Then I helped big media serve 40 million pages a day. Then I worked on a translation services API doing millions of dollars of business. Now I'm building the core platform of a global startup accelerator. Feel free to email me.

Book

I co-wrote "Python Web Development with Django". It was the first book to cover the long-awaited Django 1.0. Published by Addison-Wesley and still in print!

Colophon

Built using Django, served with gunicorn and nginx. The database is SQLite. Hosted on a FreeBSD VPS at Johncompanies.com. Comment-spam protection by Akismet.

Elsewhere

Pile o'Tags

Stuff I Use

Bitbucket, Debian Linux, Django, Emacs, FreeBSD, Git, jQuery, LaunchBar, macOS, Markdown, Mercurial, Python, S3, SQLite, Sublime Text, xmonad

Spam Report

At least 236604 pieces of comment spam killed since 2008, mostly via Akismet.

99 problems

There is a classic set of programming exercises called "Ninety-Nine Prolog Problems". Though somewhat tailored to logic programming, they form an interesting set of exercises for other languages. I've seen adaptations of varying completeness for Haskell, Lisp, Perl 6, and Python.

I was reminded of this all by a recent blog post by some bloke called Dave who was using the problems as a way to become more familiar with Python. He used Python's unittest module to test his solutions.

I actually played with these same problems in Python a while ago (before I had found that collection on the Python wiki), and like Dave I decided to incorporate tests. Instead of unittest, though, I used doctest, so the test cases live in the docstring with the description of the problem. For example:

def p31(n):
    """
    P31 (**) Determine whether a given integer number is prime.

    >>> p31(7) and p31(2) and p31(31)
    True
    >>> p31(1) or p31(4) or p31(9)
    False
    """
    if n < 2:
        return False
    for i in range(2, n/2 + 1):
        if n % i == 0:
            return False
    return True

(No, not the most efficient algorithm!)

I collected all the problems in a single module. At the end is the code that invokes the doctest runner:

if __name__ == '__main__':
    import doctest
    doctest.testmod()

One motivation for this structure was the idea that I could build a version of the module with just the docstrings and pass function bodies as a blank slate for people who wanted to try their hand at the problems.

I got through about 40 problems, but it's unlikely I'll have the time to finish them any time soon (life got busy, and they get harder as you go). The source is here for anyone who feels like continuing the project, or using the doctest idea to enhance the version on the Python wiki. Keep me posted if you do!

Wednesday, April 2nd, 2008
+ + +
3 comments

Comment from Pistahh , later that day

One trivial optimization is to terminate the loop after sqrt(n) instead of n/2.

Comment from mabuse , later that day

just one advice. There is no need to go from 2 to n/2. You only need from 2 to sqrt(n).

Comment from Paul , later that day

I'm trying to come up with a good excuse. sqrt not a Python built-in? Not enough coffee? Too much coffee?

Comments are closed for this post. But I welcome questions/comments via email or Twitter.