Time management for programmers

Introduction
—Relics (Star Trek), Commander La Forge and Captain Montgomery Scott Are programmers properly in control of time management? Project managers are likely to disagree with this view. While project managers are likely to use project management tools and draw gantt charts for their projects, the individual programmer is often left to manage the time of their assigned units of work themself. The problem with this approach is obviously that the programmer may not be able to report progress with a measurement but will fill in arbitrary information, which may easily follow cognitive biases or simply confirm the expectations of the project management. This course is meant to help the individual programmer to support the project management in tracking the time required for the implementation of units of work. The planning of whole projects and their work breakdown structure is outside the scope of this course.

Analyzing a unit of work
A unit of work may have different phases depending on the project management and the type of project. The most naive approach of planning your units of work is to estimate programming time and to report this estimate to the project manager. Unless the project manager is aware that your estimate is not including overhead like testing, debugging, documenting and possibly supporting your unit of work your estimate will most probably be as wrong as it can be.

The time requirements for the different units of work and the type of work required may vary from project to project. A good idea is to request the expectations of the project management about type of work and distribution of these types of work at the beginning of the project. Significant differences between the projected use of time and the actual use of time should be recorded in order to compile statistics for future use.

An assigned unit of work can be analyzed individually or can be categorized into a category of typical units of work. This analysis, if not performed by the project management, should allow the programmer to determine the expected overhead: the types of work and their distribution. A specification work unit, for instance, may require more meetings and more documentation but no testing and debugging and an entirely different quality of support. An eager programmer doing specification work, however, may easily overspecify an interface (e.g. interface bloat), thus increasing the work for others programmers, too.

Reporting changing expectations
Feedback is important for the project management. Especially the time required for debugging is difficult to predict and bug tickets your receive may depend on third parties and are thus outside your control. Therefore it is important to monitor your time estimates permanently and to report back to project management when and if you discover changing expectations. Reporting changing expectations can, of course, easily fill a narrow communication channel with signal noise. The best way to communicate back changing expectations should therefore either use a tool that can filter those information depending on the amount of time or at least depending on thresholds specified by the project management: Another day of work may not require reporting but an additional week or two may disturb the project timeline seriously, especially if a programmer is on a critical path.

Testing your time management skills
Think of some simple programming tasks and give estimates for how long it will take you to complete each task; complete the tasks and verify how good your estimates where. If the tasks where simple enough your estimates shouldn't be too far away from the expectations. Now think of a more complex task, like a whole program with several functions, some of them non-trivial and possibly requiring some reading of documentation. Your estimate for completion should be at least 12 hours, otherwise make the program more complex. Now break down the units of work and write down estimates for each independent task, including reading of documentation, implementation of prototypes for each function or for newly acquired knowledge about previously unknown libraries. You will probably notice that the time management is getting more difficult if new knowledge has to be acquired and estimates for previously unknown tasks are required. This is, however, not an uncommon event for a programmer (which is why Scotty is right in a way).

An example project
To test your own ability to estimate the time of work required for a unit of work and the different types of work you can work alone or in a team. A team has the advantage that the interaction will be more realistic. As an example project you can work, for instance, on your own copy of vsrs.sf.net. The advantage is that the resulting software can be used to operate a web site or can be sold as an internet booking engine, just in case you want to make some money, too. Of course you can also work on other projects, like a calculator, an editor or a web browser.

The example project will allow you to create statistics for the estimated time and the actual time of work and the time required for the different types of work. If you work in a team you can verify each others work and file bug tickets in order to create the overhead for reading and writing bug tickets and documenting your work. You can also use project management software to track and to document the overall progress of your example project. Programmers who work on open source software or hobbyist projects often avoid the less interesting (and in these cases irrelevant) overhead of planning use of time. The example project is, of course, the chance to learn to plan use of time.

Preparing knowledge
The first phase of preparing for the project can be to determine what additional knowledge is required and how many persons require specific knowledge.
 * Which books have to be read?
 * Who has to read which books?
 * How fast do people read? Are the books easy to read or hard to read?

Project management may frequently avoid this problem by selecting people who already have the required skills or by sending people to in-service training outside of specific projects. For the individual programmer this can be an interesting measurement that does not directly involve implementation.

Breaking down your units of work
The project management in your example project will probably create some ad hoc assignments (design by committee), meaning your units of work will be crude and underspecified, which is good, because this way you can learn to deal with modifications of the assignments and giving feedback to the project management. One should note that "design by committee" gives committees a bad name, which is, of course, in itself an anti-pattern. A committee is a sensible form of organization, it merely does have a penalty; the trick is to minimize the penalty.

