Monday, April 30, 2012

Hard because its hard or because its easy?

Some problems are hard because they're actually hard.
Some problems however are only hard because the answer is so easy that no one tells you about them.

I recently encountered a problem of the latter type while playing around with Scala's Option type.  If you are not familiar with it Option is a type that can either hold a thing or hold nothing.  So, Option[String] is either a String or its nothing (actually None in Scala).  For reasons that you probably either already know about or don't care to know this is very useful when coding in Scala.

You can say things like:
   foo match {
     case None => // handle the case where is is None
     case Some => // handle the case where there is something

(Of course we Scala folks like tricky things and so we'd tend to say
  "case _ =>" in the second case, but for now you can ignore that as showing off).

So, imagine you are in the second case and actually have a Something.  How do you get at it?

You might think you'd say foo.Some, or Some(foo) or a variation on that theme.  Failing that you might check the documentation on Option or read up on the topic in one of the several fine books on the topic.  Unless you looked someplace I didn't you won't find too much.  Foo.some doesn't exist and most variations of Some(foo) give truely unexpected answers.  For example, try this:

val bla = 4
val foo : Option[Long] = Some(3L)
println(bla > foo)

This results in the pretty confusing error message:

:10: error: overloaded method value > with alternatives:
  (x: Double)Boolean
  (x: Float)Boolean
  (x: Long)Boolean
  (x: Int)Boolean
  (x: Char)Boolean
  (x: Short)Boolean
  (x: Byte)Boolean
 cannot be applied to (Some[Option[Long]])
              bla > Some(foo)

So, how do you access the "some" part of an Option?  The "obvious after the fact" answer is with "get".

You can say println(bla > foo.get)

I bet that most people learning Scala have struggled with this or perhaps are still struggling with it.  However, it seems like such a dead simple case that most people won't admit to having been confused by it.

That's my definition of hard because its "too simple to mention".

Wednesday, April 18, 2012

Retrospective Velocity - part 3 of 3

While it may take a huge effort to get your organization to move to Scrum, you can as an individual go compute your personal velocity right now.  Any bug tracking system out there will allow you to gather data about the number of bugs assigned to you and/or fixed by you per unit time. If it were a database query you’d do something like “select count(*) from bugs where assignee==”me” group by month(assignedDate)”.  Now, you may object saying “but I do lots of other things besides fix bugs”.  You would  likely be correct, and it still doesn’t matter.  If a third of your time historically gets absorbed by mind numbing meetings what makes you think next month will be any different?

All discussions of Black Swans aside, whatever last month looked like is a good starting point for guessing what next month might look like.  By all means measure each month and look for trends.  Perhaps you and/or your organization is getting better and your velocity is increasing.  Now we have more confirmation of that fact.  Or perhaps in response to missed deadlines you’re attending still more mind-numbing meetings to discuss such gems as why things take too long and so your velocity is decreasing.  Cold comfort perhaps but now you have data to back up that dark realization.

As an individual you might pick from several data sources to establish a velocity.  The selection may depend on your job function (sustaining engineer, development engineer, etc) and/or on the systems you are using for bug tracking, source code management and the like.

You might track the number of bugs fixed by you, the number of source code checkin’s you do, the number of code inspections you participated in or some combination of these and others.  One interesting strategy is to gather the data from as many interesting sources as possible and then graph the results for longest time period that you have data for.  If we assume that your actual theoretical velocity has been relatively constant you can select a data source or sources that results in a flat graph.  Of course if you have switched languages or processes or problem domain your velocity likely has not been constant so your mileage may vary.

Tuesday, April 17, 2012

Retrospective Velocity - Part 2 of 3

One of the key take away messages from the experts in the field of estimation is not to estimate at all.  To quote Steve McConnell: “ If you can’t count the answer directly, you should count something else and then compute the answer by using some sort of calibration data”.  So, if we can’t count our velocity directly we can count the number of bugs in our last project, how long they stayed open, how many requirements were present and so on.  Our calibration data is that all of those requirements and bugs took place in the time interval of the project.  It’s not especially fine grained but in a waterfall model we are not looking for fine grained data.

Some may argue that bug reports and requirements are not precisely defined and standardized.  What passes as a single requirement for one team might be 3-5 separate requirements for another team.  Some teams have bugs like “it doesn’t work” while others might enter a dozen or more particular bugs to cover the same underlying defect.  Here is the strange thing though: it doesn’t matter.

Just like story points are not standardized, all that matters is that within your team you tend to be consistent.   Whatever your team’s definition of a story point is if you’re doing Scrum is likely to represent about the same quantum of work next month that it represented last month.  In the waterfall world,  the level of granularity you bring to your bug reports is likely to be fairly constant.  The point to keep in mind is that we’re not looking to equate points or bug counts against anything but other points and other bug counts.  So, if your last several projects had 6 requirements, generated 60 bugs and took 6 months you have a velocity of 1 requirement and/or 10 bugs per month.  If you next project arrives with 15 requirements and a deadline of three months from now we can safely conclude that you are in trouble!

Keep in mind the distinction between accuracy and precision.   In the proceeding case we can say with high confidence that you are probably hosed.

Monday, April 16, 2012

Retrospective Velocity - Part 1 of 3

So how long is this going to take?  This is one of the most common questions to ask or be asked in a traditional software development environment, and one of the most difficult to answer.  The agile methodologies, and Scrum in particular address this problem with the notion of velocity.  Whatever your team accomplished in the last time period (sprint) is likely similar to what they’ll be able to accomplish in the next one.  Scrum’s use of burn down charts, standard definitions of “done” and retrospectives allows for the discovery of a team’s average velocity.  One can argue about hours versus story points and many similar details but almost any implementation of Scrum allows for tracking how much work was done per unit time.

Sadly, many projects are still using “traditional” methods (which seems to be one of the new names for waterfall).  One of the drawbacks of this approach is that the time scales are relatively quite large compared to Scrum, which also means there are fewer time periods to measure.  There is simply less data available is you have two six month buckets versus 12 one month buckets.  This is one reason that “traditional” projects do not typically end up producing a team velocity.  This in turns make it substantially challenging to estimate how long the next project will take.

There is however other data that can be mined so as to uncover this more fine grained time measurements we are looking for.  The data in question lives in your requirement tracking system, bug database and source code control system.  While these systems are often, shall we say imprecise, they do contain useful data.