Friday, June 26, 2009

Visible Metrics with Corey Haines



We've been discussing Metrics in the Software Craftsmanship Group and I just posted some notes on the topic yesterday. Today, I had an opportunity to watch Corey's "Road Thoughts" on Visible Metrics.

Road Thoughts - Visible Metrics from Corey Haines on Vimeo.



And I like where Corey is headed with this. The measurements discussed are related to code quality. They apply to a code base written by one or by a team of hundreds. These metrics can and should be used for good. Developers can monitor their improvement or ensure their quality does not slide.

Corey takes this concept to a new level; comparative metrics. Metrics that are gathered about your code base, but are devoid of any specific intellectual property. These metrics are then shared, perhaps publicly or perhaps anonymously, for collective comparison. So not only can you then monitor your own quality, but you can compare against others. How do you mark against the industry as a whole? How do you mark against companies of similar size in your regional location? How do you compare against individuals around the world in your language of choice?

With courage, what can we as a community do to help each other learn and grow?

Thursday, June 25, 2009

Metrics in Software Development



Today I posted an entry on the Google Software Craftsmanship Board. In the posting, I asked if anyone had experience with individual velocity metrics on an Agile project. I posted a similar (but more brief) inquiry on Twitter as well.

The responses were varied and the discussion was good. But I was a bit surprised by the overall quality of the responses.

First of all, I had to rephrase the question more than once before anyone answered it. I received many vague and prescriptive responses stating it should not be done. But most folks never indicated if they had personal experience with it. "That's not the agile way" seemed to be a satisfactory argument. No additional support required.

Only one respondent directly stated they had experience with using individual velocity metrics. They also described a disastrous outcome; a complete breakdown of trust, quality, and throughput. All of which, were attributed to the collection of a single data point. Seems to me a project that crashes and burns that hard has issues beyond collection of a metric. Perhaps the collection (or use) of the metric was an indicator of a greater problem, but I doubt it was THE problem. In other words, the team was likely to suffer the same fate whether or not personal velocity data was gathered. More likely, the motivation behind the collection and use of the data was the real issue.

As the discussion progressed, there seemed to be a dangerous general consensus; metrics that apply to individuals are bad and metrics that apply to groups are good. While the discussion started with velocity, it took a winding path through all forms of data points; code coverage, cyclomatic complexity, estimation accuracy, etc. The danger here is the generalization of good and bad based on individual or group respectively.

Good points were also made. Many spoke of the need to understand the purpose of the metric. As one individual put it:

(1) you need to be aware of what question you are asking and what situation you are trying to change;
(2) you need to understand what the relationship between a given metric and a given property is;
(3) you need to [be] clear under what circumstances the metric will cease to be relevant.


Anthony Broad-Crawford said it very well:

As a manager myself the primary goal of metrics is to simply create a "check engine light". Meaning, when the light comes on, it doesn't necessarily mean anything is wrong. What it means, is you should "pop open the hood" and start asking some questions to figure out if something really is in fact wrong. For example, if you did track individual velocity metrics, and someone did report a very low number for the iteration, a check engine light should come on. It doesn't mean the developer did anything wrong or sub-par. It could be for any number of good things (pair programming, design sessions, training, etc). However, if a goose egg is thrown, and they didn't participate in anything that would account for the goose egg (extensive pairing, design sessions, training, etc) something may be wrong and you as the manager should find out.

I do agree if management simply looks at the spreadsheet and makes assumptions (good or bad) based on some threshold it will be problematic. Metrics, must like everything else, are not black and white. A good manager (IMO) will realize that metrics are shades of gray and act accordingly.



The discussion was primarily about the need for individual velocity metrics. And the general consensus (on Google and on twitter) was that individual metrics are bad while group metrics are good.

But metrics, whether individual or collective, can be used for good or evil. They can result in improved or hindered performance. They can tell a valuable story or they can completely mislead.
To categorically dismiss all metrics related to individuals is almost as dangerous as categorically accepting all metrics that apply to groups.
We need to recognize that metrics without a clear and expressed purpose are noise at best and are quite likely dangerous. And the metrics are merely indicators; they don't tell the complete story. I like the "check engine light" analogy. Metrics let you know that you need to look into it further.

Monday, May 25, 2009

Altering your Session Key in Rails 2.3

I am working on a 'toy' application that I started a couple of Rails releases ago. When I ran my test suite, I received the following warning:

DEPRECATION WARNING: Disabling sessions for a single controller has been deprecated. Sessions are now lazy loaded. So if you don't access them, consider them off. You can still modify the session cookie options with request.session_options.. (called from /Users/docondev/[...]/app/controllers/application_controller.rb:9)

The line in question follows:
session :session_key => '_docondev_session_id'

I learned this technique from several RoR books written only a couple of years ago, but there is a better way to alter the session key.

Although I could have altered the line in application_controller.rb, I decided to put the settings in a more appropriate location. I removed the line from the application-controller entirely. I then altered the config/initializers/session_store.rb file.

The changes should be fairly obvious, but note that :session_key and been changed to :key. I alter the secret by replacing the end of the string with my application name. This is really not necessary, but it is a habit I've established, it does no harm, and it keeps my key and secret visually coupled.

ActionController::Base.session = {
:key => '_docondev_store_session',
:secret => '005000374cbcd1[...]docondev'
}

Wednesday, April 15, 2009

I disagree with Uncle Bob on this one

I am reading Bob Martin's "Clean Code - A handbook of Agile Software Craftsmanship" again. For the most part, I am really digging it. It reminds me a bit of Steve McConnell's Code Complete. I still have the original version of McConnell's book around here somewhere. But I digress (and show my age).

