Composite Design Pattern Kata

Today’s post is nothing elevated, just two examples from which one can understand this powerful design pattern.

First, let’s do a quick recap, how the pattern actually looks like: 

(if you’re new to design patterns, please find a detailed description here)

The exercises are the following (note that the second one usually looks easier, because it’s easier to imagine. However, you are gonna have a harder time if you want to do that properly using TDD. Mocking recursive structures is not the easiest thing to do):

  1. Implement an application that can draw(no, you don’t really have to draw, just implement the data structures) pictures using rectangles and circles. A picture can be made from primitives (rectangles and circles), primitives combined with other pictures (one or more primitives and at least one other picture – which is composed of primitives), and several pictures combined. (Spoiler: circles and rectangles are leaves, pictures are composite objects)
  2. Implement an application that can compute (yes, you really have to compute) the size of a directory. The size of a directory is equal to the sum of all the files it contains plus the size of its subdirectories. (Hint: you might want to wrap java.io.File objects inside your Leaf and Composite classes. Spoiler: in this case plain files are leaves, directories are composites).

You can find a solution to the second problem here (implementation in Java, unit tested with JUnit and Mockito).

Code Kata Nr. 6

This week’s code kata is a little bit more advanced. This time one has to use several different techniques in order to solve it. I admit, the exercise itself is not my idea (found it on the net), however I like it very much, since it’s about soccer.

