This semester's course description lays out a plan much like I've used in past semesters. The first three weeks consist of a rapid introduction to course topics while students complete a series of three assignments. The next two weeks are devoted to a two-week project, where students work in pairs on a challenging project, bringing to use all of what they learned earlier in the semester. The final ten weeks are devoted to the final project—a project created by teams of undergraduates and completed in three iterations.
During these first three weeks, there's too much of a disconnect between the assignments and what I'm talking about in class. It works fine when students are keeping up with the reading and asking good questions, but that seems to only happen by chance, not by planning. Each assignment asks students to refactor with increasing sophistication, and I'm also asking them to look at either their own "legacy" code from previous semesters or Open Source code. I can tell that a great majority of them are trying to refactor on paper, without the help of the compiler, but almost none of them have the experience to pull this off. (Indeed, they don't have the experience to recognize that they should be using a compiler to check their work!) Because they are focused on the point-granting assignments, I am sure it is very rare that they take my end-of-class advice, where we are working on a case study and I say, "Try writing the next test yourself!" or "See if you can fix that UI problem." These mini-challenges never come up again: no one asks about them, unless it's me in the next class, when I am met with blank stares. This leads to what always strikes me as the most significant problem for our Advanced Programming class: in the first three weeks, the student are not programming. In particular, the weaker students are not getting the practice they need.
Before using three weekly assignments, I used to give daily assignments in CS222. This actually worked very well, in part because I could tweak them based on what we did in class. Why not just go back to this? Well, the course used to be Tuesday/Thursday, so that meant two assignments per week, and we used to have half as many students. Now, we have an exciting growth in majors, and despite my protestations, CS222 is now MWF. If I gave daily assignments—the interesting kind, that require me to read and give thoughtful feedback—I would drown in grading.
I am certainly open to suggestions, but really, the point of this post is not to plea for help but for me to remember today's thoughts in ten weeks when I'm prepping for Spring. In that spirit, here are some of the ideas I've had about dealing with this.
- Request a teaching assistant for the first few weeks of the semester. I generally have avoided them because I like to know what my students are doing and to give them expert feedback. If I could get a teaching assistant who has taken my course, though, maybe I could get them to do some of the more menial checks.
- Use more tooling to help with identifying refactoring opportunities. What if we had a static analyzer that would flag students' code based on some heuristics of code quality? For example, Clean Code talks about avoiding nested control structures: that's imminently detectable, but we would need to have the right tool to do it, and that would mean teaching yet another new tool to the students. (Also, I am not sure that this is better than learning to see it yourself, similar to how using spellcheck doesn't help you actually learn how language or spelling work.)
- Incorporate peer-evaluation. I did this a few semesters ago with achievements, where students needed to get peer-approval before sending work to me for evaluation. It did not work at all, in part because there was no incentives for evaluators to know what they were talking about. That's a systems problem, and I could try to improve that system, but I fear that this approach still leads toward blind-leading-the-blind.
- Remove the requirement that students find their own code to evaluate. The reason for introducing this was twofold: first, it gets students thinking about Open Source code; second, there are no issues of copying, since each student is doing different work. If I were to, say, create some repositories of code with Clean Code violations, then I would know that they can easily check it out (learning fundamentals of git) and actually run it in the IDE—and I could even provide unit tests! However, then the whole class would be working with the same code, and that invites the weaker students into the temptation of not thinking through the hard problems for themselves.
- "Flip" the first three weeks more aggressively, moving more presentations to YouTube with graded clicker-style multiple-choice questions at the beginning of class. This would eliminate the assignments entirely, but it has this problem that the clicker-style questions don't get at the kind of process knowledge I want them to be developing.
- Completely change the first three weeks, having them do individual programming assignments, relatively simple ones to make sure they know core Java ideas, and evaluate these on strict subsections of Clean Code. This probably would not take much more effort than what I am doing now in terms of reading and giving feedback. It echoes the problem above, though, that it could tempt the students who most need the practice to copy approaches rather than apply the processes we're trying to learn.