Some time ago I was browsing on http://rubyquiz.com/ and found a really interesting exercise there. It’s name is Getting to 100. The rules are quite simple:
- You are given the sequence of numbers 123456789
- Each number in the interval [1-9] has to be present in the sequence
- Each number must appear once and only once
- Numbers should be in increasing order
- You are given three operators: two minuses and one plus that you have to insert between those numbers
- The resulting equation should be give 100
The actual task is to:
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):
- 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)
- 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).
Well, the following post is about some feedback I’ve recently received on my activity regarding our self-improvement group. I was really about to abandon the whole thing, but my friend Lajos Fülep’s kind words made me continue.
In the last two weeks our little self development group was busy with a brand new topic: namely legacy code (legacy code in the sense of: “code that is working suspiciously, and have no tests around it.”). Some time ago I’ve posted some really ugly code that is full of bugs and has no tests at all. As discussed there, two rounds should be taken: one for adding tests , another one for refactoring it (and fixing the numerous bugs the code contains).
The first round was a pair programming session. The task was to cover the code as much as possible, and spot the mistakes – spot but, don’t touch them (hint: there are at least four major bugs in there). This task can be implemented in an hour. After that, we choose a reference implementation for the second round.
The second round is done randori-based. It means that there is a single laptop along with a projector, while people keep rotating in front of the computer. Everyone is allowed to make a single change. A single change can be: extracting a method, extracting a class, renaming TWO methods, variables etc. Basically the “one change” rule can be adjusted as you wish. I was kind of afraid of this randori-session; I thought people would be afraid of being creative while all fellow group members are looking at them. However, it went really well; people kept saying “I want to stay, this was half a change only”. What is very important here is that anyone not in front of the computer can speak only after the next change to be made has been named by the person at the computer. This means that you cannot give tips what to be done next (only if it was requested explicitly), but can argue whether a change is needed or makes sense at all.
Here’s the feedback I’ve received (translated from Hungarian):
I found this session very useful. What I liked about it was the task itself. It was cool we had to refactor an ugly piece of code. On the other hand it was very useful to me to see how other people were working and thinking. Way to go 🙂
Code refactoring in progress :-).
A few weeks ago, I had this idea of organizing an in-house self development group. Since then, we have already had three weekly meetings, with a kind of tricky exercise to solve. Continue reading “Rediscovering Strategy pattern”
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;
- In order to solve it in TDD, it needs the random number either to be injected (dependency injection rulez!) or faked.
- Finally a kata, which requires you to have several classes.
- 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).
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:
- The problem is presented
- We have a first round of x minutes, when the players can implement their solution employing TDD
- After that we have a discussion round when everyone tells the others what and how did they do
- All the solutions are erased
- 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.
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 ):
- An IBAN number is an alphanumeric literal of at least five, at most thirty-four characters
- The alphanumeric string can only contain uppercase letters and digits
- The first two characters have to be LETTERS ( trough which we can identify the country of origin,
IT60Q0123412345000000753XYZ, we have Italy)
- characters three and four have to be digits (
IT60Q0123412345000000753XYZ, we’re doing great)
- the rest of the characters can be either letters or digits
- the first four alphanumeric characters have to be moved to the end of the string (Q0123412345000000753XYZIT60)
- all the letters have to be converted to numbers, following the formula: A=10, B=11, C=12 … (
- 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:
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.