Guidelines for Programming Projects

Programming projects are part of many courses. The primary goals of these projects is to make you more familiar with course material and to improve and expand your programming skills - design, coding, testing, debugging.

Programming Priorities

When you set about to tackle a programming assignment, your priorities in decreasing order of importance should be:
  1. Correctness

    Your code must perform the required operations correctly and handle "anomalous" input and conditions gracefully. A beautifully designed and implemented program that does not work or, worse yet, works incorrectly is, to put it bluntly, a failure. This will become even more critical after you've graduated. While you will probably get partial credit for a non-working program here, your future employer will not be so accommodating. So learn the lesson now - correctness must be your first priority.

    The ranking of the following priorities are somewhat arbitrary and some courses may consider one of these priorities to be more important than another. I offer them in order of my general feeling about their importance.

  2. Comprehensibility

    Your code should be well documented and easy to understand - by you as well as others. This is a prerequisite to maintaining and extending your code. You should give careful thought to the design of your code before you begin implementation (in my experience incomprehensible code often starts off well enough but is badly mangled due to poor initial design). You should identify those parts of your code that are unique or potentially confusing and be careful to document those parts especially well.

    One tactic I use is to begin coding by writing my algorithm as a narrative pseudo-code description. Then I gradually replace the narrative with code to perform the proper task, and turn the narrative into high-level comments. Further comments are added to document code that is anything less than obvious.

  3. Efficiency (aka Performance)

    Your programs should be efficient in their use of time and memory. Some courses (e.g., analysis of algorithms) place greater emphasis on efficiency than others. However, a program that works slowly is obviously superior to a (potentially) fast program that doesn't work. When programming, make it work, then make it work fast. It is quite easy and common to waste significant programming time optimizing portions of programs that have little effect on the overall efficiency. In the words of Dr. Donald Knuth - We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

  4. Reuse and Extensibility

    Programming with extensibility in mind requires you to think ahead to ways that your code might be used or modified in the future. A key principle is to make your code as general-purpose as you can (e.g., a Stack class that can hold objects of any sort is more general than an IntegerStack class that can only hold instances of a particular class).

    Likewise, reuse requires you to factor out those generally-useful structures and algorithms and package them for reuse. But do not be over-aggressive - extract reusable components when you discover something you need to reuse. Overly aggressive decomposition can end up fracturing your code into too many little fragments.

  5. Elegance

    This is a subjective criteria that encompasses the overall beauty of your design. In some ways, elegance is the sum of the other priorities taken together. Elegant programs use and reuse appropriate data structures and algorithms, are well designed and implemented, easy to read, understand, maintain, and extend. Contrary to what you might expect, elegant programs rarely use new or novel techniques unless called for, and program size (e.g., number of commented lines of code) is rarely a good measure of elegance - squeezing code into as few lines as possible can be terribly cryptic and nearly impossible to read, let alone maintain; too much code is also hard to read and maintain, and can perform poorly. Elegance is about finding balance. Speaking of the history of Computer Science, the late Edsgar Dijkstra once said:
    I thought that programmers should not be puzzle-minded, which was one of the criteria on which IBM selected programmers. We would be much better served by clean, systematic minds, with a sense of elegance.
The order given above does not imply that you should first implement a correct program with a given data structure, then rewrite your program with a different data structure to achieve reasonable efficiency! You should keep all of these priorities in mind as you design and implement your programs.

I also recommend that you program incrementally. Begin by developing a minimal set of classes and behavior and incrementally add new capabilities. This gives you a sense of progress and, in the event things don't go well, you still have a partially-functioning solution to a project. However, don't get locked in to an initial implementation if you find that your program is becoming incomprehensible or difficult to extend. There are times to redesign and start again.

See this article on writing "unmaintainable" code for a contrasting approach.

Last modified: , by David M. Hansen