Tuesday, November 8, 2011

WattDepot Katas

So I spent part of this week and all of this evening getting up to speed with WattDepot by completing a few practice katas. Each kata took me about an hour, though for different reasons.

The first couple katas were simple requests from a WattDepot server.
Given the sample code from the WattDepot client tutorial, this required only a big copy-and-paste and the modification of a couple lines.

These still took a couple hours, though, because I did the first couple katas in class on a day that we tried pair-programming. I think this might be a good practice once both programmers are comfortable with the API and understand the problem at hand. As it was, we spent most of the time setting up our Eclipse projects and then reading the assignment and the WattDepot documentation over each other's shoulders. I also switched groups halfway through, and we were also required to swap laptops periodically. This means the second pair I was in ended up starting over again at the beginning of one of the katas on a different machine.

Lulled into a false sense of security that these katas would all be as easy as the first couple, I returned to the project late this afternoon. I first took some time to install the FindBugs plugin in Eclipse. (I've been gradually installing plugins for tools that I have so far been using Ant to run. It's generally tedious and slow to run Ant compared to a plugin. But it's been a slow transition since I like to spend an hour or so reading the documentation and playing around with each plugin before I install the next one.)

After cleaning up what code I threw together in the last few minutes of class to see it work, I finished up kata #2. That kata and the ones after it all require sorting a list of key-value pairs by value. This stumped me a for a little while because this should be very easy... but it's not. I surfed a few 1/2 to 1-page posts of code that sort a Map by value. There were a few nice one-liners, but they required Google Collections and I didn't want to mess with an extra library.

In the end, this is my solution to sorting a key-value list by value. It's conceptually a "two-liner", but all the generics and the anonymous class make this look horrible:

  Map<String, Long> map = ...  //the map to be sorted by value

  //dump map into a list of key-value pairs...
  List<Map.Entry<String, Long>> entryList = 
      new ArrayList<Map.Entry<String, Long>>(map.entrySet());
      
  //...and sort it with a comparator that sorts based on values
  Collections.sort(entryList, new Comparator<Map.Entry<String, Long>>() {
      public int compare(Map.Entry<String, Long> left, 
                         Map.Entry<String, Long> right) {
        return left.getValue().compareTo(right.getValue());
      }        
  });

  //now print the list in value order
  for (Map.Entry<String, Long> entry : entryList) {
    System.out.print(entry.getKey() + ": " + entry.getValue());
  }

This solution also assumes you don't need map-like access to the sorted version, but just need to run through it for a simple task like printing.

The other time-consumer was learning how to use java.util.GregorianCalendar and
javax.xml.datatype.XMLGregorianCalendar. (There's also org.wattdepot.util.tstamp.Tstamp,
though I didn't find this to be as useful as I'd initially hoped.) This was another example
of something that should be easy but isn't. For example: "Give me the date of the most recent
Monday". It seems we have to start with the current time, for which I chose to use a GregorianCalendar object. Then, after a few lines spent modifying that time to the desired relative Monday date,
I had to translate it to an XMLGregorianCalendar. This was fairly long and messy with the various required
factory objects and exception handlers. I still like Java a lot, but I must admit that detractors
have a point about how much grinding tedious boilerplate you have to wade through sometimes.

I also need to take a minute at some point to figure out how to control Eclipse's insertion of try/catches. The quick default just wraps the one line in a try block, which requires so much reformatting that the feature is hardly worth using in most cases.

In the end, I got all the katas done. This was the first time I've written an application that deals with a web connection behind the scenes. It is pretty slow and variable (read: flaky) at times due to network access delays and potential connection time-outs. For my last kata--which took a couple minutes to gather all the data it needed--I added a little "status indicator" by printing a series of dots.

I spot-tested my katas as I went. However, if they were production code, I think I'd like to test them a little bit more to make sure I'm really pulling the right data and that all my calendar manipulations worked correctly. But since they are mainly katas intended to practice solving the problem, I think they went quite well.

No comments:

Post a Comment