What are “lamp post metrics”?
If you lose your keys between the restaurant and the car on a dark night, when you go back to look for them, where are you going to look? Of course, you are going to first look where there is light — under the lamp posts. When you pick a metric because it’s easy to gather, that’s called a lamp post metric.
Why are they bad?
Let’s look at an example.
A few years ago, someone noticed that when Carmelo “Melo” Anthony or Monta Ellis were out sick or injured, their teams had a better chance of winning the game. This was surprising because both players had top ten in the NBA points/game stats for the two years of the analysis. However, points per game is a function of two other metrics: 1) how often you take a shot; and 2) the percentage likelihood that each shot will score. It turns out that these two players had high points per game stats simply because they took more shots. If we were talking about hockey rather than basketball, this would be a good thing. In hockey, good hockey players create more opportunities to take shots but in basketball your team gets a shot essentially every time you go down the court. So, Melo and Ellis were literally stealing shots from other players on the team. That wouldn’t be so bad if they had the highest chance of sinking each shot but that’s not the case. They both had a lower chance of scoring each shot than the weighted mean of their teammates on the court.
Points per game is a lamp post metric. It’s easy to gather and understand. We reward these players literally with fame and fortune based upon this metric. However, what really matters is winning games.
What does this have to do with ODIM?
We do this sort of thing all the time in business. We drive behavior with metrics when those metrics are not good proxies for the desired outcomes. That’s why I introduced the ODIM framework — to help teams and organizations pick metrics that will drive the desired outcomes.
The effect of measurement goes like this:
Effective measurement and visualization provide better insight. Better insight leads to better decisions. Better decisions lead to better outcomes.
However, as our NBA example above illustrates, when you are making metrics decisions, it’s best to begin with the end in mind. By that, I mean, you should start with the Outcomes you are a trying to achieve and work your way backwards to the Decisions that drive those outcomes, then the Insights that will help you get there, and finally the Metrics and visualization that will give you that insight. That’s why the acronym is ODIM rather than MIDO.
Back to the NBA example
We agree that the desired Outcome is winning games. The Decision we want to make is the decision that players make many times a game — whether to take the shot or pass the ball. The Insight that would best inform this decision are things like, “From this point on the court, when I’m up against a player that is bigger/smaller than me, what’s my chance of scoring?” and “What are the chances of the other players from where they are standing or where they could move to?”. So, you’d need Measurements (metrics/stats/visualizations) that represent this. From that, you’ll look for patterns that can easily be used at game speed.
A simple version of this was used by a number of NCAA teams and those teams that used this went much further on average in the NCAA tournament than they were predicted. Their analysis showed that it was bad to take shots at middle distances from about the distance of the free-throw line to the 3-point line. These shots had a lower chance of going in than ones closer in and they were worth less than shots taken from behind the 3-point line. These NCAA teams coached their players to not take shots from this middle-distance and in looking at the heat map of shots, it’s clear they achieved this.
Not all insights are so heuristically simple. You may need more nuanced coaching and it’ll take time to change game-time behaviors. One-on-one coaching using retrospective analysis of each shot a player took in the last game where the coaching is informed by these stats will go a long way toward achieving this.
Agile Team Example
Let’s say your team’s desired Outcome is to ship more value, sooner. Each day, maybe several times a day, they make the Decision to either take on more tasks or to help finish the ones that their team has already started. If they have the Insight that lower work in progress (WiP) directly correlates with faster time to market, then the Measurement of the team’s current WiP will give them the needed insight to make the best decision between pulling in something new to work on versus doing something to finish work already started… even if that something means swarming on work with other team members.
Join me for a workshop on ODIM… and more
Seats are filling up fast for my workshop, Around the World of Agile Metrics in One Day, on October 17 in downtown Raleigh, NC. If you found this post on ODIM useful, it’s only one of many similar pieces of content we explore during the day.
Join my mailing list so I can let you know about my upcoming workshops and seminars.
A drop-in replacement for localStorage that runs on node.js.
I’m working on a project to do local caching using localStorage. I want it to work in both node.js as well as in the browser. I have a similar situation with my RallyAnalytics project where I use driverdan’s node-XMLHttpRequest as a drop-in replacement for the browser’s native XMLHttpRequest object. So, I decided that the best approach would be to build my caching mechanism on top of the localStorage interface. Since I couldn’t find one in the wild, I created node-localstorage. It might be useful for testing or you may have a situation like mine where you want to run the same code on the server/desktop as you run in the browser.
github repository (including usage and installation documentation)
Slides from my talk in silicon valley on my ODIM and Rally’s Performance Index frameworks for agile measurement.
Subtitle: when CoffeeScript rock stars run around naked in public
Just because you can do something doesn’t mean you should. Leaving the parentheses out of your CoffeeScript might make your code look a bit more “natural”, but it almost always makes the code less readable and in a many cases, it makes it impossible for the CoffeeScript compiler to understand your intent. It’s more “natural” to go around naked but you shouldn’t. Just like you need to cover your private parts when you go outside, I feel strongly that you should properly cloth your CoffeeScript function/method parameters in parentheses.
In the last few months alone, on StackOverflow, there have a been at least six questions that I have flagged as caused by this issue:
- Calling functions with no parameters
- Lambdas with multiple functions
- Help showing code flow with jquery
- Calling a function which calls a function
- Confusing space
In all of the cases above, there is an idiom that you can’t precisely/clearly express without parentheses around function/method parameters. Often, the coder realizes that it’s ambiguous but “hopes” that the compiler can figure out his intent. He posts a question on StackOverflow once he is able to show that it cannot. In all of these cases, the coder has learned CoffeeScript by looking at a bunch of examples that leave out the parentheses and he doesn’t realize that you can put them in… or he wants to know how the cool-kids express it without them. In each case, the answer is invariably, “Simply add parentheses and it will work as expected.”
If this is confusing the compiler and the new users who want to be CoffeeScript cool-kids, we CoffeeScript bloggers should all make an effort to post all examples with the parentheses left in. I’m going so far as to leave them in all of my code and my collaborators seem to appreciate it. If nobody ever needs to read your code, then feel free to walk around naked in a drug-addled state within the privacy of your own home. But as soon as you step out the door, or want anyone else to read your code…
It’s perfectly fine to leave them out of if-statements, while-loop, etc. We like our female rock starts to show a little cleavage and some folks get turned on by Mick Jagger’s tight leather pants.
Chaining (needed for compiler to understand intent)
Calling a parameter-less method (also necessary)
Function/method calling (even when not chaining, for human clarity)
…I even favor including them when the last parameter is a callback (although I do cringe every time I see that lonesome closing paren a few lines down so I’m OK with you leaving them out in this case).
someMethodNeedingACallback(parameterA, (err, data) ->
Functions with no parameters (could live without this, but IMHO, it’s more readable with it)
f = () ->
return "hello" # notice how I also like to say "return". That's another clarity choice.
One last argument to try to convince you… Python is the most readable programming language out there. The Python BDFL has come out time and again in favor of readability even at the expense of conciseness. Python used to have a parentheses-less
I know… you want to show that you are a CoffeeScript cool-kid. You can write a one-line list comprehension that is like a brilliant guitar solo. But I think it’s cooler for my code to be readable and for the compiler to precisely understand what I intend. The list comprehension guitar solo may be showing off but we expect our cool rock stars to show off. However, it’s uncool (even for rock stars) to be drug-addled running around naked in public. Be the rock star without the drugs… or running around without your function/method calls properly clothed in parentheses.
The examples you add to document your project are like a map to the buried treasure that is your library/API/tool/etc. But if the examples are wrong, it’s like labeling the map with “promised land” right over the spot where it should say, “there be dragons”.
It’s less about testing your code with your documentation, than the other way around. Make sure that the examples in your documenation stay current with your code. coffeedoctest is a way to test your documentation with your code… to make sure that the map matches the terrain.
If you’ve spent any time working in Python, then you are probably familiar with doctest. Coffeedoctest is built along the same lines.
For entire story visit the coffeedoctest project page on github.
I’m neck deep in RESTful APIs. I’m in the late stages of designing the Analytics 2.0 APIs in my job as Product Owner for Analytics at Rally Software. I’m in the early stages of designing an API for the Lean Software and System’s (LSSC) Kanban Benchmarking and Research Program… and just today, I met with Steve Speicher and others from the Open Services for Lifecycle Collaboration (OSLC) to talk about joining one of the working committee designing RESTful services for data interchange.
I have been struggling with one aspect of “pure” REST APIs as defined by the four constraints in Roy Fielding’s dissertation. In particular, it seems that almost none of the popular “RESTful” APIs on the internet implement the Hypermedia as the Engine of Application State (HATEOAS) constraint. If the constraint is so critical, as Dr Fielding insists, then why is it so often ignored? The idea is that operations that you perform on a resource should be made visible to clients not via documentation but rather via links in the responses to a few published endpoints. A good citizen consumer of a truly RESTful API will not know the link to transfer bank funds, or approve a leave request, or (any action) on (any resource). Rather, it will “discover” the links for these actions in the initial response to a query against the bank account, or leave request, or (any resource).
My main problem with valuing this constraint as highly as Dr Fielding seems to is that it doesn’t seem to greatly reduce coupling as intended. The client still needs to KNOW that you want to transfer, approve, or (some action). Knowing the link to do so before hand seems like a fractional increase in coupling. That said, if it doesn’t cost too much, it would be nice to follow this recommendation because it would fractionally reduce coupling.
That brings me to my second conundrum. The Analytics 2.0 APIs are all read-only. What “application state” (as opposed to resource state) is there in such a situation? Then today, it finally came to me… the only application state (that I can think of) in a read-only API is around paging. The first page response to a multi-page request should include the link to the second page, and so on. This is particularly useful for Rally’s Analytics 2.o Lookback API because we were already recommending that the requests for the subsequent pages include an additional clause to ensure that the data returned for the subsequent pages is for the same moment in time as the first page. We had little confidence that this recommendation would be followed. Now, I’m specifying that we add a NextPage link to each response. We may also remove the “start” parameter from the API as it enables a tighter coupling than the use of the NextPage link.