So, here it goes; There are given several teams and their strenght expressed as integer values (for a list of country – strength point values see this link: http://en.wikipedia.org/wiki/FIFA_World_Rankings). These values can be used to predict the outcome of a game between two teams. The formula for that is the following:  (In order to keep it simple, we assume that the team with the higher probability to win, wins the game). Of course teams’ strength are not constant. They have to be changed as teams play games. Winners’ strength increases while losers’ strength decreases.

Now, as we know which team wins and which loses, we have to update their strength points. The formula for that is the following:  where:

  • I: importance of the game. This can be a constant; 60 is its default value.
  • GD: goal difference. This is a random number between 1-6.
  • R: result. Its value is 1 for a win, 0 for a loss.
  • Win(expected): given by the formula above.

What the kata requests you to do is to predict the winner of a game, increase their strenght and decrease losers’ strength. If this is too easy for you, then select several teams, and predict the winner of a whole tournament.

This kata is nice for a number of reasons;

  1. In order to solve it in TDD, it needs the random number either to be injected (dependency injection rulez!) or faked.
  2. Finally a kata, which requires you to have several classes.
  3. It familiarizes its solver with JUnit’s assert for floating point numbers (remember two floating point numbers cannot be considered truly equal; When testing such numbers for equality, you need to pass in a third argument to the assert. That is a delta walue, which tells the maximum difference between the numbers at which they are considered equal.)

Solve it, have fun, and if you really want to play it on the hard level, have a time limit of 30 minutes (OK, up to one hour).

Code Kata Nr. 5

This week we returned to the world of strings and realistic programming (more or less). The kata itself is a slightly modified variant of the well known Soundex algorithm. (see a detailed description of Soundex algorithm here: http://en.wikipedia.org/wiki/Soundex)

And now the actual exercise we had:

  • The algorithm receives a name as input, which is at least two characters long
  • Retain the first letter of the name, and drop all occurrences of a, e, h, i, o, u, w, y in other positions.
  • If two or more letters are the same on adjacent positions in the name, omit all but the first.
  • Here we get a little tricky and diverge from the original algorithm: convert all the resulting string to all-uppercase
  • Convert all letters (but the first) to ASCII characters
  • Back to the original algorithm: convert the resulting string to the form LETTER NUMBER NUMBER NUMBER (note that NUMBER is an ASCII character of two digits)
  • If there are not enough characters in the string, use the number “00” instead

Why was it needed to modify the algorithm to something that does not really do anything useful? Well it was required because of the nature of the katas; we play them the following way:

  1. The problem is presented
  2. We have a first round of x minutes, when the players can implement their solution employing TDD
  3. After that we have a discussion round when everyone tells the others what and how did they do
  4. All the solutions are erased
  5. A second round comes of x minutes again, where everyone can use ideas or parts of others’ solution

This kata was played with 20 minutes long rounds. If the character grouping had been a constraint, we would have spent all the time testing that all the characters are grouped properly. The checking of the banned characters took too much time anyway. If you play katas differently (longer rounds, or no rounds at all, no time constraint), then just add this requirement too, and implement the whole algorithm (have fun and see its limitations :-)).

There was no new constraint introduced, but all the previous ones remained valid.

Code Kata Nr. 4

This week we got back to realistic programming. After last week’s fibo-emirp numbers (even if there were two almost perfect solutions) I found out that real life problems are somehow closer to the teams’ heart.

This week we had IBAN number checking as a kata (yeah, we are doing such exercises on purpose: I’m planning a great attack on World Bank 🙂 ). In order to check an IBAN number, one has to follow the steps below (note, I am using the following IBAN as test data: “IT60Q0123412345000000753XYZ”, taken from http://www.morfoedro.it/doc.php?n=219&lang=en ):

  1. An IBAN number is an alphanumeric literal of at least five, at most thirty-four characters
  2. The alphanumeric string can only contain uppercase letters and digits
  3. The first two characters have to be LETTERS ( trough which we can identify the country of origin, IT60Q0123412345000000753XYZ, we have Italy)
  4. characters three and four have to be digits (IT60Q0123412345000000753XYZ, we’re doing great)
  5. the rest of the characters can be either letters or digits
  6. the first four alphanumeric characters have to be moved to the end of the string (Q0123412345000000753XYZIT60)
  7. all the letters have to be converted to numbers, following the formula:  A=10, B=11, C=12 … (260123412345000000753333435182960)
  8. as a last step the following computation has to be carried out; resulting number MODULO 97. If the value of the modulo is 1, then we have a valid IBAN. (*)

(*) A possible way of  modulo computation: divide the number into parts of (let’s say) eight digits. Take the modulo of this smaller number and put the result of the next pack of digits. Let us break this numerical string into five parts: 26012341, 23450000, 00753333, 43518296 and 0. The remainder of the division of 26012341 by 97 is 45. The remainder of the division of 4523450000 by 97 is 15. The remainder of the division of 1500753333 by 97 is 82. The remainder of the division of 8243518296 by 97 is 68. The remainder of the division of 680 by 97 is 1. [http://www.morfoedro.it/doc.php?n=219&lang=en]

If you’re curious of my solution, you can find it here:  https://github.com/tamasgyorfi/Code-kata—IBAN-numbers

The kata is of two rounds, twenty-five minutes each. The exercise involves a constraint also, namely the one testcase one assert. This was needed because there were many cases when I saw testcases with 5-10 asserts. In my opinion that is not a very good practice.  Let’s consider the following situation: there is an algorithm of some kind that checks numbers against some criteria. Let’s say the algorithm is faulty and fails for 1, 11, 111 etc. If there is a single test case that contains a lot of asserts (positives and negatives alternatively) it’s gonna fail for one and the test runner will not go on. Which means that the method will not be checked for 11, 111 etc. So one tries to fix the algorithm for 1, and will not notice the pattern… I personally like to see how many test cases there were, how many of them passed, how many of them failed. I don’t like asserts that are not run at all. Comments on this are welcome.

Code Kata nr. 3

So far we’ve had a credit card checking kata, another one on string manipulation, and now a tell-if-a-number-is-a-very-tricky-one. Its text, shortly is the following: given a number, return the FIBO-EMIRP number closest to it. Yeah, they actually are called FIBO-EMIRP. These numbers have the following properties:

  • they are prime numbers
  • the number’s reverse is also prime
  • the number is not palindrome (*)
  • the number is a fibonacci number (the fibonacci numbers: 1, 1, 2, 3, 5, 8, 13, 21 … Basically the i-th fibonacci number is given by the recursive formula f(i) = f(i-1) + f(i-2))

(*) It turns out that adding or removing this property does not have any effect on the final solution. Anyway, if you consider the kata too easy without it, just add the constraint; also, if you think it’s horribly hard, you can just ignore it.

Solving the kata (you can find it on my github page: https://github.com/tamasgyorfi/Code-kata—Fibo-Emirp-numbers) made it clear that two rounds of twenty minutes each would be enough. However, I did not take into account one important thing; the kata is not the best due to its character: a number has to be checked again and again and again against all the must-have properties. Putting together lots of different algorithms doesn’t make a good kata.

The goals of this kata were:

  • clean code with self-explanatory names
  • production code is added on red bar only refactoring is carried out on green bar only.

We also had an innovation this time, namely the introduction of infinitest (can be downloaded as an Eclipse plugin from http://infinitest.github.com/). Infinitest is a great automatic unit test running tool, that finds out which test cases are related to the source code being edited and runs them upon save. Such a way one can have a really fast feedback on the correctness of code. I’m looking forward to using it in our new project.

After the teams have solved the kata I’ve noticed a very important progress element: the guys were creating test cases step by step as described previously. Three weeks ago they were trying to write tests for the uppermost method, spending the whole time “in red”. Now, I’ve seen red and green bars alternatively which has made me glad 🙂

A lot of progress, go on folks!

Code Kata Nr. 2

Since after the first Kata we’ve completed I received quite good feedback, we went on with a second one. I thought this time we’d start from something simple, having the possibility to complicate the exercise as much as possible. The basis of the Kata was again a little quiz from www.rubyquiz.com, namely string equations. However, I modified the syntax a little bit  to better fit for Java and avoid frustration from teams side.

So the exercise itself sounds like this:

  1. Given a string in the form ‘word1’ & ‘word2’ & ‘…’ == ‘wordn’ & ‘wordn+1’ & …, called a string equation. The two sides are equal if and only if the left side (without the apostrophes and &s) is an anagram for the right side
  2. Words might contain asterisks (yeah, yeah. I know… Words usually don’t contain such characters. But anyway, let’s just stick to the exercise) . Words that contain an odd number of asterisks are invalid ones, so they should be removed. Such a way they don’t count at the final anagram check. (I reached this point in a two-round kata, you can see my solution on my github page: https://github.com/tamasgyorfi/Code-kata—string-equations)
  3. Words that are palindrome (are the same read from the beginning and end) don’t count either.

We had an hour resolved for the Kata; I asked the guys to take extra cares of two things:

  • Self explanatory names (classes, methods, variables etc)
  • Correct usage of assert functions of JUnit

The first round took 20 minutes, all the pairs opted to work on the basic version of the kata. After the first round we had two complete solutions. At the discussion after the first round I was glad to hear the guys talking about writing much more unit tests then a week before.

In the next round, the two pairs having completed the first version started working on the extended kata, while the others tarted over the basic one (of course everyone had to delete their work so far -not actually delete, but unload it from eclipse).At the end we had again a complete solution, and a halfway-completed one (I told the pairs the main goal was to write clean and tested code, and not to just have a working implementation of the exercise. I see that they still think the only measure of these kata sessions is completely working code. Hope this will change over time. Till then I’ll tell them every time.)

What I saw after looking at the codes the guys wrote, I can say that this kata was even more successful than the first one. More test cases, better collaboration, correct usage of asserts (yeah we have that action point completed! Nicely done guys, we can move on to another one). However, classes and variables have had kind of strange names (I even saw a class named WTF :-)), like p1, p2, k, c etc. I also saw quite many long functions, hard-to-understand logic and overcomplicated algorithms. I definitely think that we are going to need a refactoring workshop, where we can look at several widespread antipatterns, and have them corrected.

Maybe I can arrange it it a week or two.

Code Kata Nr. 1

The credit card number checker kata

Some time ago, I was browsing www.rubyquiz.com, and found a very good exercise, namely “Credit Card Checker”. It’s not only nice because it is based on some ‘real-world-stuff’, but also because it has all the features a great TDD code kata needs.

Let’s see what the exercise is all about:

  1. Starting with the next to last digit and continuing with every other digit going back to   the beginning of the card, double the digit
  2. Sum all doubled and untouched digits in the number
  3. If that total is a multiple of 10, the number is valid

Some weeks ago me and my colleague have started working on the exercise above, and found out this would serve as a great kata (for beginners or a bit more advanced TDDers). In order to make it slightly harder, we also added the constraint that the card number’s digit groups must be separated with spaces (so some string operations are involved).

Here is what we came up with, after a kata of just one round (it could be improved, but as I mentioned, we had time for one round only) -the whole of source code can be found here, you can take a look, comments are welcome-: https://github.com/tamasgyorfi/Code-kata—credit-card-checker

Having solved this, I thought it would serve as a great first kata for my new project’s teams. It is a good start for several reasons:

  • it’s simple enough to be understood
  • it’s hard enough for TDD newbies to take them two or more rounds (anyway, extra constraints can be introduced for those progressing too fast.)
  • test cases are quite simple and straight-forward (just follow the steps above)
  • one can achieve 100% code coverage
  • confers the feeling of self-confidence upon successful completion

Although no one was able to finish the exercise entirely, there were some really good ideas, and we’ve got an almost-ready solution. We have had two rounds; the progress between those two rounds was a striking one. The second round’s solutions were waaaay better, every pair made significant progress.

One of the team members has mentioned after the first round, that he was under pressure because of the time limit (which was set to fifteen minutes). I told him it was important for progress measure, as we compare the first round’s solution to the second’s. I also told him, that his second solution would be far better than the first. And guess what, he proved me right. They (as we were working in pairs) managed to get way farther then they did at the first time. I hope I convinced him that time limit was necessary indeed…

In spite that we had no fully finished solution, I consider this kata really successful. The teams finally had a “do-it-yourself” session of TDD, and I think it was a good experience for all of us. Who knows, maybe we’ll look at this kata once more in some months and observe the progress made…