Two days ago I attended the first GothPy meeting here in Gothenburg. Jeppesen was kind enough to let us use one of their conference rooms for the meeting. About ten people showed up to listen to Andrew's PyCon 2007 talk about Stackless Python and to work on the BankOCR code kata.
The kata was very interesting. It was my first and I was dead certain we'd end up fighting about IDE's or whether function names should be likeThis or like_this, but everyone was very polite and helpful. Funny thing though. When we planned the meeting, Emily insisted that we should bring a computer that is not-a-Mac, preferably a Windows PC. About two minutes into the meeting there are at least six Macs on the table and I only counted to seven computers in total. But apart from the fact that no one could get along with the keyboard, the PyDev/Eclipse editor and that the unit test results where printed in red regardless of whether they failed or succeded everything went fine using a Windows-machine ;-)
We actually managed to get further than I thought we would during the kata. The last piece of code we wrote was the validation part (User story #2)
... The next step therefore is to validate that the numbers you read are in fact valid account numbers. A valid account number has a valid checksum. This can be calculated as follows:We made three different versions of the is_valid method. Jacob, who had the keyboard at the time, implemented it like this:account number: 3 4 5 8 8 2 8 6 5So now you should also write some code that calculates the checksum for a given number, and identifies if it is a valid account number.
position names: d9 d8 d7 d6 d5 d4 d3 d2 d1
(d1+2*d2+3*d3 +..+9*d9) mod 11 = 0
>>> def is_valid(account_number):and I suggested this:
... total = 0
... for i in xrange(9):
... total += (9-i)* account_number[i]
... return total % 11 == 0
>>> def is_valid(account_number):but the clear winner in our little refactoring battle was Andrew who wrote this:
... return sum(d* i for d, i in zip(reversed(account_number), range(1,10))) % 11 == 0
>>> def is_valid(account_number):which is brilliant and reminded me of why I love Python. It looks like pseudo-code! Reading Andrew's implementation is basically like reading the specification.
... d9,d8,d7,d6,d5,d4,d3,d2,d1 = account_number
... return (d1+2*d2+3*d3+4*d4+5*d5+6*d6+7*d7+8*d8+9*d9) % 11 == 0
NOTE! I re-wrote these functions from memory so I may have missed some little detail. My apologies if that is the case. Also, some variables have been renamed to protect the innocent.