Effective Programming Strategies Postscript and pdf versions are available.

Abstract:

A person's success in programming is dependent, in large part, upon the strategy used. A strategy that involves designing a solution from the top-down and coding the design from the bottom-up while maintaining a short code-compile-test cycle often produces desired results.

Strategy Matters

I remember the first time that I became vaguely aware of the importance of strategy in writing computer programs. I was a fairly accomplished, third year computer science major and was in the computer lab working on an assignment. A couple of second year students were also in the lab working on an assignment. One of the students had just “finished writing” her program and was attempting to compile it! Needless to say, her several page program produced over a hundred compiler errors. This student was accomplished enough that she had anticipated a large number of errors. She proceeded to produced a line-numbered printout of her source code along with the list of errors. She then spread the huge stretch of fan-fold paper, fresh from the printer, out on the floor and took a pen and began to write corrections on the printout. After quite some time of correcting she returned to the computer to enter her corrections. She was elated to discover that the number of compile-time errors had been reduced to less than fifty! After three iterations of the print-correct cycle she had narrowed the errors down to one or two, at which point she abandoned the printing and simply made corrections in the text editor.

At the time I was intrigued by her approach but took note of the fact that my own approach was significantly different. Although I was fairly sure that my approach must be a better one, I wasn't absolutely convinced of that and certainly didn't know how to even describe “my” approach. One thing was certain, though: “my approach” didn't seem to require printing pages and pages of source code in order to eliminate compiler errors.

Since that time “my approach” has evolved somewhat, but it differs only slightly from the time I first learned to program. It is silly, actually, to call it “my approach” because it is the same approach used by virtually every successful programmer. The approach does not require great intelligence or discipline. It is not difficult to employ except insofar as it may require you to unlearn your current strategy.

In many years of teaching hundreds of students with varying abilities I have found that the difference between success and failure in a programming course has much more to do with the strategy employed than with the inherent abilities of the student. I have been on record for also making the claim that the primary determinant of success in a programming class is the student's level of enjoyment of the subject! I believe now, that ultimately, these are two interrelated concepts. If a student employs a successful strategy they will be much more likely to enjoy the subject. If a student enjoys the subject they are more likely to find and exercise a strategy for success.

Steps to Success

Writing a computer program can be a difficult task. Most of us who are called upon to write such programs do not enjoy exaggerated giftedness. For this reason, many of the concepts presented here serve the purpose of taking a complex problem and breaking it down into smaller, manageable pieces.

Step 0: Learn the Tools

A woodworker would never consider using a tool with which they are unfamiliar on a masterpiece in progress. Yet many students will attempt to take a brand new programming concept (or language) and try to apply it to a difficult assignment without first understanding the concept. If you are using a language or language feature with which you are not familiar you should write one or more “dummy” programs that simply test that you understand the syntax and semantics of that feature. In doing so you will almost certainly discover that your understanding was limited. Also, you will produce working code which can be used as a reference when you are using the same language feature to solve a difficult problem.

This step serves to isolate new concepts until they become familiar ... only then do you attempt to use the concept in the context of a larger problem. This is simple enough to understand and to do, but it is often omitted as a step because, to the novice, it appears to be a “waste of time” since the dummy programs may have little to do with the problem actually being solved. If we return to the carpenter analogy, one could argue that the carpenter who tests the new tool on scrap wood is wasting time (and wood) because the same cuts could have been made on the project already in progress. I'm no master carpenter, but I feel confident that any experienced carpenter would agree that practice cuts represent time well spent. That is certainly true in computer programming!

Step 1: Design from the Top, Down

Numerous books have been written on the analysis and design phases of program production. This document is written in terms of relatively small programs produced in an academic environment. Before you start on your program should have designed a solution. Identify the major tasks that need to be performed and list them. For each tasks list sub-tasks and for each sub-task list individual steps. This should be continued until you have at least a vague idea of how to accomplish every aspect of the program. At this step you should draw pictures of any data structures you need to use and have an idea as to how to begin. It is difficult to provide highly specific suggestions for this phase of writing a program without knowing the paradigm being used and the specific problem you are solving. Suffice it to say, if you are unsure how to accomplish this step, seek help from your instructor.

Step 2: Build from the Bottom-Up, Incrementally

The biggest fault in the second year student's approach (from the first section) was that she failed to build her program incrementally. She used a two phase approach: write the entire program and then debug the entire program. For all but the most trivial programs that strategy is poor. Even when the program is eventually convinced to compile the much more pressing (and difficult to resolve) concern of whether or not the program works must be addressed.

When you write code it should start with a simple, bottom-level task. If you are a beginner you should write just a few lines of code before you stop, compile and test. Do not proceed with the program until you are convinced that the few lines of code you've added really work. Then add a few more lines of code. Depending on how thoroughly you completed the previous step you may want to write all code as individual functions or you may want to initially write new code in main and then move that code into a function once you feel comfortable you've found a natural break.

The most important part of this process is the incremental approach! Do not write large sections and then test. Write only a small segment and then test that small segment. It should be noted that if you take this approach you will be writing quite a bit of “extra” code to check the values of variables, etc. Also, it can seem like a waste of time to stop typing and compile and test. That is only true if your goal to is type a lot of source code. If you goal is to produce a working program then the only waste of time is typing in big chunks of code and then trying to debug them.

Some Conclusions

In this document I've claimed that your strategy for writing computer programs will determine your success in that endeavor. I've further claimed that the strategy I've outlined has proved highly successful. Thankfully, that strategy is relatively simple and is very easy to understand. A successful strategy involves learning language features in isolation, planning your solution (top-down), and building your solution (bottom-up) in an incremental fashion.

It may be difficult to employ this approach if you have never seen it demonstrated. If you need help, ask your instructor to demonstrate this approach on a small program.