Friday, August 05, 2011

Hanlon’s Razor

Never attribute to malice that which is adequately explained by stupidity. – Hanlon’s Razor

And a similar quote by Sir Bernard Ingham: “cock-up before conspiracy” (where cock-up refers to mistakes or foul-ups).

Thursday, August 04, 2011

Task estimation on Agile Projects

imageTypically I have used the planning poker estimation sequence when performing task estimation (1,2,3,5,8,13). Here the numbers represent hours instead of story-points as they normally do during User-Story estimation. We used a cut-off of 13, the number of hours above which we think the task should be broken down. The basic idea behind it was that using the planning poker sequence for the number of hours a task would take, provided a buffer to the estimates.

Recently we had a discussion at work on whether tasks should be estimated in just plain hours as estimated by the developers, or whether we should use the planning poker sequence to drive the number of hours estimate.

imageThe first thing to realize: its important to use different units for your user-story estimates vs. task estimates. This is accomplished by using story-points for user-stories and hours for estimates. This is useful because story-points are an abstract entity, making it easier to realize that the story-points are trying to capture not just effort, but also complexity and risk. In addition, it makes you also realize that story-points (as opposed to another unit like ideal hours) cannot be directly converted to number of hours that the user-story will take (although one can estimate this after a few sprints have passed and we have a team sprint velocity metric).

Back to the topic on hand: Based on research I have done, I am now a convert to using just plain hours for the task estimates (instead of using the planning poker sequence). Here is why:

  • User stories are large, complex and have a lot of uncertainty and risk. They are harder to estimate. Hence we use the planning poker sequence to reiterate the fact that there is probably going to be a magnitude of difference in the amount of work/time it will take to complete the user-story.
  • Tasks are how user-stories are broken down when it comes time to implement a user-story. An important point to remember is that a 3 hour task and an 5 hour task are not different by an order of magnitude, which is what the story-points reflect. Instead, the 2 tasks are different by 2 hours and that’s all there is to it. In addition, it is perfectly alright to have a task that would take 4 hours.  By sprint planning stage, the risk and complexity associated with a user-story should be known. In addition, tasks are typically items that the developers know about and can estimate well. Finally, the number of tasks that need to be estimated are normally small because they are done for the current sprint (where the sprints typically last from 1 to 4 weeks – smaller the better). Because of the shorter time horizon on tasks, one shouldn’t have to pad the estimates for tasks. Hence, one shouldn’t have to use the planning poker sequence, and should just use the actual time estimate for that task.

Remember, based on the cone of uncertainty: Story points are useful for long-term estimation. Hours are better for short-term estimation.

Some other notes:

Task estimation should still be done by involving all the team-members. The user-story should be broken down into tasks and estimates should be presented by all team-members at the same time (just as one would do during a planning poker session). Any differences in estimates should be discussed and a consensus estimate in number of hours for the task should be arrived at. (This in my mind is a modified wide-band delphi estimation technique).

Normally, I have done sprint-planning in two separate sessions:

session 1: break down the user-story into tasks

session 2: generate estimates for the tasks.

Its important to also realize that an estimate is not the same as a commitment to deliver (i.e., an estimate of 8 hours for a task is not the same as committing to deliver the work in 8 hours). Hence the commitment session should be separated from the estimation session. The team commits to what it believes it can deliver within a sprint, given the estimates of all the tasks, other work that the team needs to do and other factors.

Its interesting to note that in the 2011 Scrum Update, the following is said (further validating the fact that estimates are not commitments):

Development Teams do not commit to completing the work planned during a Sprint Planning Meeting. The Development Team creates a forecast of work it believes will be done, but that forecast will change as more becomes known throughout the Sprint.

Comments by Geoffrey Corey (Agile mentor):

User stories are still abstract things and should be story pointed. Planning poker and relative estimating with a benchmark story are two ways to do that. The purpose for the story points is to prioritize and identify high risk or nebulous stories that either are broken down or are candidates for a spike solution. Once the stories are sized and prioritized then a time box (sprint) can be set and based on sprint velocity user stories can be added. At that point it is useful to break down just those stories in the sprint into tasks.  

