I had the pleasure to be invited to lead a tutorial at JDEV2013 titled Learning TDD and Python in Dojo mode.

I quickly introduced the keywords with a single slide to keep it simple:

http://Python.org + Test Driven Development (Test, Code, Refactor) + Dojo (house of training: Kata / Randori) = Calculators - Reverse Polish Notation - Formulas with Roman Numbers - Formulas with Numbers in letters

As you can see, I had three types of calculators, hence at least three Kata to practice, but as usual with beginners, it took us the whole tutorial to get done with the first one.

The room was a class room that we set up as our coding dojo with the coder and his copilot working on a laptop, facing the rest of the participants, with the large screen at their back. The pair-programmers could freely discuss with the people facing them, who were following the typing on the large screen.

We switched every ten minutes: the copilot became coder, the coder went back to his seat in the class and someone else stood up to became the copilot.

The session was allocated 3 hours split over two slots of 1h30. It took me less than 10 minutes to open the session with the above slide, 10 minutes as first coder and 10 minutes to close it. Over a time span of 3 hours, that left 150 minutes for coding, hence 15 people. Luckily, the whole group was about that size and almost everyone got a chance to type.

I completely skipped explaining Python, its syntax and the unittest framework
and we jumped right into writing our first tests with `if` and `print`
statements. Since they knew about other programming languages, they picked up
the Python langage on the way.

After more than an hour of slowly discovering Python and TDD, someone in the room realized they had been focusing more on handling exception cases and failures than implementing the parsing and computation of the formulas because the specifications where not clearly understood. He then asked me the right question by trying to define Reverse Polish Notation in one sentence and checking that he got it right.

Different algorithms to parse and compute RPN formulas where devised at the blackboard over the pause while part of the group went for a coffee break.

The implementation took about another hour to get right, with me making sure they would not wander too far from the actual goal. Once the stack-based solution was found and implemented, I asked them to delete the files, switch coder and start again. They had forgotten about the Kata definition and were surprised, but quickly enjoyed it when they realized that progress was much faster on the second attempt.

Since it is always better to show that you can walk the talk, I closed the session by praticing the RPN calculator kata myself in a bit less than 10 minutes. The order in which to write the tests is the tricky part, because it can easily appear far-fetched for such a small problem when you already know an algorithm that solves it.

Here it is:

import operator OPERATORS = {'+': operator.add, '*': operator.mul, '/': operator.div, '-': operator.sub, } def compute(args): items = args.split() stack = [] for item in items: if item in OPERATORS: b,a = stack.pop(), stack.pop() stack.append(OPERATORS[item](a,b)) else: stack.append(int(item)) return stack[0]

with the accompanying tests:

import unittest from npi import compute class TestTC(unittest.TestCase): def test_unit(self): self.assertEqual(compute('1'), 1) def test_dual(self): self.assertEqual(compute('1 2 +'), 3) def test_tri(self): self.assertEqual(compute('1 2 3 + +'), 6) self.assertEqual(compute('1 2 + 3 +'), 6) def test_precedence(self): self.assertEqual(compute('1 2 + 3 *'), 9) self.assertEqual(compute('1 2 * 3 +'), 5) def test_zerodiv(self): self.assertRaises(ZeroDivisionError, compute, '10 0 /') unittest.main()

Apparently, it did not go too bad, for I had positive comments at the end from people that enjoyed discovering in a single session Python, Test Driven Development and the Dojo mode of learning.

I had fun doing this tutorial and thank the organizators for this conference!