I've been tutoring this fellow on problem-solving with C++, and I have to say that teaching is very fun. It's a chance to see understanding and to provide it the way you felt it. (It's also a chance to show off, but no one need know that.)
The assignments he brings in are very simple things, but I can tell his professor has left him woefully unprepared. None of the programming classes I've taken have been put together very thoughtfully or consistently, and this lack of rigor seems to be characteristic of computer science classes. Compare this to a well-taught mathematics course: math builds upon math, so the material builds upon itself and progresses logically from concept to concept. Vector spaces progress so:
- Define "vector" and "vector space"
- List the ten axioms for a vector space
- Define the span of a vector and sets of vectors
- Define linear independence of sets of vectors
- Define basis using spanning subsets
- Define inner product spaces of vectors
- Define length of a vector, angle between vectors, and orthogonal projections of vectors using inner product spaces
- Define orthonormal basis using orthogonality, length, and span
- Define coordinate mapping using orthonormal basis and orthogonal projection (or inner product)
- And we haven't covered any more than that.
Programming courses are a chaotic jumble of discrete math, syntax, and some actual concepts. I really have to lower the bar; for I overestimated the progress the course had made. The exercises don't seem to impart any real understanding; they're completely out of sync with what he knows how to do. As an example, one of them calls for a function to swap two integers using references. Any novice programmer could write that in a heartbeat:
void swap(int &a; int &b)
{
int c=a;
a=b;
b=c;
}
Yet he is still hung up on the syntax. And the very idea of a parameter list gives him trouble. It's not his fault, of course, for we aren't born knowing this crazy syntax someone dreamed up, but shouldn't they be doing exercises recognizing and writing these fundamental things? It's like giving ART-100 students perspective exercises the first day of class, and then adding the extra burden of doing it with pastels. He doesn't understand what's going on and is starting to learn blocks of code by rote, kind of like me as a little kid learning how to program. That's inefficient, and I just wound up learning it the right way in the end.
We're making some progress, though. One of these days he'll finally remember how to call a function, and, with any luck, he'll understand what it is. In the meantime I'm scratching around for a good definition of these things, and I'm ultra-pedantic on the different parts of the code. One has to be clear about all these different parts of code lest they run together in the mind. I'm also thinking up good exercises that will force him into understanding, kinda like the Socratic method.
How about this: I wrote an function to compute a div b. ("div" is the integer division operator: 5 div 4 is 1. 10 div 3 is 2. Kinda like rounding down.) When will this function fuck up?
int div(int a, int b)
{
int i=0;
while(a > b) {
a = a - b;
++i;
}
return i;
}
So then he could write a small program to test this function out (he knows how to write a 'main' function pretty well) by calling with different values. This would help him understand function calls as well as code analysis. An extension of this problem would be: how can you fix it? Yet another: how can you change it to return the remainder instead of the quotient? And, the most painfully obvious part of this: what operators do these two things for you already? (Correctly and quickly?)
Here's another idea for an assigment: I give you some function definitions that you can use, but I hide how they're written. Given some small documentation, use them to save a "secure" message to a file. Later on, load it and print it to the screen:
SecretMessage *makeSecret(char *message);
void destroySecret(SecretMessage &s);
void saveSecret(ofstream &file);
SecretMessage *loadSecret(ofstream &file);
void printSecret(SecretMessage &s);
Nah, that's kind've advanced for now. Pointers and stuff. Oh well, I'll think about it.