I’ve decide to try some of the techniques Mark Guzdial calls “worked examples and self-explanations” in my introductory programming course.  Some of the benefits he mentions are that the students

  • kept working after the end of class
  • asked significant questions (“What’s the difference between MethodX and MethodY,” “What’s the difference between colours and pixels?”)
  • turned in unusually ambitious first programming assignments (50-200 lines of code)
  • made sense of abstract concepts (“Isn’t a function just a way to name some lines of code?”)
  • reported finding it “surprisingly” enjoyable

Part of this is no doubt attributable to the “media computation” approach that he uses, which seems like a very cool way to introduce people to programming.  Unfortunately I am stuck with a 2-line LCD that has timing issues I haven’t figured out completely, so we’ll be starting with blinking lights.  But there are definitely aspects that I can incorporate, including having students

  • type in examples
  • develop line-by-line explanations for themselves
  • compare examples that differ in small ways
  • compare their explanations to others’
  • plan and execute a change to the program

I decided to make an instruction sheet and “comprehension constructor.”  I’m in Cris Tovani‘s debt as usual — the connections to other reading comprehension work I’ve tried are striking.

 

You’ll notice that the “self-explanation” part has two columns: one titled “Explain in English what this means” and one titled “Why does it have to be here?”

When I’ve tutored for programming courses in the past, I’ve noticed that students often write unhelpful comments such as

index = index + 2;        // Add 2 to index

For a fluent programmer, these are frustrating.  Not only did I waste time reading something I already knew, but now I have to spend time figuring out why that line is there.  My working hypothesis is that a beginning programmer needs that translation, just as a beginning student of Italian may need to translate statements into English before they can begin to interpret them.  When beginners are forced to comment their code, they write what they think, which is a literal translation.  I’m hoping that by making space for that translation (what Tovani calls “holding your thinking”), it will enable students to go to the next step and write something that will continue to be helpful when they stop needing every line to be written in two languages.

I’ve also asked them to document the differences between their code and the code of the person on either side of them.   The example programs differ only in tiny ways — maybe a different pattern of LEDs is turned on, or there is a slight difference in the I/O bit mask.  I was deliberately keeping it simple for the first run through, as we worked through the hiccups.

The next step is for students to summarize the meaning and function of the new ideas we learned (for example, the difference between a “port” and a “register”).  Finally, I ask them to plan a change to the program, tell me what their plan is, and then make it happen (this order of operations is designed to prevent students from making a random change, documenting its effect, and claiming that it was their plan all along).

Since it was our first time trying this, I walked the students through it as if I was a student.  I used an example program (shown in the document above) and annotated it on the board.  There are a few elements I told them they were not responsible for explaining, and I skipped over them.  One was the “void” keyword used as the return type of the main function (I didn’t even want to get into data types, let alone functions, or what the main function would be returning that value to).

I also didn’t explain the infinite while loop in much detail, except to confirm with them that 1 would always equal 1, so the condition would always be true (all the while loop conditions have relational operators such as 5==5, or 6>3, based on my theory that it’s easier for a beginner to see that those are true than to make sense of while(1); or something like that).

We only had time to get about half-way through this exercise in class, and so far the results are promising.  I have very little to compare to, since I haven’t taught this particular course before, but I was encouraged that they were attending to detail, looking for patterns, and making inferences about the system’s requirements and possibilities.  Some of the questions that came up:

  • Does it matter if things are on the same line/how many tabs there are/how many lines between commands?
  • Do you always need the semicolons/stars?
  • Instead of using while(5==5), could I use while(x==5) and make x equal to something and change it?
  • If a pin is set as analog, does that mean it needs an analog input?  What if it’s set as a digital input?  Does it need digital input?