I totally agree that tasks should be done in hours, not story points. You can then add up the task hours and build a chart showing Story | Story Point | Total # of task hours.   This will show you if your story point estimates are in line with task estimates.   For example,  you many have around 20 hours of tasks to do for a 5 point story.   If you are within +/- 4 it appears you were consistent in story point estimates for all the 5 point stories.   If you have on 5 pt story that is 60 hours of tasks, then you might want to pop the flare early before the sprint and inspect what went wrong and if you should repackage the sprint.

Velocity is still done by story points.    Task estimation is just a validation of the planning poker estimate.

User story to task validation chart:

 

Story

Story Point

Total # of task hours

1

as a user I would like to pay using a credit card

5

25

2

as a user I would like to pay using a debit card

5

23

3

as a user I would like to register my account

3

15

4

as user I would like to login using Facebook Connect

3

25

5

as user I would like to reset my password

5

15

* the 3rd story probably has a bad story point estimate. the same is probably true for story 5.

References:

  1. Task estimation: Do or don’t? http://www.agilejournal.com/articles/columns/column-articles/1232-task-estimation-do-or-dont
  2. Are you using planning poker for estimating tasks? Maybe you should reconsider it… http://geeks.ms/blogs/jlsoria/archive/2011/05/19/are-you-using-planning-poker-for-estimating-tasks-maybe-you-should-reconsider-it.aspx
  3. Sprint and release planning should be in different units: http://blog.mountaingoatsoftware.com/sprint-and-release-planning-should-be-in-different-units
  4. Why I don’t use Story Points for Sprint Planning: http://blog.mountaingoatsoftware.com/why-i-dont-use-story-points-for-sprint-planning
  5. Separate estimating from committing: http://blog.mountaingoatsoftware.com/separate-estimating-from-committing 
  6. Agile estimation and the cone of uncertainty: http://agile101.net/2009/08/18/agile-estimation-and-the-cone-of-uncertainty/
  7. How to implement Scrum in 10 easy steps: http://www.allaboutagile.com/how-to-implement-scrum-in-10-easy-steps/
  8. Wideband Delphi: http://en.wikipedia.org/wiki/Wideband_delphi

Monday, August 01, 2011

Powershell: Test for variable existence

If variable name is helloWorld (referenced as $helloWorld):

test-path variable:\helloWorld

return true if the variable has been defined and false if variable has not been defined.

PowerShell 64 bit and Sql Cmdlets

I was getting the following error when I tried to execute a script that tried to load the Sql Powershel cmdlets.

Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2.
This error occurred only 64 bit machines and only when I ran the 64 bit version of Powershell.
To get around it – I had to go through the following 2 steps:

Step 1: update the registry to insert an entry in the Wow6432Node hive.
After installing Sql Management Studio on the machine where you are seeing this error, run the following script to setup the registry correctly.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps]
"Path"="C:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\SQLPS.exe"
"ExecutionPolicy"="RemoteSigned"

Step 2: Install and add the powershell cmdlets.

Next run the following Powershell script to install the Sql powershell cmdlets.

#
# Add the SQL Server Provider.
#
if ($SqlServerMaximumChildItems -ne $Null -and $SqlServerMaximumChildItems -ge 0)
{
    write-host '$SqlServerMaximumChildItems is defined - sql provider is already loaded. Exiting load routines....'
    exit
}
else
{
    write-host '$SqlServerMaximumChildItems is not defined - continuing to check if sql provider needs to be loaded'
}
$ErrorActionPreference = "Stop"
$sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"
if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
{
    throw "SQL Server Provider for Windows PowerShell is not installed."
}
else
{
    $item = Get-ItemProperty $sqlpsreg
    $sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)
}

#
# Set mandatory variables for the SQL Server provider
#
Set-Variable -scope Global -name SqlServerMaximumChildItems -Value 0
Set-Variable -scope Global -name SqlServerConnectionTimeout -Value 30
Set-Variable -scope Global -name SqlServerIncludeSystemObjects -Value $false
Set-Variable -scope Global -name SqlServerMaximumTabCompletion -Value 1000

Push-Location
cd $sqlpsPath
$framework=$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())
Set-Alias installutil "$($framework)installutil.exe"
#following needs to be done only once on any machine – the script must be run
#in a Powershell window that has been spawned with admin priviledges

