CS 16 Help: Guide to Programming

CS 16, Sem. II 2003-2004


Use the techniques in this Handout. They will help you. Follow this guide, and you are likely to find that programs will take you much less time overall, and the time you do spend will be dedicating to understanding the concepts rather than rewriting and debugging code.

0. Read and Understand The Handout

Read through the handout. Write down any words you don't know. Look them up in the book and the lecture slides, and if you're still not sure, ask the professor or TAs on hours. There is nothing we love more than conceptual questions. We don't put anything superfluous in the handouts, so make sure you know what every sentence is trying to say before you move on to step 1.

1. Draw Diagrams

This you did learn in CS15, so there is no excuse for not doing it; and pictures are fun! Figure out all the classes you will need, and draw a diagram (or two) that shows the relationships of all the classes (containment, inheritance, reference).

2. Write All Algorithms on Paper

The homeworks are specifically designed to reinforce this point. It is much easier to figure out how an algorithm should work while you don't have to worry about compiler errors. Here you can employ whatever method you use for writing homework solutions. We suggest writing down an English version of what happens when a method is called. (Ex. What happens when a user hits P in tetris? Pause(): Check to see if the game is currently paused or unpaused, if paused, turn on all key input, start current piece falling, if unpaused, turn off all key input, stop current piece from falling.) Then rewrite this in pseudocode using good variable names and everything.

2.1. Helper Methods

A quick note about a trick to writing algorithms: helper methods are awesome; do not be afraid to use them. They are good for two reasons. First, they can make your code cleaner/easier to read/easier to debug.
Compare this:

makeDinnerAllInOne() {
    washLettuce();
    cutTomatoes();
    cutOnions();
    cutMushrooms();
    makeDressing();
    defrostChicken();
    boilPasta();
}
makeLunchAllInOne() {
    washLettuce();
    cutTomatoes();
    cutOnions();
    cutMushrooms();
    makeDressing();
    heatSoup();
}


to this:

makeDinnerWithHelpers() {
    makeSalad();
    defrostChicken();
    boilPasta();
}
makeLunchWithHelpers() {
    makeSalad();
    heatSoup();
}
makeSalad {
    washLettuce();
    cutTomatoes();
    cutOnions();
    cutMushrooms();
    makeDressing();
}
The second set of methods does exactly the same job as the first, but the code is cleaner, easier to read, and easier to debug! For example, if your picky roommate comes in and decides she doesn't like mushrooms in her salad, you only have to change code in one place (i.e., makeSalad()) rather than two or more places. This concept is analogous to putting a bunch of constants in one place.

If you're wondering where to use helper methods, here's your clue: If you're writing any code that feels redundant, OR you're writing something that feels like a tangent then feel free to write a helper. (Getting two keys out of two Locators out of Positions and comparing them is sort of tangential to an insert method.)

3. CODE INCREMENTALLY.   No, really, CODE INCREMENTALLY

Now that you have all your methods/algorithms on paper. Go to your computer. Think of the very first thing you want to see happen. (Ex. get insert() to work in your Queue before anything else, then get size() to work, then your iterator()...) The order only matters such that each new thing should be testable before you move on to the next part. Debug each step as you go. Do not move on until the piece you have tackled is fully functional. If you have done the other steps thouroughly, this could be the shortest step in the process. Ideally it will be as simple as creating classes with the appropriate variables and methods from your diagrams, and converting your psuedocode to java to fill them in.

4. Debugging

If you've coded incrementally, and with helper methods, this should be easy. When you have a problem, put printlines in the method you're working on and look at the values of all your variables to make sure they are what you think they are. Printlines are like that best friend who will go spy on everyone and come back and tell you what they said about you: the window to infinite information. If you want to know what's going on, just ask, and they will tell.

4.1 Debugging Helper Methods

One handy trick in debugging is to write a printing helper method. For example, a method called printStatus() may print out all the variables in your program. If you are coding a queue, printStatus() could print out the values in the array, the size, and the front and end pointer. Notes about helper printing methods:

This coding style may take some getting used to, if you try it just once, we guarantee* that it will make life easier!




*Note: not a guarantee**


**Note: yes it is