Friday, January 27, 2006

Blogging about teaching: the upper-level electives

In my last installment in my blogging about teaching miniseries, I'm going to talk about how I approach teaching the upper-level electives. These are courses that are typically taken by our more advanced students: sometimes sophomores, but more typically juniors and seniors, since they are the ones that are most likely to have navigated all of the prerequisite hoops.

In a sense, teaching the upper-level courses is easier than teaching any of the other courses in our curriculum. The topic is very well-defined. The students are somewhat advanced, typically have good programming skills (the "coding maturity" I referred to earlier), and are capable of thinking more deeply about computer science as a field. Usually, if you're teaching an upper-level elective then it's at least marginally related to your field of research, and thus you're fairly comfortable with it. But these same features also can make teaching these courses tricky. How deep, for instance, can/should you go? How much material can/should you cover about a field? How do you reconcile what's important to you--and what you're comfortable teaching--with what the "real world" expects students to know about the field? And how much programming should you expect in an upper-level course, versus covering more theoretical problems? In short, how do you best mix theory with practice in the classroom?

Personally, I tend to teach the electives that have higher numbers of prerequisites, so I have high expectations for my students. I expect them to put more time into their work, and I expect them to have to delve deeper to find answers to the problems I assign. I expect them to be able to make connections to other fields, to apply concepts to completely new areas, and to wrestle with less well-defined problems. Lately, I've been making my expectations more clear up front, so that the students know what to expect going into the class. This minimizes the frustration quite a bit--or at least if the students are frustrated by a particularly hard assignment or exercise, they are more willing to accept the frustration as part of the learning process. (This is one of the key lessons I learned in my first few years here, and one that's served me very well.)

So how do I address the theory/practice issue? The short answer is that I try to work in both. Since the students are more sophisticated programmers, I can assign larger and more complex assignments. I may, for instance, have the students read a real-life design document or specifications document and implement the system that's outlined in there. The neat thing about an assignment like this is that the students have to integrate everything they've learned so far in the CS curriculum. They have to apply good design principles. They have to consider the relevant theory when making design decisions: if some feature can be implemented several ways, what does the theory indicate as the best way to implement it under these circumstances? And they have to deal with things like the fact that these types of documents rarely spell out all of the details, and so design tradeoffs need to be made. In the classroom, I try to split my time equally among theory and practice. We'll discuss theoretical reasons why a particular concept does or doesn't work, and then come up with real-world examples of that phenomenon.

In summary, I find teaching upper-level classes fun and challenging. While I may not spend as much time prepping (learning) the material, I spend more time and energy coming up with relevant assignments and examples, thinking about how my class will fit the students' needs after graduation, and making sure that they continue to develop into deep thinkers and skilled programmers.

technorati tag:


John Dupuis said...

Hi Jane, I was wondering if you assign much in the way of readings from the CS journal and conference literature in these upper level courses? In particular, I know a number of CS profs at my institution get their students searching in the ACM and/or IEEE digital libraries to find references or who assign articles from those databases as required readings. I think it also helps them identify which students may be interested in grad studies.

Baker said...

Jane, I've been reading your miniseries with rapture. I teach High School CS and, naturally, run into the same kinds of problems as you do (only with teenagers I think each problem is heightened by a factor of 2).

In any event, I do have some upper-level students, kids who have been programming for 3 or 4 years and are very accomplished mathematically. My main difficulty is taking things out of the abstract without being trivial. Pressured teens are generally less tolerant of deep thinking unless it gives intermitent rewards along the way, or unless the problem is somewhat tractable.

I would love to hear some examples of "real-life design documents" that I could have my students attempt to model.

Thanks for a great blog!

Anonymous said...

Hello Prof. Jane,

Great mini-series regarding your teaching methodologies. Couple of questions if you don't mind answering and of course some comments.

Do you still require students to work in groups? Do your groups get larger in senior level classes? For example, if you were teach an OS class would you increase the size of your class? Personally, my group size grew larger, the more senior I got (from 1 to 4) and usually I find that it helps a lot in terms of learning. Do you prefer in your senior level classes to have a major project and small assignments or a few major assignments i.e. minor projects? Once again all my senior classes were of the former type so I am not sure which one is better. Finally how different is teaching undergrad vs graduate students?

With regards to coding maturity have you tried switching programming languages every assignment. I think this works best in an algorithm class. You can switch from Lisp (great, great language and even useful in obtuse things like CAD) to Prolog to Java. The coolness in high level classes is absolutely fantastic. From learning stuff like garbage collection to A-star to the TCP/IP stack is just dy-no-mite.

As always have fun,


Jane said...

John, it depends on the class but yes, I do try to assign at least one journal/conference paper as part of the readings. I did teach one seminar in which most of the course readings were journal articles, and I will do the occasionaly "search the available literature" assignments. At this stage, it's a skill the undergrads should be learning and practicing. (And it helps that our librarian is super-fantastic! She is an absolute treasure.)

Baker, I agree that students have to reach a level of general intellectual maturity before they can deal with less well-formed problems--and sometimes they are not quite there even when they are juniors/seniors in college. The Internet standards (RFCs) are good examples of "real-life design documents"--some of them are quite accessible to students (and others you can limit the scope enough to make them tractable). Glad you're enjoying the blog!

SV, I do occasionally require group work, depending on the size of the project. I still find that pairs work the best--it's easier for students to get together outside of class, and I think they still learn more in pairs than in larger groups. I usually assign one major project and a series of smaller assignments, but I make sure that the smaller assignments prepare the students for the bigger assignments. As far as covering different languages in the same class, I will do that occasionally if it's relevant to the class. And I do agree that the upper-level classes have a very high cool factor! :)