installutil Microsoft.SqlServer.Management.PSSnapins.dll
installutil Microsoft.SqlServer.Management.PSProvider.dll

# Load SqlServerProviderSnapin100
if (!(Get-PSSnapin | ?{$_.name -eq 'SqlServerProviderSnapin100'}))
{
    if(Get-PSSnapin -registered | ?{$_.name -eq 'SqlServerProviderSnapin100'})
    {
       Add-PSSnapin SqlServerProviderSnapin100
       write-host "Loading SqlServerProviderSnapin100 in session"
    }
    else
    {
       write-host "SqlServerProviderSnapin100 is not registered with the system." -Backgroundcolor Red –Foregroundcolor White
       break
    }
}
else
{
  write-host "SqlServerProviderSnapin100 is already loaded"
} 

# Load SqlServerCmdletSnapin100
if (!(Get-PSSnapin | ?{$_.name -eq 'SqlServerCmdletSnapin100'}))
{
    if(Get-PSSnapin -registered | ?{$_.name -eq 'SqlServerCmdletSnapin100'})
    {
       Add-PSSnapin SqlServerCmdletSnapin100
       write-host "Loading SqlServerCmdletSnapin100 in session"
    }
    else
    {
       write-host "SqlServerCmdletSnapin100 is not registered with the system."
       break
    }
}
else
{
  write-host "SqlServerCmdletSnapin100 is already loaded"
}

Pop-Location
write-host 'initializeSqlServerProvider.Ps1 has completed'

Friday, July 29, 2011

Listening better….

From Julian Treasure’s TED talk: 5 ways to listen better:

The acronym RASA to help you become a better listener:

image

Receive: Pay attention to the person talking

Appreciate: Making noises that lets the speaker know that you are listening and receiving their message (oh! ok! yes!)

Summarize: Saying “So….”

Ask: Ask questions afterwards

Thursday, July 28, 2011

Sql scripts: SetVar, :r and spaces in file paths

Had some issues getting a SqlCmd variable working with the :r SqlCmd command.

Here is how I got it working finally:

:setvar databaseScriptFolder "C:\My Folder\"
:r $(databaseScriptFolder)"test script.sql"

Wednesday, July 27, 2011

.Net 4 web-apps not working under IIS7

If your .Net 4 web-apps fail to load, or you do not get .Net 4.0 options for websites under IIS7, then it maybe because your .Net 4.0 installation has been corrupted and it probably just needs to be repaired.

Here is one symptom: Under ISAPI and CGI restrictions for the IIS web-server, Asp.Net v4.0.xxxx does not show up.

image

Here is a simple command to run the repair:

%windir%\Microsoft.NET\Framework64\v4.0.30319\SetupCache\Client\setup.exe /repair /x86 /x64 /ia64 /parameterfolder Client /norestart

It took about 15 minutes to complete on my machine.

And after the repair, all the enteries showed up:

image

Monday, July 25, 2011

Determining which website is running under which W3WP process

Or this post could be named “where is IISApp.Vbs script go in IIS 7?”

If you look at the Windows Task Manager, you may see multiple w3wp.exe processes running:

image

So how do you determine which one is running which website? In IIS 6, one would use the IISApp.vbs script to get that info. In IIS 7, there is a new executable called AppCmd.exe. This file can be typically found under the “c:\windows\system32\inetsrv” folder.

To determine which W3Wp.exe process is hosting which website, simply run the following command: AppCmd list wp

image

Monday, July 18, 2011

Windows 7 Service Pack 1 Installation Problems?

I kept getting an installation error with Windows 7 Service Pack 1 with an error code of: 8024200D.

I tried the Windows Update Readiness Tool multiple times, as well as restarted my computer multiple times. None of that helped.

Finally, I found the download page, from where you can download the entire installation package (http://www.microsoft.com/download/en/details.aspx?id=5842). After downloading the almost 1GB package, I was able to finally get SP1 installed successfully.

The installers based on your platform are (you need to validate that you have a genuine copy of Win7):

windows6.1-KB976932-IA64.exe
windows6.1-KB976932-X64.exe
windows6.1-KB976932-X86.exe

More info: Steps to take to make the SP1 install go smoothly: http://support.microsoft.com/kb/2505743