On Software Project Estimation

Estimating a software project’s effort is a pebble in my shoe. Gladly, the same problem haunts all software developers. Somehow, we tend to be extremely optimistic before starting a project, and as the clock ticks, we get more and more realistic, and see the light at the end of the tunnel move much farther away, almost to infinity.

Here’s my take on it.

WARNING: The views expressed here are solely my opinion, based on personal experience and observations.

Software as Civil Engineering

I have heard software developers describing a feature to higher-ups by comparing it with building a house. That type of comparison for me is totally bogus. Here’s why:

Software developers never built a house. Ever.

I mean themselves, by hand. Ok, maybe some of us have, or finished a basement. But even when drawing that comparison they’ll have the mental schema of bricklaying. If you have ever seen a house being built, it takes hundreds of different trades, and skills, all at different times in the house-building process.

A civil construction (a building for the uninformed) is a tangible thing (you can touch it).

Building some concrete takes time to put it together, takes time to replicate it, takes time to clean it, and takes time to tear it down. Building software is merely giving instructions to a machine on how to do things. By how to do things, I mean telling a computer how to transform a file (or a set of them) into another file. If you want to be specific, how to transform a long sequence of 0s (zeroes) and 1s (ones) into another sequence.

A consequence is that to “build” software it becomes as simple as pressing a button and watching the computer do its job. And if you’re curious, to replicate, to clean or to tear it down, it’s also a matter of pressing another button. Ok, maybe calling “make clean” if you wanna geek-it-out.

If you still don’t follow or agree with me, here’s an example:

Imagine you’re building a software “house”. You don’t create each window by hand (technically you can, but it defeats the purpose of using a computer). Instead you define a model of a window, that is going to respond properly to you as you interact with it. Then you instantiate your window. You define things such as the size, number of panels, etc. Now, you have to make sure the window interfaces properly with the rest of the software. Now imagine that you want to change the colour of the window. In real life, you grab a pail of paint and you paint it. Don’t like the colour? You gotta wait until the previous paint dries, remove the old paint, and apply the new colour. In software? Well, if your window doesn’t define a way to specify a colour, you add support for that: If your abstraction model doesn’t define colour, well, you create the colour abstraction. You write this in some file (or files), and add these to your project. Then you build your software, and watch it render your window in the colour you specified.

Now, you can place windows everywhere you want in your software by re-using the same code you wrote for one class of windows. In a real house, you have to buy (or build) a new window each time you want to see through a wall.

Debugging a building? Don’t try this at home.

In your real-life window, if you don’t see through your window properly, you’ve gotta clean it, or turn on a light, or draw the blinds, etc. All that’s built-in for your. It’s physics.

Your software window doesn’t show through? Maybe you forgot to add another abstraction (or illusion) of what it was supposed to show. Or it’s interacting with other abstractions in a way you didn’t foresee. Or it’s not interacting with the hardware (the physical part of a computer) it’s not prepared to deal with. Or the other abstractions written by other people don’t interact with your window the way they’re supposed to. The list goes on. What’s worse? It’s very rarely the computer’s fault. It’s either your fault, or other person’s fault. The people that programmed those features didn’t do them the way were supposed to, or didn’t think of certain possibilities, or had another cascade of problems that led them to do things the way they did.

And just like in real-life (tangible, touchable life), when you fix something, you can break another. A short intro into the so-called art of testing.

Testing in real-life requires a person (or a number of them), to physically interact with each instance of an object (thing) to verify it behaves properly. In artificial life, you write even more lines of code that creates (or instantiates) objects. Then you write more lines to push buttons in these objects and see if they behave properly. You check the result by looking at strings of ones and zeroes. Or better yet, tell the machine to find certain patterns in the strings of ones and zeroes.

Finally, where am I going with this?

Once something physical is built, changing/replicating/updating it takes some considerable amount of time and resources. It’s easy to see and understand why.

Once a piece of software is written,

Replicating it is a matter of copying it. It’s like photocopying a document, except that it’s an exact replica of the original. You cannot tell the original and copy apart. The number of copies just depends on the amount of available hard drive space.

Changing or Updating it is a matter of editing a handful of files. Then you build it again. Let the computer crunch (transform the string of bits into another string of bits).

