CS 1101: When to Think While Programming

If you still feel overwhelmed by the process of programming, perhaps you are thinking too much, or not realizing when you should need to think while programming. Let's look at the programming process and gauge how much thinking (versus rote activity) should go into each step. If you feel you need to think a lot in a step that we label as low thinking, then you're not using the design recipe as much as possible. Practice the low-thinking parts until they become automatic. Then you can save your thinking for where you should need it.

Step 1: Data Definition (Data Analysis and Design)

Thinking Level: High

In this step, you are looking at the information you want to write programs about and trying to decide how to organize it into data. You have to ask yourself questions such as "can I use built-in data (like numbers or strings)?", "do I need to define structures to glue related data together?", or "do I need a list because the number of data items isn't fixed"? Data analysis is one of the thinking-intensive parts of program design. It's also one that carries over into lots of other domains (you need to be able to organize information even if you never program again), so it's worth learning how to do well.

Once you decide what data you need, writing the actual definitions is much easier. All structs have the same shape. Keep an example of our common data definitions handy and just copy from the general pattern.

Writing examples of data is a low-thinking activity. Just read off your data definition to write down data with the right shape.

Step 2: Template

Thinking Level: Low

In this step, you are writing a skeleton of program that you can reuse on programs that process a given kind of data. Once you learn the basic rules of building templates, this step should take almost no thinking (because there are easy rules to follow). Specifically, the rules are:

• If the data has different cases, write a cond with questions to distinguish the cases.
• If the data has pieces (like a struct or list), pull out the pieces (this may happen inside the answer part of a cond if your data could be one of several structs).
• If there are arrows in the data definition (references to other data that you defined), send the corresponding piece of data to its template (ie, call the same function on the rest of a list).

Note that there is almost no thinking here beyond remembering the rules. Bring the rules to classes/lab/exams on a piece of paper to make this easier.

Step 3: Contract and Purpose

Thinking Level: Low-Medium

If I gave you the problem, this requires very little thinking because you just write down the name of the function and what kinds of data it consumes and produces. The purpose is largely given to you in the assignment. Thinking rises to medium if you are writing the function for yourself. For class purposes, this should almost always be low.

Step 4: Test Cases

Thinking Level: Medium

Writing test cases forces you to understand the program you want to write, but NOT how to write it (hence this is only a medium-thinking step). Forget how the program will work and focus on what answer it should produce. The format of test cases just follows the contract.

Step 5: Fill in the Template (the function body)

Thinking Level: Medium-High

Now you have some work to do, because there are no simple rules to follow to fill in templates. Remember that the template does a lot of the work for you though! Ask yourself what each piece of the template computes, then all you have to think about is how to combine the pieces. Maybe you want a helper function to do this, or maybe it's something simple to write without a helper. Either way, figuring out how to combine template pieces requires some thought.

Your test cases are an excellent guide to this step. If all of the expected answers in the test cases have the same shape, or some piece of data in common, you can copy that part verbatim into your answer. The places where the test cases differ indicate where you need to compute some information from the inputs. Learn to spot the differences in answers and filling in the functions gets much easier.

Step 6: Run Your Test Cases on the Code

Thinking Level: Low

If you wrote your tests properly, this is trivial. Thinking only comes up if one of the tests produces a different answer than what you expected. In that case, you are really back to step 5.

Watch yourself as you program, and see if you put too much thinking effort into some of the steps (and make sure you are following the steps in the first place)! The steps are designed to be independent -- you shouldn't need to consider anything other than the step you are currently doing. If you are, you're making this much harder for yourself than is necessary.