Before you begin to work on your assignments you should break down your work into task lists and categorize units of work and/or tasks. The better your task list is the more precisely you will obviously be able to estimate time requirements and measure your actual progress through this list. An anti-pattern to be avoided during preparation is analysis paralysis, although that should be of minor importance for the individual programmer.

Implementation pitfalls
Not everything that is called a programming anti-pattern is always and everywhere an anti-pattern, but in general it helps to know the most relevant anti-patterns for a given type of task. An understanding for organizational anti-patterns and project management anti-patterns is also useful for the individual programmer in order to avoid problems in a project team.

Just because you didn't cause a problem doesn't mean you shouldn't try to solve it. The categorical imperative could be seen to suggest that this attitude would not be "a maxim whereby you could at the same time will that it became a universal law". As far as time management is concerned some of the anti-patterns to be aware of are gold plating, escalation of commitment, coding by exception, repeating yourself, copy and paste programming, improbability factor, not invented here, premature optimization and tester driven development.

Unit testing
Unit testing is an established standard and should only be avoided if there is a good explanation for not providing a unit test for a specific piece of code or for a feature. Unit testing is usually very costly in development time but worth the effort. Of course the exact details of mandatory unit testing are part of the project guidelines and policies in every serious large-scale project. In your example project a good policy is to test every piece of code that contains non-trivial algorithms and even pieces of code that contain trivial algorithms but can be imagined to malfunction in ways the program will not be able to report as errors. If the unit test is more complicated than the function being tested then that may be a pointless effort. One should be careful also to test for boundary conditions and special cases. Obviously undiscovered software bugs may become more difficult to track once larger subsystems are assembled and the unit tests appear to confirm that these subsystems are functional. A side note on documentation: If you apply the categorical imperative you should write the kind of documentation you would like to receive, which means the Java documentation from Sun Microsystems is a reasonable example.

Debugging, logging and exception handling
Obviously the way the issues of debugging, logging and exception handling are dealt with can affect the time management for a project. Bad debugging, logging and exception handling can increase the time required to trace software bugs and tracing software bugs can, depending on the type of project, be a large part of the whole development time, therefore it is sensible to plan ahead and allow for enough time to debug a software unit and to do that in a way that doesn't waste too much time. There is a large choice of programs and libraries which can be used for these issues and it is worthwhile to know which are useful for what type of work and how logging or debugging facilities should be configured to allow efficient work. A prominent example is the decision for or against checked exceptions or when to use what type of exception, which should be part of the project guidelines and not be left to the individual programmer.

Managing priorities
Different units of work can have different priorities. If the project management provided a schedule with different completion dates for different units of work the priorities will depend on that schedule, of course. Usually that means the more important task is the one which must be completed first. If a task cannot be handed to another programmer that may affect priorities, however. If a task is already difficult to accomplish in the available time frame that may also affect priorities: It may be more important to complete a task in time which has a later completion date but a more critical path for the whole project. Some types of work may have assigned priorities, others may not have priorities or may even have their own priorities (e.g. bug tickets). The individual programmer should be aware of priorities and not take assigned priorities (especially those of bug tickets) as the final decision. Requesting explicit decisions from the project management, again may fill a narrow communication channel with signal noise, therefore the individual programmer should be willing to make priority decisions themself and be able to decide when and where that is appropriate.

Improving time management skills
Besides better planning and more realistic task lists you can improve your time management skills by improving your estimates with a "Scotty factor", which is the factor by which your estimates are usually wrong, which is actually something you can measure and which can be used to improve your estimates. Simply multiply your future estimates silenty with the currently valid factor, but continue updating the "Scotty factor", because your estimates may, of course, improve over time. Another way to improve estimates is to check your expectations for cognitive biases. Do you have biases that affect your estimates? Most people will now and then discover that cognitive biases do affect decisions and views that should be primarly subject to logic. Knowing cognitive biases and consciously countering their effects should be a useful exercise anyway and if you didn't learn that in school it's most probably a good choice to learn it now, which means you should read more or less all the Wikipedia articles concerning cognitive biases, just in case that wasn't already obvious. Planning fallacy and well travelled road effect should be the first articles to read from this list.

One could also argue, for instance, that the belief in Sod's law (or Murphy's law), if one ascribes any meaning to it, is most probably merely brought about by a combination of some of the following cognitive biases: Selective perception, pessimism bias, confirmation bias/experimenter's bias/observer-expectancy effect, contrast effect, anchoring/framing, negativity bias, availability heuristic, availability cascade, base rate fallacy, belief bias, clustering illusion, conjunction fallacy, gambler's fallacy, hindsight bias, illusory correlation, recency effect, Von Restorff effect, self-serving bias. Thus the claim that Sod's law applies could also be seen as the challenge to understand and overcome the cognitive biases that may lead to the perception of Sod's law.