In Chapter 9, Martin covers unit tests. In listings 9-3 and 9-4, Martin shows the "simplification" of a unit test. Listing 9-3 makes two method calls followed by five assertions. Each assertion checks a specific state. Each state is clearly identified. I do not particularly like the five assertions. But this is not the point that Bob makes. This is not the correction he covers. Instead, he condenses all five assertions into a single assertion by introducing a string of seemingly arbitrary characters.

We go from:

assertTrue(hw.heaterState());
assertTrue(hw.blowerState());
assertFalse(hw.coolerState());
assertFalse(hw.hiTempAlarm());
assertTrue(hw.loTempAlarm());


To:

assertEquals("HBchL", hw.getState());

He goes on to explain that each character in our string represents a possible state; Capital is true, Lower is false. He follows up with, "Notice, once you know the meaning, your eyes glide across that string and you can quickly interpret the results. Reading the test becomes almost a pleasure."

WHAT?


"Once you know the meaning"? This is not from a solution domain. This is not from the problem domain. This removes clarity under the guise of improved readability. How, pray tell, am I to know the meaning? Is there a comment in the code to explain the meaning? Is he really suggesting that a blatant code smell is better than methods that clearly indicate the intended behavior? And what happens when getState needs to also return the humidifier State? How much code breaks? I should be able to introduce a new behavior without these issues.

I have to disagree with Uncle Bob on this one. This is NOT a better solution. It does NOT make the code more readable. I am suprised to see this recommendation and I bet it does not appear in the Second Edition.

Break each assertion out into their own test within the class, put them all into their own test class with a shared setup and tear-down, or use a Template Method pattern. Frankly, you could just leave them all in a single test given they all test the same single concept. But this string of place-holders with case representing on or off state is a fart in a garden of beautiful code. It just smells bad.

Saturday, April 11, 2009

Ruby on Rails - Basic Authentication

In this post, we are going to cover a very simple way to implement authentication in your application. This is not an appropriate technique for securing a commercial application in production. I use this technique to quickly "secure" an application while in User Acceptance. It allows me to put the application out on the internet and give it a single user name and password. This technique can also be used for easy REST authentication.

Let's assume your intention is to secure the entire application. Add the following to your application controller:

class AdminController < ApplicationController
before_filter :authenticate

private
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == 'UserName' && password == 'SecretPassword'
end
end
end

This will "secure" the entire application under a single account.

If you prefer not to put the plain-text password in the source, you can instead use the following:

require 'digest'

class AdminController < ApplicationController
before_filter :authenticate

private
def authenticate
authenticate_or_request_with_http_basic do |username, password|
encrypted_password = Digest::MD5.hexdigest(password)
username == 'UserName' && encrypted_password == '58d613129c5e71de57ee3f44c5ce16bc'
end
end
end
I used http://www.miraclesalad.com/webtools/md5.php to generate the hash

Thursday, April 9, 2009

10x Difference in Software Developers

I finished reading Uncle Bob's posting on Master Craftsman Teams and in the comments was a link to Steve McConnell on 10x differences in software developers.

I encourage you to read both articles along with the comments attached to each.

In McConnell's article was a paragraph that made me stop and think for a bit:

"Another factor is that, while numerous studies have found 10x differences among individuals, researchers have not found 10-fold differences among programmers working within the same organizations. Some research has found that good programmers tend to cluster within certain companies, average programmers tend to cluster within other companies, and so on (Mills 1983). So even if there’s a 10x difference industrywide, the difference you’d typically see within a given company is more like 3-5x from best to worst, which means the difference from best to average is more like 1.5x or 2x within any given company."


So which company am I in and with whom have I clustered? What about you?


I can say with certainty that I've spent some time at the bottom of the scale. Rallying against not only the organization as a whole, but against the fear and apathy of my own team. Clustered they had. And they settled in an environment that supported them. I posit to you - should you ever find yourself in this situation, it is far easier to change your circumstance that it is to change an organization. I should have left far sooner than I did.

Today, I find myself surrounded by wonderful, talented, people. I suspect I pull down the multiplier, but I aspire to be one of them. And the best way I know to improve yourself is to surround yourself with people who are much better than you. People who can push you, challenge you, and teach you. It worked for me as a musician. It worked for me as a runner. I am certain it will work for me as a software developer.

Look around. What end of the multiplier do you think you are on in your current organization? And are you clustered with the top, middle, or bottom of the scale?


Is that where you want to be...?

Friday, March 20, 2009

Values


Our Values...
... are the foundation for all decisions. They serve as the compass that guides us through our personal and professional lives. All action; all thought; in every way we represent ourselves; we must represent our values.

Be fair.
Find the answer that best serves all parties. Act upon your highest sense of right.

Improve.
Grow continuously, personally and professionally, in small ways. Evolution is the sum of many tiny, nearly indiscernible adjustments.

Innovate.
Seek new ways; seek new means; do the unexpected.

Take Initiative.
Present your ideas. Put forth the extra effort. The one who make the most mistakes, learns the most lessons.

Be accountable.
Answer for your mistakes and your deserved praise will come.

Be forgiving.
Seek to understand and assist. Do not condemn others for their differences. To criticize and dismiss leaves neither party better off.

Participate.
Become truly involved. Make this your team, for it already is.

Have respect.
Honor your coworkers and clients.

Live.
Make your life rich in many ways. Seek new experiences, new relationships, and a new perspective. Then bring it back and teach others.

And always, Tell The Truth.

- Michael J. Norton (1997)