Top Six Estimating Tips for Programmers

Every programmer struggles with providing estimates. It is a universal truth of software development. Most of the time we go way too deep, try to be more precise than we have any reason to be. Many times we have fear driving our estimates – what if they are too big (will they cancel the project? or will they assign the work to someone else?) or worse, what if they are too small (will they fire me because I appear incompetent?).

Here are my top six tips for solving estimation challenges in software development projects:

1) Keep tasks independent – break the dependency chain.

Sometimes it is hard to make tasks independent. If you are struggling to break down tasks try working the chain of dependency from the other end. If you started with the database, and were working your way to the user experience – maybe stop and work backwards from the user experience and see if that works.

 Sometimes that means that replacing one structure with another cannot be done as a single action. Sometimes you have to build the new structure, then point the consumers at it, then you can delete the old structure.

 Also, sometimes it is necessary to use “shims”. Small hard coded, temporary elements which let you work on one side of a connector, in isolation. Then work on the other side as a separate task – without breaking the build.

 Example: I need to deprecate a property of a domain model class, and re-engineer business logic to depend on a different property which is net new to the model. I can work with provider/consumer pairs of classes, to add the new property to the provider as a shim , with logic based on the deprecated property. Then I can remove the dependency on the deprecated property within the consumer class. Then I can remove the shim by completing the implementation of the new property and deleting the old.

2) Division to discomfort.

 If you’re task is unfamiliar and you are struggling… start with a ridiculously large estimate like 10 days. It must be obvious that that estimate is too big. Really stinking obvious. Keep dividing in half until you are uncomfortable with that estimate. Then take half of what’s left and add it back.

 Example: I know for sure that I can add that subclass in 10 days. (/2) I know I can do it in 5 days. (/2) I am not sure I can finish in 2.5 days – (+.5) So my estimate is 3.75 days.

 Code abstraction of algorithm:

Function Estimate(Decimal approximate) {

    if developer_is_uncomfortable_with(approximate) return (approximate * 1.5)
    else return (Estimate(approximate/2)

}

3) Infer from other estimate.

 If you have already estimated something similar, or of similar complexity, then that is a reference point. However sometimes, you can say this is some factor of complexity or scope from something you did. This is useful at a personal level, but less useful at a team level.

 Example: The similar thing I did took a day and a half, this one is about twice as complex, so I would estimate 3 days…

4) Estimate unknowns as tasks.

 When you have design or implementation options that depend on information you don’t have, or on decisions that aren’t made. Turn the analysis or decision into an “unknown” task. If that means that the optional work is non-determinate – then leave your estimate at a summary level, choose the largest option, and add the unknown tasks and that is your estimate – albeit not fully elaborated. Sometimes people refer to this as estimating plan a and plan b.

Example: I am using an enumeration type. I need to create a list of the enumerated values to display. I don’t know if the language has support for that (plan a) or if I will have to use a different type to simulate the enumeration (plan b). My tasks are: 1) Try to use the enumeration (unknown) estimate how long it will take if this works. 2) Replace the enumeration, estimate how long to work around the fact that task 1 failed. If the enumeration works, then I cancel task 2, and gain that time back on the plan.

5) Provide a confidence factor.

 Sometimes, you just feel uncertain. You may not be able to put your finger on it yet, but you feel that your estimate is not on solid ground. What percent of the work is solid, what percent is squishy? 30% solid? 70% solid? – divide your estimate by the percentage – to allow for confidence. I know that “real project managers” and statistics geeks will tell you that this algorithm is too simple. That you should use some other probabilistic method. Problem is that most programmers don’t understand statistics or probabilities and the explanation will make them roll their eyes back into their head. This is about helping developers not project managers.

The fact is This is especially useful when working on legacy code. Remember that any code that you, yourself didn’t write in the current iteration is legacy.

 Example: I have to extend the portfolio class to expose aggregate value summaries based on an arbitrary collection of categories (assuming that the categories are unique value attributes of each portfolio item). I know how to do the work but am unfamiliar with the structure of the portfolio class. I have to account for the fact that I may have to adjust existing properties or methods in the class to support the extension. I think this work might take half as long as the work I know. The ratio of known to the whole is my confidence in this case 66%. If my estimate for the known work is 2 days, add the unknown estimate 1 day, I say 3 days divided by .66 confidence = 4.5 days.

6) Template the estimate.

 Sometimes the task involves a number of similar touches to a collection of components. Its hard to estimate until you know the number of touches that need to be done, but it might be easy to get the approximate effort per touch. You can get creative, by saying some of the touch points are more or less complex than others, and estimate big and little touches – in ratio – but what you are really doing is estimating the mean effort to complete the touches and letting big and little offset each other.

 If the number of touches creates an estimate that is larger than your task size threshold you can combine this tip with tip #1 to divide the task into iteration sized chunks, or across multiple team members.

 Example: I have to change the signature of a widely used method (more than 20 classes call this method). I estimate that each call will take 30 minutes on average to complete including any unit test adjustments. I then perform an accurate count of the calls and calculate the sum of effort. So my estimate looks like # of calls (23) * template estimate (.5 hours) = 11.5 hours.

No Comments

Post a Comment