Being Cellfish

Stuff I wished I've found in some blog (and sometimes did)

June, 2009

Change of Address
This blog has moved to
  • Being Cellfish

    Kanban explained with pictures

    Henrik Kniberg recently posted a number of comic strips describing the essence of Kanban pretty well. Using humor is not only funny, I think it makes the message stick a little bit better. The only downside with this comic is that it might not make all that sense if you have no idea of what Kanban is, but if you know at least something, then it should make some sense. In the comic I especially like how it shows a good way of handling a problem.
  • Being Cellfish

    Why it is worth adding tests even when the investment is large


    Have you ever found yourself fixing a bug or adding a simple feature to some code that have no tests and since you usually do things test driven you know you should get the code under test but you decide not to because the change only takes a few minutes and getting the code under proper tests would take days? The first time it might feel OK but then you find yourself having to touch that code again later and sooner or later you end up regretting you didn't get the code under test the first time.

    I've been in that situation and each time I make the same mistake since the trade off feels reasonable. But in hindsight almost all the time it would have been better getting the code under test right away. And a few days I found somebody who actually took the time to get some numbers proving why you should get the code under test as fast as possible. The interesting fact is that in two large projects (gcc and python) the probability of touching the same code twice in the same week is 35%. The number might be a little on the high side since touching the same file twice in the same week does not necessary mean you're working on two different things. It might be incremental check-ins. But if they're incremental, then it's probably worth getting the code under test anyway since you're spending days on the code anyway. It is also interesting to see that there is almost a 50% chance of touching the same code twice in a month.

    So now we have great statistics and a gut feeling telling us to add tests the first time even if it feels costly at the moment because the probability of the investment to pay off within a few weeks is very high. And you'll be much happier the second time around this way...

  • Being Cellfish

    Making the smallest change to make a test pass is not the same thing as making the simplest change


    Considering my recent rambling about the power of words I had an almost embarrassing experience at yesterday's dojo. When you look at the existing TDD literature it typically says; write a failing test, make a smallest possible change to make the test pass. When I learned TDD I also learned that being able to make these small steps is the important part because that is what you revert back to when things get difficult but in practice you might skip the simple, almost stupid things. When you're in a flow you don't typically write code you know you'll refactor in two seconds. Let me explain with two examples. Let's use the Bowling Kata as an example. Let's assume you have a test for a gutter game (all zero rolls) where the implementation just returns zero we would have something look like this for the implementation:

    1: public class Game 2: { 3: public int Score(int[] rolls) 4: { 5: return 0; 6: } 7: }

    Adding a test for a all ones, making the smallest possible change to make it pass could look like this:

    1: public class Game 2: { 3: public int Score(int[] rolls) 4: { 5: if (rolls[0] != 0) 6: return 20; 7: return 0; 8: } 9: }

    However there is another simple thing you can do with a few more key strokes:

       1:  public class Game
       2:  {
       3:      public int Score(int[] rolls)
       4:      {
       5:          int score = 0;
       6:          foreach (int roll in rolls)
       7:              score += roll;
       8:          return score;
       9:      }
      10:  }

    Either you argue that my first example is simple and stupid and that the second one is better. But then I could say that the coding dojo format is intended to always do the smallest possible changes (baby steps) and the second version implements more than just an all ones game. Actually baby steps is defined as small steps to keep them trivial. The first dojos I attended however kind of enforced smallest change possible and that makes sense in some way because I think it proves that even when being almost stupidly strict you eventually end up being able to refactor into something nice. The down side however is that it is a terrible experience if want the dojo to be a good TDD experience for people learning TDD because all that minimum changes makes your progress really slow.

    So let's look at the last version again. Sure it implements more than just a all ones game but that is conceptually the same thing as all twos and so on. Only strikes and spares are really different. Also the last example involves more key strokes but it is still simple since it only solves one dimension of the problem (the other dimensions being spares and strikes) and it is also a simple change that is easy to understand.

    And another good thing about focusing on simple changes over small changes is that simple is what you should do all the time while the smallest often is skipped for a larger but simple change. So much in the same way Behavior Driven Development and Example Driven Development better describe what Test Driven Development is all about I think simple change better describes what you're supposed to do. Both in a coding dojo and in real life.

  • Being Cellfish

    Team Coding Dojo 3


    We basically did two changes this time compared to last time. We adopted the micro pairing previously discovered and we tried a new Kata; BankOCR. I had prepared a variant of BankOCR where we added one user story at the time so that the group didn't really know what was coming later. Since we only got the initial parsing and check-sum calculations done we decided to bend a dojo rule for next time and actually continue where we ended this time. It'll be interesting to see where that takes us.

    We also made an interesting observation that is worthy a post of it self.

  • Being Cellfish

    PAL to NTCS converter


    Finding a good PAL to NTCS converter turned out to be harder than expected. I needed something for my Wii, DVD player and digital video camera. And also something that would work with the TV I got. Turned out I had to dig a little bit more into my pocket than expected but so far I'm satisfied with my purchase (CMD-HDX98). The only downside is that if we decide to move back to Sweden it cannot be used for NTCS to PAL conversion.

    So a few pointers to you if you're looking for a PAL to NTCS converter. The cheap ones do not convert sound so you might notice unsynced sound. Second the cheap ones might convert between PAL and NTCS but does not change the update frequency (from 50Hz to 60Hz) which is needed unless your TV can handle that for you.

  • Being Cellfish

    Extreme Interviewing


    During an interview I've always found it hard to get all the facts I want about a candidate. Several years ago I gave up on technical details. More important is to see if the candidate is interested in learning new things and how good they are at accepting help solving a problem (if they can't solve it them selfs). And I want to find quitters who give up early when they face a difficult problem.

    The typical Microsoft interview for developers typically involves solving a number of problems using a white board (tale from interview). And I think people passing that test is generally people who can deal with stress and perform under pressure. And also have the ability to communicate well with others. But I think this method also rejects some great developers that are great assets but who don't really like performing in front of others. Depending on what kind of person you're looking for there might be other ways of finding the best candidate(s) I think.

    A while ago I read somewhere about someone who used pair programming as an interview method. I think this is a good method even if you don't use pair programming daily because it is more relaxed taking some pressure off the candidate. It also makes it easier to see how the candidate works with the development tools and you get some insight in how the candidate thinks but it might not give you any interesting designs (that depends on time available and task at hand I guess).

    Another interesting approach is extreme interviewing. I like how that method focuses on finding good team members. But it is not a silver bullet for all kinds of situations. For example I once worked as a contractor in a project where one of the other contractors was almost impossible to work with. One time when I reported a bug in his code and suggested a simple fix, he spent four hours rewriting the code (it was a SQL trigger) so that the bug was fixed but with less code. The new solution was so complex that I did no longer understand the logic. I later talked to the project manager about this guy and got the response: "Yeah, he's almost impossible to work with, but he's too good not to have on a project". And I kind of agree because he was really good at what he did. But he didn't leave a trace of code that was easy maintainable so I guess it might not be true it was worth it because I know he's no longer on the project...

  • Being Cellfish

    Power of words


    There is an old saying that the pen is mightier than the sword. The power of words, that is what words you use are very important when you want to teach or just get other interested in your ideas. An example of this is how Dan North came up with BDD. Another example is how agile principles talk about (continuous) improvement rather than change. Because change can be both good and bad. Improvements however are always good. An example from outside software development is how a Swedish dish called Lungmos (literally mushed lungs) was renamed to Pölsa (which does not really mean anything) in hopes of getting increased sales (guess it failed due to the taste). Actually I don't know if the name change was because they wanted to increase sales but it makes a better story that way...

    Another common example is the use of "but" vs "and" in a discussion. A fun game I learned in my Scrum training was having two people plan a party by each saying a sentence or two. The twist is that in one case one person must always start their sentence with "yes but" and then you try the same thing but always respond with "yes and". An example:

    - We need a nice place for the party.
    - Yes, but we also need drinks.
    - Should we also have food?
    - Yes, but we must also have vegetarian options.

    - We need a nice place for the party.
    - Yes, and we also need drinks.
    - Should we also have food?
    - Yes, and we must also have vegetarian options.

    Which one of the two alternatives sounds more productive for both parties? In the first case it sounds like having drinks and vegetarian food is a problem that must be solved. In the latter case drinks and vegetarian food is not so much a problem but rather a way to add details to the planning. These are just a few examples of how the words you choose when you communicate with your colleagues, customers, friends and family may influence how your message is received. So choose your words wisely...

  • Being Cellfish

    Test readability


    I read this excellent post on test readability a few days ago. I like the way he shows how he refactors a test for readability but personally I would have written the example test a little bit differently. First of all I would have added another extension method:

    1: public static void PushOkButtonMultipleTimes(this ILoginView view, int times) 2: { 3: for (int i=0; i<times; i++) 4: view.PushOkButton(); 5: }

    With that extension method my version of the test would have looked like this:
    1: [Test] 2: public void only_three_login_attempts_are_allowed() 3: { 4: presenter = given_a_login_presenter_with_bad_credentials(); 5:   6: view.PushOkButtonMultipleTimes(3); 7:   8: view.ShouldBeClosed(); 9: } 10: 11: public ILoginView given_a_login_view_with_bad_credentials() 12: { 13: ILoginView view = CreateLoginView("BadUser", "BadPassword"); 14: ILoginService loginService = CreateLoginService(false); 15:   16: LoginPresenter presenter = new LoginPresenter(loginService); 17: presenter.Initialize(view); 18: return view; 19: }

    I personally prefer to move as much as possible of test setup to separate methods that are called explicitly by the test. The use of the extension method to remove the three times duplicated PushOkButton call is not something I'd always do. I was considering having the for-loop in the test method but I think an in place for-loop is less readable than making the calls three times. The extension method wrapping the for-loop however removes the duplication without decreasing the readability of the test.

  • Being Cellfish

    Random SQL


    I must say that I have never used the random functionality in SQL more than once in my life and that was not for work, it was in a hobby project. Never the less, I find this article (free registration required) on how the RAND function works and is seeded quite interesting.

    A summary of the article: You want a random number for each row in a result to do some kind of filtering. The problem is that the RAND function by default uses date/time to seed the random so in a query you don't really get any different random numbers. So you need a nifty way to seed the random for each row. The article proposes: RAND(Checksum(Newid()))

    The use of Newid in the link above might however not be practical for performance reasons. If you want to try some other ways to produce random you can find more alternatives here.

  • Being Cellfish

    Invest in good user stories


    INVEST is an acronym to help you remember how to write good user stories.

    • Independent - avoid dependencies between user stories.
    • Negotiable - is there a possibility to implement both basic and advanced versions of the story?
    • Valuable - can the story deliver customer value (i.e. something the customer wants)?
    • Estimable - is it possible to estimate the story?
    • Small - will the story fit into an iteration (together with a bunch of other stories)?
    • Testable - is it possible to test the story? Automatic testing is preferred but not needed.

    Negotiable is the part of the acronym I find a little bit funny. Why do we want a user story to be negotiable? I tend to look upon it as this; if the story is too detailed there is no room for adjustments when the story is implemented. Having a few unknowns in the story means it is easier to write a story (since we don't have to be detailed) and it encourages the developer to talk to the customer about the details when the story is implemented. This means the details of the story will be exactly what the customer wants when the story is implemented instead of what the customer wanted when the story was written.

    Another hard part is to keep stories small. A good description of different ways to split stories can be found here.

Page 1 of 2 (11 items) 12