It seems that, in my experience, getting us engineers to accurately estimate and determine tasks to be completed is like pulling teeth. Rather than just giving a swag estimate of 2-3 weeks or 3-6 months... what is the simplest way to define software schedules so they are not so painful to define? For instance, customer A wants a feature by 02/01/2011. How do you schedule time to implement this feature knowing that other bug fixes may be needed along the way and take up additional engineering time?
If you are cranking out a project nearly identical to other projects you have done, using familiar tools and a familiar team, and you are given firm, written requirements, then it should be possible to make good estimate.
These are the conditions that painters, carpet installers, landscapers, etc., regularly experience. But it is not a good fit for many (or most) software projects.
We're often asked to estimate projects that use new tools, technologies, where requirements are changing,etc. This is more extrapolation into the unknown than interpolation over our past experiences. So it is natural that estimation will be more difficult.
According to my personal experience, it's exactly the opposite of what Pemdas said: with practice, I've just understood that it's totally impossible to estimate how much time a task will require. At the beginning of my career in software development, I often gave estimates like "45 days", "five weeks", etc., then tried very hard to finish in time. A few years after, I started to give less precise estimates like "approx. one month", "five to seven weeks", etc. Actually, I try either to not to give any estimate, or ask the customer to give her own estimate or deadline or I give an estimate as rough as possible.
Why is it so difficult to have an estimate? Because it's nearly impossible to know how the whole source code will be written before actually write it, and because your work depends on random things as other peoples work, your motivation, etc. Here's a more detailed list of the possible reasons:
It's not easy to know what exactly is required to do a product, and especially how to do it. Very often I started some parts of an application, than, after days of work, understood that my first approach was wrong, and that there is a better and smarter way to do things.
Some problems may arise. For example, if, to begin your work, you must install on your machine a fancy SQL server and the installation fails and the support is nonexistent, you may spend weeks solving this issue.
Requirements are often not clear enough, but after reading them at the beginning, you think they are. Sometimes you can understand that the mean 'A', and, after starting to implement them, you would notice that they maybe mean 'B'.
Customers like change their requirements exactly when you've just finished the concerned part, and they really don't understand why are you requesting two more weeks and $2000 to do a tiny change, because they don't see that this tiny change requires to change other things, which require to change others, etc.
You can't estimate your motivation. There are days when you can work for hours and succeed well. There are weeks when, after writing ten lines of code, you switch to Programmers StackExchange, and spend hours reading ans answering questions.
Things become really bad when your estimate depends on other people. For example, in one 2 month project I had to wait for a designer to do his work to finish my own. This designer took 3 months before delivering a piece of unusable crap. Of course the project was late.
Your estimate also depends on your customer. I had customers who spend weeks before answering their mail. It can really affect your schedule when you must wait for their answer (for example if you are asking them to precise a requirement).
What can you do?
Give a larger schedule. If you think you can do the job in two weeks, say you will deliver it in one month.
Be clear. If you rely on a designer, another developer, etc., say it. Instead of telling "I will deliver the product in three months", say "I will deliver the product in two months after the designer will give me PSD files."
Explain that if requirements change every day, the project will hardly be delivered in time.
Slice your schedule. Delivering parts of a large project on time is easier.
Never give an estimate when you use a product you don't know well or, especially, when you will work on a source code of somebody else: you can never predict how crappy the source code can be and how much time you'll spend understanding and copy-pasting it to The Daily WTF.
A very similar question is "How long will it take to solve this crossword puzzle?"
You cannot answer that until you have had a look at it to see numerous things like:
- Is it in a familiar language? (Spanish versus English versus Chinese)
- Is it one of a type we have solved before? (One in a series running in a magazine e.g.)
- Do any of the leads require additional knowledge before we can even understand it?
- Is there anywhere in the puzzle things that, to your knowledge, will require additional work?
Since there are usually several new things in a project (otherwise it would not be a project) you cannot tell how long time they will take to solve until you have had a very careful look at them. Perhaps even solve more or less or them, and then you are still not certain that there isn't a surprise or two where you didn't think of them.
Also there is a strong pressure to do it as cheaply as possible, hence as quickly as possible and the blame for a too low estimate does not go on the project manager pressurizing but the developer giving the estimate. It does not take many iterations for the developer to catch this, and learning to be VERY weary of giving out any absolute numbers.
The most obvious reason why you engineers can't give you accurate estimates is that it's impossible.
Of course you can estimate how much time +-2 minutes it will take from your home to work. You know how to drive a car, you can evaluate the traffic, and some other external factors.
Tell me how much time it will take you to drive from London to Barcelona. Without any advanced GPS planning tools of course. Using the good old method like we still do in software estimation. Empirical estimation and predictions.
In software, it's worse:
- Estimates often become a commitment, so our judgment is modified.
- There can be huge differences between the estimation of Bob and Karl for the same task.
- Uncertainties are very common, how much of us get stuck on a stupid bug or hard drive crash destroying any apparent good estimation.
- We usually forget about all other tasks than programming including meetings, phone calls, helping our coleague, etc.
- Human brain is limited. It has not been designed to estimate long running tasks.
That's why it's impossible to tell your customer what you will be able to ship for the 02/01/2011 with good accuracy, and forget about the 03/01/2011.
- The first two issues are addressed using Planning Poker. Estimations are collective and the team owns them rather than individuals.
- The last third issues are addressed using Velocity and Iterative Development. By knowing your velocity (the factor to apply to your estimations based on history), you can plan releases with more confidence. Iterative development, when well done, bring most important features to the top and helps you deliver value to your users early.
Software development is -- by definition -- an act of discovery and invention. It must always involve something unknown.
The only time everything related to software development is known is when the software is complete.
The only time there's no unknown technology or business feature is when it's a complete, packaged solution ready for download.
The reason we write new software is because we have a new feature or new technology or both. New means new -- unknown -- unpredictable.
Because software development must involve novelty, the development effort cannot be predicted.
Honestly, I think it just takes practice. If you write enough code eventually you should be "fairly" accurate. My first boss believed that this skill was important enough that he requested that I informally practice this on every feature/project that I implemented. After each project we reviewed the estimates and attempted to figure out where I went wrong. Eventually, you get the hang of it.
It's never easy. You just try to get better at it.
One advantage of breaking up your deliverable code into smaller pieces, is so clients get an understanding of what to expect and when to expect it. Now you have some sort of baseline for them to use as a reference.
If they have a strict definition of a feature that they need at a defined time, they need to know that additional resources have to be allocated to this request. They are taking a risk in the severity of the bugs that occur and how long they can go without them being fixed. When something major comes up, you go back to the client and force them into a decision. Do I fix the bug or make the deadline on the new feature? Give them enough information to make an informed decision.
Hopefully you have enough history of working together and have established yourself enough to be trusted. You can't expect them to fully understand the development process, but you can make them feel you are putting forth an honest effort and not taking advantage of their lack of knowledge.
Because we do the schedule too early. See Construx's article on doing a preliminary rough one, then better one later. Also if you don't track how you did on prior estimates, it is hard to get better. FogBugz does that [a customer of their free one, no other conflict of interest].
I have learned a lot from this book:
In short to get better estimation results we do this:
- all but trivial tasks are estimated by more then one person (two in our case)
- we divide task into smaller task. The more tasks you have the more likely your estimation will be good - law of large numbers if I remember correctly from the boo
- we estimate worst, best and most likely scenario. Sometimes each of us estimates those tree scenarios totally differently. That means we have to talk and usually it turns out that one of us did not understand the task. Had that one person estimated the task alone it would be estimated wrong.
- we put 3 numbers from above point into equation and receive estimation (excell) k
After work task is finished and our estimate was wrong we try to find reasons why. And we incorporate this knowledge into next estimation process. So far this is the best process I have used for estimation of bigger tasks. When I say task I mean jobs that take from about 50-500 hours.
Note: This really only applies to projects where you bill by the hour versus a fixed/flat rate.
I usually try to plan out my schedule so that it consists of essentially a bunch of SCRUM Sprints (whether using SCRUM or not). Up front when making the schedule I determine what the length each sprint will be and what the features will be for the project. Typically there are some features that have to be done first so I try to give a best estimate (not to be confused with optimistic) for those and any features that will be towards the end of the project will have generalized estimates. After mapping the features to sprints I try to add 1 to 2 sprints at the tail end of the project to account for features that slide right and for features that were overlooked in the original requirements gathering.
The key to this is that I make all of this transparent to the client upfront so they understand why the last two sprints are empty or sparsely populated. At least to this point the client's I've worked with have liked this since they know that there is some cushion in the schedule/financials since most of them are aware that SW estimates tend to be less than concrete. They are also aware that if we don't need the last sprint or so then those are hours that we don't bill. With the transparency in how the schedule is built and the regular feedback on how progress is going during the execution of the project every client that I've done this with has been extremely satisfied.
In addition to all the things named, I see these two things as some of the biggest problems. First you estimate the final date based on every devloper being available for the full 8 hours a day 5 days a week. This is incorrect and will virtually 100% guarantee that the end date is missed on any project that is not trivial. People take time off, attend company (or non-project-based) meetings , fight with HR over health insurance claims, take breaks, etc. Never assume more than a 6-hour availability per developer per day.
Next devlopers notoriously forget to estimate all the non-development tasks like meetings and emails concerning the project, deployment, QA support, UAT support, writing unit tests, research, documentation etc. Once we added these types of task to our estimation spreadsheet, our estimates got way better.
When it comes to time estimation for tasks which can take longer then a few hours I try my best to use this rules:
- Don't ever try to predict when other people will finish their job if you happen to depend on it. Speak only for yourself.
- First analyse the task, then estimate. By analysing I mean at least writing down (and not trying to keep everything in you head!) a list of subtasks with estimation for each one of them.
- If a task is complex enough, estimate the time for such analysis itself. Let the estimation be a separate process. You may also make sure your boss knows about that.
- Don't estimate under pressure. Make it clear that it takes time to make a reasonable estimation and just tell them something like "I will name a date tomorrow by 11:00 when I'll finish analysing the task". I know some customers/managers can press hard, but they shall not pass. Put your busy face on and claim your time!
- Ask a little more time than you think you'll need because you probably forgot to add a coffee break time (and othe distrctions) in your estimation.
- For big tasks ask even more - there will probably be more than one coffee break.
- If you really can't estimate (the task is too difficult/unfamiliar) or really unsure - ask someone capable for help with your analysis.
There's probably more rules than that, but I actually don't have a poster with this rules on my wall. I just formulated them now, but they come from my experience (so it may not work for you).
The only reliable way to schedule software development I can think of (but I haven't actually tried it) is Evidence Based Scheduling which is basically the Monte Carlo method used to count probability of a ship date based on historical records about tasks that you've accomplished before. It feels nice because it doesn't try to use any metrics other than estimated and actual time. However, it requires a lot of experience to split big tasks into smaller ones beforehand and you have to have a big set of historical data to make it work precise enough.
There are "known unknowns" and "unknown unknowns." :-)
Estimates often become deadlines.
- Nobody want to miss a deadline and become headline!
Requirements change (often rationally) and the programmer cannot veto it.
Programmer do/may not have control on factors such as
- Availability of code she is depedent on
- Quality of code she is dependent on
- Overall architecture and design of the system
- APIs to access other parts of the system