I’m sure a number of you will disagree with me here. I can hear the “It’s not quite that simple”. Actually, it is. If in your case it isn’t, you’re doing it wrong. You’re placing yourself in the middle of a process where a machine is perfectly capable of handling. If you don’t trust the machine to do something for you, that’s a different story.

So if building software is so much faster than building real things, how come we’re always wrong about the time it takes?

Because when we’re building real things, you are in direct contact with them. In software you are at least one level of abstraction away from the thing. You are defining a very specific set of instructions on how to build something. You are not grabbing a hammer and hitting on a nail. Rather you are telling a machine to grab a hammer, and nail, and giving it instructions on how to push the nail in. As an exercise for all the skeptics, try writing a system to do just that.

Now, try to imagine the effort required to tell a computer how to do all the hundreds of different tasks required to finish anything. The optimistic will say it’s not that much. The pessimistic will say it’ll take forever and a little more. The optimistic will be late. The pessimistic won’t even start.

We have been living in dwellings for as long as we can remember, so we had a lot of time to perfect the art of building them safe, sound and in time. Though, I hear in civil engineering and architecture, projects often end up late. If creating software is the equivalent to a meta process for building houses, for example, no wonder all projects are always running late.

Under the hood

Another comparison I hear often is to compare a code change (e.g. required by a new feature) with working on one’s car engine. Once the developer is in the middle of something, he will try to explain to his manager that nothing is building because the engine is out, and all the tubes, pipes, wires are disconnected, etc. The guts (pun intended). The manager gets it, because she has seen her car like that, and she knows she can’t go anywhere if the engine is not able to start. That’s a fallacy. It’s so obvious it’s hard to explain.

How do we estimate tasks?

It’s all guess work. No matter how we sugar coat it, and how many project management books on software engineering we have read, or fancy tools, it’s all guess work. The truth is that we don’t know how long it will take to build some software because we haven’t built it yet. As a matter of fact, the last sentence should read as follows.

“The truth is that we don’t know how long it will take to write a piece of software because we haven’t written it yet.”

If you want to know exactly how long it takes to write anything, you have to write it. Then it becomes paradoxical, because once you have written it, the estimate is no longer necessary.

Since we don’t have all the time in the world, we try to short-circuit that process by guessing. We estimate the effort of a task by basing it on other similar tasks we have done in the past. These are some of the factors that influence our guess work.

Requirements (or how we interpret them)

If we could transmit our exact thoughts from one human to another, we wouldn’t need requirements documents. So in a project that involves many different people, that thought synchronization is vital, but it only happens with experimentation. We build something, show it, and let the user try it. If what we wrote is what the user wanted or better, all is good. Otherwise, we have to “synchronize” requirements again, rinse and repeat.

The APIs and tools we rely on

Marketing does a great job of promoting how easy it is create software with a particular software library. The complexity of any software we write today has been greatly reduced by being able to re-use someone’s work through a software library. However, it doesn’t always behave as expected (or understood), and we tend to spend time learning the ins and outs of the diverse components and tools we use in our trade.

Mood

Ask any developer to estimate how long is something going to take when he’s on a roll. If he’s having a great day, squatting bugs, getting everything done perfectly and feeling great, he’ll underestimate the effort. Ask him again when he’s having one of those days that he couldn’t submit a single line of code because everything has been failing on him, and he may not even give you the time of day.

Unconsciously relying on our real-life schemas

When we think about features we wrote in the past, that are similar to what we’re trying to write now, we tend to remember only the time spent coding. By coding, I mean the time we spent typing the code. That’s a real tangible measurement of time. We were in front of a machine, typing. It’s easy to measure. Try to measure the amount of time you spend thinking about something, or finding a solution, and you’ll realize it’s a number of times more complicated, and you won’t remember it so easily. That’s because the amount of time spent typing code is what we find like brick layering. You’re placing one brick (compilable token) at a time, aligning it, making sure it’s the right one, etc. The estimate however, should be on all the effort taken to get to that point, plus the typing time, plus a margin for error.

As we’ve stablished before, that’s not a good comparison, hence the optimistic estimates.

The due date

We tend to think backwards from our goal. This is perfectly rational. We are given a goal, and an end-date. It’s natural to think that we are going to try to fit all the features we can in that amount of time. We don’t know how long it’s going to take to write it, because we haven’t written it yet. But we are usually optimistic we can do it in that amount of time. We are also afraid the task, which we really want to do, may be given to someone else, which will accept it for the same or less time and money.

