Tuesday, 7 June 2011

Estimation

I'm terrible at estimating development time for software projects. Before I went freelance, I didn't really notice this. I think that's partly because my manager was so good at estimation himself that he was almost able to do the job for me, and partly because he was a nice guy and didn't want to criticise. I guess it's also because I was rarely given entire projects to do on my own from scratch - a lot of the time I was working on a three-day assignment to fix a bug here or improve a feature there.

Since going freelance, I've developed two iPhone apps for clients. The first one took three times as long as I thought it was going to; the second took one and a half times as long. So I suppose I'm getting better… But after the first one went so badly, I'd kind of hoped that I'd be able to solve the problem straight away just by being aware of it: I would put more effort into the planning this time around, and get within a reasonable margin of error. So where did that go wrong?

I've been looking at the notes I made during development, and found out some interesting bits and bobs. The first one's not very relevant, but I thought I'd sling it in because I found it fun. Fred Brooks estimated in The Mythical Man Month that you can expect to produce an average of ten lines of production-standard, fully tested code per day. He was talking about large projects in 1975. Working as a lone developer on a small project with modern tools, I've found the figure is almost exactly a hundred lines. But you can't generalise like this from a single project, so that's enough of that.

I've also identified five reasons, specific to this project, for underestimating the development time. Here they are, in order of how hard they are to fix.
  • The client requested specification changes during the development process.
Aha! So it wasn't my fault after all! Well, in fact they were small changes, and they only made up 15% of the delay. So I'd better keep looking.
  • I didn't budget for talking to client and colleagues, or for making demonstration builds.
An easy win here for the future - these things didn't occur to me when I was drawing up an estimate, so they started eating into the buffer immediately. Although I was responsible for the project, I wasn't the only team member: there were business and graphics considerations, for example, and I needed to explain what I was doing. Since the process was somewhat iterative, it was also important to create demo builds of the app from early on, so that others could offer their input. Each build needed a little testing and a little explanation ('Here's what I changed since the last build'). Next time, I'm going to budget half an hour per day for team discussion and demo builds.
  • The estimate was too closely based on the spec.
The functional spec rightly concentrated on the user's experience, and - as you might expect in an iPhone app - that meant it was centred on a wireframe diagram of the screens the user could navigate between. To make my estimate, I looked at each screen on the diagram and tried to list all the development jobs that lay behind it. That was an incomplete approach, and two big things lost out: the app's data model, and the logic that allowed the app (which was a client for an internet service) to talk to the server. I don't mean I failed to consider them at all; but I hadn't sat down and looked at each of them specifically, breaking them down from end to end in their own right. Another easy win, really - next time, do that.
  • Optimism.
I was eager to please clients who were themselves being optimistic about the amount of work involved. Expectations have a tendency to be high because, as Joel Spolsky has pointed out, 'When you think of writing code without thinking about all the steps you have to take, it always seems like it will take n time, when in reality it will probably take more like 3n time.' Now, I was aware of this risk when I was estimating the first project, and doubly determined to head it off when I was estimating the second, but it's a hard one to get shot of. Practise, I guess.
  • Not enough detail.
I hadn't broken every task up into small enough pieces. Of my five problems, I think this is the hardest to fix. You only have a limited time to make the estimate. How do you find the right level of detail without actually doing the work itself? It's especially difficult when the project involves learning how to do things you haven't done before (which, in software, is always). So next time I do it, I think this still won't be perfect - but I can see pretty clearly that it'll be better than last time. I'll identify the cloudiest bits, use Google and Stack Overflow, even create some rough prototype projects to explore options for third-party code and techniques for handling unusual requirements.