Project planning, a vital part of any non-trivial project, includes estimating and scheduling. There are two obstacle to proper project planning in a student project:
What is the objective of a project plan? By looking at your project plan, one should be able to answer at least the following questions:
Preferably, planning should be done as a collaborative activity. When the plan is built upon team consensus, your plan itself tends to be of better quality and the cooperation from the team in following the plan tends to be higher.
Even if your team wants you, the team leader, to draw up the plan, do not simply allocate work to team members at your descretion. Instead, present them with a draft plan and get their feedback before adopting it.
Any non-trivial student project should be done in iterative fashion. Waterfall may suit certain kinds of projects, for example, when an a team of seasoned programmers build a product they have prior experience in. Most certainly your project does not fall into this category.
“It’ll be done when it’s done!” is not a plan [quoted from:JoelOnSoftware] (neither is it a good attitude to have). 'design 4 weeks, implement next 6 weeks, test during the last 6 weeks' is a plan but it is too high-level (and not a very good one either - for one thing, it follows the waterfall model). So what is the appropriate level of details for our project plan?.
First, there is a limit to how detailed we can be. The element of uncertainty common to all software projects and our own lack of expertise in similar projects prevent us from knowing in advance every detail of how we will do the project.
Second, we may not want to detail out certain things upfront even if we could. For example, we may not want to be specific about which function we will be implementing on Monday of the 11th week from today. Instead, we might stop at specifying which set of features we will be implementing from weeks 8-12 from today.
... my mantra of estimation and planning: estimate size, derive duration [AE&P2006]
Every time we have to decide 'how long will feature foo take?', we must break it into two questions: 'how much effort will it take?', 'how long will it take us to do that amount of work?'. The answer to the first question depends on the task, and the second depends on the person who does it.
If we are following an iterative process (we should) and the product has many features, we have to figure out in which order we will implement them. While many factors influence this decision, two most important ones are the business value and the risk. One strategy is to use the following order [AE&P2006]: first, we implement high risk high value features; then, low risk high value; last, low risk low value, leaving out high risk low value features.
This order emphasizes that "critical" features - those that are difficult to implement (i.e., "high risk") yet vital to the proper functioning of the product (i.e., "high value") should be scheduled early in the project although the client/instructor does not demand it that way. This gives us enough time to recover if something goes wrong while implementing this feature.
Another important factor we must consider is feature dependencies. This analysis might even discover a critical path of features in the project. A critical path is a tightly packed chain of features each one dependent on the previous one. A delay in one feature will cause a delay in final delivery date.
In general, we prefer to define the milestones in the high level plan (we can call this the master plan) using features rather than modules, functions, or tasks. This emphasizes our focus on delivering values to the customer and not merely 'doing some project work'. Here is an outline of such a plan :
iteration 1 [weeks 1-2] : skeleton architecture, feature 1
iteration 2 [weeks 2-3] : feature 2, feature 3
iteration 3 [weeks 3-4] : feature 4
iterations 4-7 [2 months] : features 5,6,7 and 2 additional features from the
'nice to have' list
This plan tells us which features we will deliver at the end of an iteration. After every milestone (i.e., end of an iteration), we plan our next iteration in more details (we can call this the iteration plan). Here, we will break down each feature in that iteration into fine-grain tasks, estimate the effort required, and schedule them appropriately.
Align your iterations (wisely) with the external milestones (i.e., those imposed by the course instructor or the external client). For example, if your iteration ends 1 day before the external milestone, you have a buffer of 1 day to pit against last minute delays.
If we can use a simple table or a spreadsheet to document the project plan and still achieve all the objectives easily, there is no need for fancy templates, diagrams, and charts. See here for a sample project plan, maintained as a simple MSWord document.
A floating deadline (i.e., "let's finish our tasks and email each when we are done") is a sure way to slowdown the project. Estimate how long the iteration will take, and fix a deadline based on the estimates. Deadlines are a way to get a commitment from all, and push the project tasks up the list of priorities ("I have to finish this by Friday, or the team will let me have it!"). Of course if you find yourself finishing the work before the deadline, set a shorter deadline next time.
Start with 1-week iterations. If things go according to the plan, you can think of longer iterations; if they don't, make the iteration even shorter. If you can gather all team members together for a couple of hours, consider starting with a mini-iteration that lasts only a couple of hours.
Once you have found an iteration size that fits you, try to stick to it. Try to schedule milestones on the same day of the week. This helps to "get into a rhythm". This especially make sense since most of your work from other courses also follow a similar pattern.
It is better to estimate size of a task before allocating it to someone. This way, there is less chance of someone padding the estimates for his/her own tasks. We can estimate the task size as a team or as a sub-group of teammates related to the task. Here is a fun way (called the planning poker) to build consensus about the size of a task.
Alternatively (if you don't like fun games that is), you can ask the person who will or likely to do the task for an estimate. Then, others can add their opinion, especially if they think the task is being over/underestimated by a big margin.
"Complete the parser" is a verifiable task. Either the parser is complete, or it is not. "Add more functionality to the parser" is not a verifiable task. Always plan an iteration using verifiable tasks. How else will you decide when the task is done?
Floating tasks are those tasks that are not in the critical path of the project plan. They have flexible timing requirement. E.g., "looking for a good format for the user manual" can be done any time, as long as it's done before starting the user manual.
Identify floating tasks for idle team members (those who have completed their tasks, and waiting for others to finish) to do.
During iteration planning, you will be asked questions such as "how long do you need to do task X?" and "do you think you can finish task Y and Z by Friday?". To answer, you need to estimate the time required for each task. While you may not have a lot of past data/experience to help in estimating, and while you are not usually required to use sophisticated estimation techniques, do resist the temptation to give the first number that pops into your head. Take some time to consider the following factors:
In rare cases when you have absolutely no idea of the size of a task, you may want to try out a similar task at a MUCH smaller scale before venturing an estimate. Such a tryout is called a spike solution. While this delays the planning process by a bit, it is much better than planning based on guestimates.
Unlike industry practitioners, your commitment to the project is not full-time (because you are taking other courses at the same time). This means the number of hours you can dedicate to the project is different from one day to another. Therefore, think in person hours, not person days, when you estimate the duration a task will take.
E.g., If you think a task has a size of 5 hours, and the time you can devote for the project is Monday - 2 hrs, Tuesday - 0 hrs, Wednesday 4 hrs, you should ask for time until the end of Wednesday to finish the task.
What unit do we use to estimate the size of a task? One suggestion is to use "value hours" (not a standard term). That is, the value it adds to the project, measured in terms of typical-person-hours. In golfing terms, this is like the 'par value' of a hole: it's the number of strokes a decent golfer would take to reach that hole.
As a side benefit, you can use the same measurement to calculate the contribution of a teammate towards the project. Just sum up the value hours attached to all the project tasks he/she did. This also means that a weak team member will spend more "clock hours" to earn a given number of value hours than a strong team member, which is only fair.
According to Ed Yourdon's book Death March, one reason for project failure is
the naive "we can do it over the weekend" optimism of the youth. An
overconfident programmer (in our case, a student) might think he/she can develop
any system over a weekend, and things such as documentation,
error-handling, and testing are so "minor" that do not need much
time.
We should keep accurate measures of the time we spend on each task, compare it with our initial estimates, and adjust our future estimates accordingly. Do not be surprised if you found your estimates were less than half of the actual time you took.
Let's face it: estimates can never be 100% accurate. Larger the task is, less precise the estimate will be. First, break larger tasks into smaller ones. Second, do not give seemingly precise values to largely uncertain estimates. Using scales such as 1,2,3,5,8 (Fibonacci series) or 1,2,4,8 reflects that when the task is bigger, our estimates are less precise[adapted from AE&P2006]. For example, using the first scale means when a task is bigger than 5 hours, we put it into the 8 hours bucket instead of choosing between 6, 7, and 8 hours.
Things like unit testing, adding comments, and routine refactorings are usually considered integral parts of coding and therefore, should not be shown as separate activities in the project plan. However, it is better for student teams to include them as separate activities [adapted from AE&P2006] , at least until they become a habit. This practice will help us to consciously allocate time for these important activities which may be overlooked otherwise. Also remember to allocate time for fixing bugs (found in features delivered in previous iterations) and meetings.
However, we should not include things that do not add value to the project (e.g., answering emails).
Having fixed times set aside for meetings (e.g., Monday 12-2pm) from the beginning of the project avoids the hassle of trying to find common time slots for each individual meeting. No team member can claim to be busy during such pre-allocated meeting times; it is his/her responsibility to keep that time slot free.
Do not forget to include meeting times in the project plan, and in
contribution calculations.
Each iteration should start by drawing up a detailed plan for that particular iteration. For increased visibility, you can send a copy of the plan to the supervisor at this stage itself.
You can also maintain the project plan as a GoogleDoc (or some other online format), and give access to the supervisor. In this case, it is easy for the team members to update the doc as and when required. For example, a team member can mark a task as "done", as soon as it is done. GoogleDocs also keep track of the past versions of the document, and show who did which change. You can also consider more specialized project tracking tools.
Some teams allocate one member to "do the project plan". This member creates a nice project plan and submits it, while others never get to see it, let alone follow it. Instead, each team member should have an intimate knowledge of the project plan, at least the part that applies to him/her. One should always be able to answer the following question: "According to the project plan, what should you be doing today?"
It is not enough to know the plan, you should also try to follow the plan.
At the same time, track the time you spend on tasks assigned to you. Rather than wait to estimate the time you spent on a task from memory (if we are good at estimating, we would not have to go to all these trouble anyway), use some technique (such as an online calendar or a time tracking tool) to record as you do the task the actual time you spend on it.
Planning is not over until the project is over. "Revise plan" should appear frequently in the project plan. It is also advisable to put someone in charge of this aspect.
Do a post-mortem analysis at the end of an iteration. What did not go according to the plan, and why? Change the master plan as necessary.
When what you actually did does not match with the plan, it means the plan needs adjusting. But remember, you should not adjust the past plan to match what you did up to now, but you should adjust the future part of the plan to match what you now think you can do (as opposed to what you originally thought).
Do not assume that everything will go according to the plan. Insert buffers to strategic locations of the task chain. If task B depends on the completion of task A, try not to schedule task A immediately before task B. Scheduling task A little earlier creates a buffer between A and B. That way, a delay in A is less likely to affect B.
Note that buffers should be explicitly shown in the plan. Inflating all estimates by 10% is not as same as adding buffers.
Consider the following true story: A team claims to have implemented all the features of
the product, but did not have enough time to hook up the functionality with the GUI,
and therefore, had no way of demonstrating the product. They offer to take the
evaluator
through the code to prove their claims, an offer the evaluator politely declines. The team
receives a very low grade, although they supposedly fell only a small step short
of the complete product. They could have got a much higher grade if they omitted
some features and used that time to hook up the remaining features to the GUI.
Moral of the story: When short of time, you have to sacrifice some features so
that at least some features survive. If you realize that you are not going to make the deadline, and if late
submissions are disallowed or heavily penalized (they should be!), you should
not carry on with the current plan as if nothing is wrong. Choose wisely what
you will include in the product, and what you will have to omit. Do not blindly
reallocate time from one task/feature to another (e.g., from documentation to
coding) - the decision should depend on the amount of credit you stand to gain
from each. Do not skimp on testing no matter what - it is better to have 90% of
the features 100% tested (i.e., a good product that lacks some features) than
100% of the features 90% tested (i.e., a lousy product. period).
Similarly, when you cannot make the iteration deadline (an internal deadline set by the team), drop features rather than extend the deadline. Changing deadlines disrupt the rhythm of your team.
The reality is that a typical student project can get by without much elaborate planning. Most students use ad hoc "back of the napkin" "inside your head" planning. However, a project course intends to teach you good project planning. That's why sincere project planning is usually given extra credit.
It is also helpful (in achieving fairness of grading and as an incentive for teammates to pull their weight) if you keep track of the contribution made by each teammate.
Note that it is more fair if we use value hours to calculate the contribution rather than clock hours someone spent on a task. For each task, estimate the effort in terms of value hours. At the end of the iteration, record the actual effort (using value hours), which could be different from the previously estimated effort (if a task turned out to be genuinely easier/tougher than expected).
Do not count partially completed tasks. A task/feature is done, or not done.
The actual effort can then be used to calculate the contribution from each member. Here's a sample calculation.
| Name | Task | Estimated effort (hrs) | Actual effort (hrs) | Total | % |
| Jean | implement foo() | 5 | 5 | 12 | 60% |
| implement bar() | 5 | 7 | |||
| Farouk | find a testing tool | 5 | 8 | 8 | 40% |
| implement goo() | 5 | - (postponed) |
Note that Jean took more than 5 hours to implement foo() because she is new to C#. However, we only count it as 5 hours, since that is time it should have taken.
Any suggestions to improve this book? Any tips you would like to add? Any aspect of your project not covered by the book? Anything in the book that you don't agree with? Noticed any errors/omissions? Please use the link below to provide feedback, or send an email to damith[at]comp.nus.edu.sg
![]() |
---| This page is a part of the online book Tips to Succeed in Software Engineering Student Projects V1.9, Jan 2009, Copyrights: Damith C. Rajapakse |---