Technology and its pace

The pace at which software and technology is currently evolving is remarkable. The common person has been living with software in our day-to-day lives for about 20 to 25 years. Software has come a long way in this time, and it seems that it has only scratched the surface of what’s possible to do with it. Software professionals have to keep up with this pace to remain competitive, and that means constantly staying to on the lookout for how to do things more efficiently, learn new technologies, and more.

However, users are not always at the latest and greatest, so software has to be written to accommodate shortcomings from the past and the future, different types of users, different legislation, and the list goes on forever. If we try to predict all these factors while estimating a software project, we run into another paradox: You can’t provide something for a user to try because you don’t have it yet. The user can’t tell you exactly what they think or want because they haven’t seen it yet.

Interrupts

We never take into account all the time required to perform other small tasks during a project’s lifetime. We help other people, answer questions, ask questions, provide builds, participate in meetings, read and write documentation, and a million other small things that eat up time. At the end of a year-long project, these seemingly small events amount to a sizeable amount of time. The problem is that every time an interruption occurs, getting back to the frame of mind we were requires some ramp-up time. That time is never taken into account (and it’s not easy to do so). That must be why many of us are night owls, when no one else is around.

Research (or lack thereof)

Often times we think something is straightforward to do, only to realize later that we need to research how to do it. Sometimes, that is a key part of the software we’re developing, but the entire project has to be put on hold, since a key assumption wasn’t valid: We didn’t know how to do something. That can throw a project’s estimate out to about infinite effort, if the problem is impossible to solve.

The Leader’s Lair

The premise

If you live in Canada, you’ve probably seen a TV show called Dragon’s Den. For those of you who never heard of it, it’s a show where a panel of 5 investors listen to business ideas from people seeking capital to take their idea or business to the next level. The format is very straightforward: Candidates ask for a certain amount of money in exchange for a percentage of their business. These candidates would use the cash to grow the business, so both them and the investors share the risks and the profits.

As part of the Ottawa Startup community, I think it would be awesome if we had a “Dragon’s Den with Human Capital” show. I call it Leader’s Lair. We have lots of technology talent in this city (including myself), and many of us are trying to start our own thing. However, it’s hard to move a mountain by oneself, and many times, one just needs a hand, not employees.

The Pitch

Create a web-based show (Leader’s Lair) with a similar format to Dragon’s Den, where, instead of money, the currency is Human Capital!

Let me explain: Money can buy things and pay for people’s time. That’s wonderful. However, I find (and I’m sure many of you do without even realizing it) that to get where you want to be, you need another type of capital: Human Capital.

Human Capital can give you feedback, connect you to the right people, show you the ropes, and most importantly, care.

Most Leaders I have met through the Startup Ottawa community want to share their experiences. So much that they take the reigns of our very own “Ottawa Start-up Community” and keep it alive and kicking. It’s a lot of work, for really no compensation. It’s fantastic! They do it because they care. Unfortunately these people become really busy and sought after. Naturally, the amount of feedback, connecting, showing, and caring towards any of us tends to zero rapidly.

We can bridge this gap and have fun doing it. How? Read on.

Leader’s Lair, the show

An innovator presents her business idea, and offers a part of her start-up business in exchange for a Leader’s expertise, in front of a panel of 5 Leaders. Examples:

  • I need Business expertise – Where is the money in my idea?
  • I need Marketing expertise – How to make my idea appealing?
  • I need Sales expertise – How to price and sell my product or service?
  • I need Execution expertise – What do I need to make this idea happen?

Discussions between Leaders and the innovator is encouraged. If a Leader finds the idea is interesting, he can offer his expertise as a commitment (e.g. half a day of his marketing expertise every two months), and negotiate the terms (e.g. for 5% of the profits for the first year). If the idea is of no interest to him, the Leader should explain why to the innovator.

The commitment from a Leader to an innovator keeps the communication channel open (helping her succeed with expert advice). And the promise of something in return from an innovator to a Leader is an added incentive for him to care, which leads both to success!

Call to Action

The concept is pretty simple. A couple of cameras, a panel of committed Leaders, movie editing software, an internet connection, a handful of wannabe innovators, perhaps even a volunteer M.C., and we have a YouTube show worth watching.

Are you in?