Our project grew out of our frustration at teaching introductory college courses and observing the poor quality of high school computer science preparation many students had. Indeed, we found that students who had taken high school computer science were often worse off than those who hadn't. Instead of merely complain about this phenomenon, we set out to work with high schools to address it. Over a decade later, ours is one of the most successful high school outreach programs, with adoption at numerous schools and universities across several continents, and over 95% approval ratings for our workshops.
Over the years, we have expanded our vision. We are on a mission to turn Computing and Programming into an indispensable part of the liberal arts curriculum. Computing and Programming teach skills just as fundamental as, and closely related to, essay writing in English and problem solving in mathematics. Below we outline some of the highlights of our approach. To learn more, please look at our materials and consider attending one of our events, including free summer workshops.
Addressing the “Blank Page” Syndrome
One of the most pressing problems that the beginning student of programming (or of any other creative art) encounters is what we call the Blank Page Syndrome: the student, given a problem statement, confronts a blank page...and doesn't know how to begin. Some students attempt to piece together a program by trial-and-error, often unable to offer a rationale beyond “Well, it seems to work...” for what their program really does or why it does that. Equally often, they stare helplessly at the blank sheet and conclude they must not be qualified for this discipline.
We have therefore devised a multi-step design recipe. The recipe begins by asking the student to examine the problem statement and extract information about available data. It then leads them through a sequence of steps, some mechanical and others creative, to obtain an understanding of the program's behavior in stages, starting with its black-box behavior and progressing into its internal structure.
Responding to “My Program Doesn't Work!”
This design recipe is useful not only to write programs but also to diagnose them.
Some teachers have great difficulty helping students whose programs “don't work”; others fire up a debugger. We have observed over the years that often, when a student has an incorrect program, the error is not in the program but in the student's understanding—something the debugger cannot detect or fix. But when the only artifacts the students produce are programs, it is difficult to examine where their misunderstandings lie. The debugger is, therefore, a symptom, not a solution.
Our multi-step recipe offers a diagnostic to determine where a student first went wrong. We often find that, once that stage has been corrected, the student has no difficulty working through the remaining steps to arrive at a correct solution. The recipe also offers a valuable grading rubric because there are more useful artifacts to evaluate. Finally, the sequence of steps make it easy to distinguish the student who understood the problem but made a small error from the one who did not understand the problem but happened to get lucky. The program alone does not reveal this.
Making Graphics, Animation, and Games Educational
Teachers are often caught in a bind between bland-but-educational material and flashy content of questionable value. We have spent several years developing programming language and programming environment support for an algebra of images. This enables students to write programs rich in graphics using just what they know from basic algebra—and to reinforce their knowledge of algebra in the process.
An algebra of images is not enough. We must also capture the processes of animation and reaction, which are necessary to make movies and interactive games. We have invested considerable research into making it possible to do this with nothing more than functions. Teachers who cover both math and computer science courses thus find this combination highly synergistic.
Testing is a valuable—even essential—skill for all programmers. Indeed, it is even a profession in its own right. Yet most computer science courses and curricula pay only perfunctory attention to testing, and are often very sloppy in its application: for instance, a student who writes tests after writing the program misses the point of testing (do you see why?). In contrast, testing is an integral part of our design recipe, and we have been preaching “test-first development” long before it was popularized by industrial practices such as Extreme Programming (though we're certainly glad to be validated by them!).
Every programming textbook introduces a programming language in stages. Likewise, standarized curricula (such as that of the AP Exam) often introduce language subsets. Yet programming environments fail to reflect this gradual process, instead plunging students into complex and confusing languages where programs that should be considered erroneous instead compute (often with unpredictable answers), and vice versa.
We have not only defined—based on several years of careful observation of student errors in labs—a series of pedagogic language subsets, we have also built programming environment support to enforce them, obeying the principle that at every level, the error messages never depend on knowledge that the student does not yet have. The result is a much more gentle and encouraging learning environment. In turn, as students progress through the levels, explicitly upgrading their level in the environment, they have a real sense of accomplishment that cannot be attained simply by turning pages in a book.
We argue that many attempts to improve computer science education have failed because they define courses while ignoring their transitions. For instance, if an introductory course does not clearly articulate how it interfaces with the rest of a curriculum, it is more likely than not to fail over the long term. We have therefore articulated transitions from the beginning to subsequent courses—most notably in the form of a year-long sequence that transitions from teaching languages to object-oriented programming.
Providing a Program of Study
Though we began with the goal of tackling the high school-college interface, we have long since grown our program in both directions. We now have under development or already published materials suitable for upper-level undergraduate and even introductory graduate students in particular areas of computer science. At the other end, we have made our material more accessible to younger high school students, and even have collaborators successfully using it with middle schoolers.