In part 1 of my blogging about teaching miniseries, I talked about the challenges of teaching the intro course. In part 2, I'd like to talk a bit more about content. The fourth goal I have in teaching an intro course, as I mentioned previously, is "making sure that at the end of the class, everyone has some baseline skill in programming a computer". But what, exactly, does that mean? And how do I reconcile that with the fact that my student population is all over the map, in terms of skills and expectations for the course?
The baseline skill I expect out of my students is this: Can you take a nontrivial problem statement and turn this into a functioning computer program that solves the problem? Are you comfortable designing, implementing, and debugging such programs? This is sufficient for all populations: the students that will never take another course know how to write a basic computer program, and the ones that go on will have a base set of skills that they can further refine in the next classes.
Notice that "writing pretty code" or "writing efficient code" is not a baseline skill. Why? Well, the best I can do at this stage is to model, and discuss, "good" programming practices in class, but there's so much other material and so many concepts that the students *must* grasp before the end of the course that I can't focus on this as much as I'd like. The students for whom those two skills really matter are the ones who will go on to take more CS courses--and the next course in the sequence focuses heavily on good, efficient design of programs, so they will see it soon enough. I also find that some students will naturally pick these good design skills up on their own--if they see good models, they will try to mimic them to the extent that they are able.
But that's all at the end of the course. The trickier question is what happens in those first few weeks---how do I accelerate the class from 0 to 60mph in 5 seconds flat? In other words, how do I move from zero knowledge of programming (I start the class by assuming no one has any knowledge about programming, and go from there) to enough knowledge of programming to have the students start writing programs? Because everyone wants to sit down and start programming right away, of course. But in order to write interesting programs, you need to know quite a bit of syntax and some conceptual stuff as well---the interesting programs have loops (repeat this sequence), and conditionals (if X is true, do this series of statements, otherwise do this other series of statements), plus you really need to know something about variables and data storage and math and....the list goes on and on.
I try to take what a colleague calls a "spiral approach". This means that I introduce things somewhat superficially at first, and then as the students gain confidence and conceptual knowledge, I drill down a bit on these same concepts. So the students will see the same concepts repeated throughout the course--first, very briefly; later, in more depth. There are two benefits to this. First, I can introduce concepts a bit more quickly, because I'm not trying to cover everything about the concept right away. Second, there is built-in repetition, which helps the students remember and internalize the concepts.
As an example, I'll have the students do a hands-on exercise on one of the first days of class--they're in the lab, in front of the computer, learning how to use and interact with a program that someone else wrote that allows them to draw stuff on the screen. I give them a few simple directions for using the program, have them try a few scripted examples, and then let them play around. Some of them stick with the simple things--drawing squares of different colors--but some of them will try to figure out how to draw trees, or houses, or smiley faces. Over the next few classes, we start to delve into the program more deeply: how were we able to specify colors, or sizes of the shapes? (variables) how did we scale the shapes? (math) how can we reuse the same set of instructions over and over? (methods or functions, depending on your programming language) And so I use a simple activity both to get them programming right away (by modifying and adding to existing code) and as a springboard for introducing the main concepts of programming, and I refer back to this initial activity throughout the course.
After the third or fourth week of the class, the students have seen most of the main programming concepts, and most of them either have had their "a-ha" moment or will shortly. And this is when I can start getting more specific and introducing more sophisticated concepts. This is when they really start writing their *own* programs, although I'll often still give them some "starter" code for the trickier things.
So that's an overview of how I teach intro courses in my discipline. Of course there are other courses in this category too--courses specifically for non-majors, that are less focused on programming and more on an overview of CS--but the programming-focused courses are the ones I teach more often, and the ones from which we will draw our majors. And there's a lot I haven't touched on--making compelling assignments, for instance. But I hope this gives you at least some idea of what I do in the classroom.
Next up: What happens between intro and graduation? The mid-tier courses.
technorati tag: teaching-carnival