July 1, 2009

Python 3.1, you shouldn't have!

I highly appreciate the presents that the Python 3.1 team (unwittingly) got me for my birthday this year. This morning I wrote the following snippet to determine the day-frequency of birthday occurrences: [*]

#!/usr/bin/env python3.1

import collections
import datetime
from operator import itemgetter


birthday = {part: int(input('Enter birth {}: '.format(part)))
    for part in 'year month day'.split()}
now = datetime.datetime.now()
days = []
for year in range(birthday['year'], now.year + 1):
    iter_birthday = dict(birthday)
    iter_birthday['year'] = year
    date = datetime.date(**iter_birthday)
    days.append(date.strftime('%A'))

counter = collections.Counter(days)
fmt = '{:15} {:>3}'
for day, frequency in sorted(counter.items(), key=itemgetter(1),
        reverse=True):
    print(fmt.format(day, frequency))
print(fmt.format('Total', sum(counter.values())))

Check out the Python 3.1 goodness: automatically numbered format strings and collections.Counter. It's also a relief that I no longer have to type iter, x, or raw — Python is even prettier without the 2.x cruft.

Turns out that my original day of birth is still in the lead!

Updates

  1. Added dict comprehensions per astute comments. :-)

  2. Replaced lambda argument to sorted with the more readable operator.itemgetter, which I didn't realize exists! Thanks @xtian.

Footnotes

[*]

Note that the script assumes your birthday has already occurred this year.