Tuesday, May 5, 2015

What We Learned in CS222, Spring 2015 Edition

In the Fall, I had some nagging doubts about the balance between individual learning and collective learning of fundamental Clean Code concepts in CS222, and so for the Spring, I made a significant change to the first few weeks of the course. I kept the overall rhythm: three weeks of warm-up, a two-week project, and a nine-week project delivered in three iterations. In those first three weeks, I added weekly assignments designed to help students keep pace with the reading and to assess their learning of the same.

I recognize that the ideas presented in the book can be rather challenging, and many students deceive themselves into thinking they understand it when, in fact, they cannot apply the concepts in programming. I do not blame them for this, but rather, I see it as one of the big challenges of CS222 to level the playing field; for example, a student who comes in with relatively little understanding of what a subroutine does still needs to emerge with a stronger understanding of functional decomposition, that a method should do just one thing without side-effects. Hence, I decided to use a mastery learning approach where the three assignments are graded on an S/U basis—either you showed that you understood the assignment or not—and you can turn in one assignment for evaluation or re-evaluation each week of the semester.

I knew that this would increase my grading load, but I was also excited at the prospect of incorporating mastery learning into the course. This model should, in theory, allow me to address my concerns that some students were "slipping through" the course by having their partners do most of the heavy lifting on the nine-week project. However, in order for the assessments to be valid, I needed differentiation: if everyone was evaluating the same code, then it would be too easy for the unscrupulous or the panicked to copy a solution from a classmate. Hence, I reused an approach that I have used in the past, where I ask them to evaluate code that they themselves had written in the past. I also made available the option that they could evaluate open source project code instead of their own, although this ran into the standard problems (which I guess I had forgotten about) that these students don't know what open source means nor how to differentiate a real project from throwaway examples on the Web; the only result of this was that some students wasted weeks writing about low-quality, non-open-source tutorial code they found on a random search.

The last piece of the puzzle was how to ensure that all students actually earned their satisfactory grade on the three assignments by the end of the semester. I decided to make this overt and clear: if you don't complete all three assignments, you cannot earn higher than a D in the course. These assignments, after all, represent that you personally understand the required course content, in particular the use of good names, clear methods that do one thing, readable source code, and the single responsibility principle.

These good intentions led to some stressful times for both me and the students in the Spring. The most challenging impediment was the initial low quality of the code that students brought with them from their previous semester. Most students had relatively little trouble fixing names once they understood the standard conventions (methods should be verb phrases, for example), but beyond that, there were much deeper problems. Their past projects were rife with side-effects, long methods, mixing of model and view, forced garbage comments (such as "// end of for loop"), and no evidence of object-oriented decomposition: everything was static and public. Add to this the fact that the students by and large did not care about the code—neither now nor in the past—and you get rather a difficult slog through the assignments. The third assignment was essentially to refactor the code to follow SRP, but in most cases this required touching literally every line of code. Kudos to those students who got through it, and I know that there were some students who got through the assignments with a much richer understanding of course content as well as much improved metacognitive and code-reading skills. However, this came at a cost of unreasonable time spent by both them and me: there must be a way to achieve these learning and assessment goals with less pain.

At the end of the semester, I dropped the D-cap grading policy and instead instituted a quantum deduction for each assignment not yet completed, and I combined this with an offer for students who were "stuck" on the assignments to send me alternative evidence that they learned the material. Only one student took this approach, but what he did was brilliant: he restated the assignments, pointed out what intellectual work they required, and explained how he had shown his ability to do this within the final project. Right there, we have an example of what I mean: he showed me that he understood specific elements by clearly and proficiently writing about them.

One idea for fixing this part of the semester is to reuse some past game studio project code and give this to CS222 students for evaluation. Unlike their own past code, these projects were ostensibly written to follow Clean Code from the beginning, and so there should be fewer fundamental problems. I am not sure of a fair way to break up a project across thirty sophomores, and doing it randomly could end up with a struggling student inheriting some very bad code. However, this would have the advantage that they would be dealing with real project code that was written by students only one or two years their senior.

During the rest of the semester, I reused by achievement-based grading system as before, where earning achievements unlocks higher grades. I took away the "quest" system for simplicity, but I found myself missing the concept of leveled achievements. I am not yet sure if I will bring that back in the Fall. One piece I have spent some time thinking about is how the achievement system could use more peer evaluation. Reading about digital badges, I know that a common successful practice is to allow anyone to sign a badge, but that the perceived quality of the badge is related to the signer's authority and expertise. I would like to do something similar, allowing the students to grant achievements to each other, which would provide incentives for them to look at and think about each others' work. This could also serve as a high-pass filter, where students only show me their work if it has been vetted by a peer. I spend an unfortunate amount of time writing feedback of the form, "This method is not a verb phrase," and if I can turn that pain into a peer learning opportunity, all the better for it.

In the Fall, I am scheduled to teach two sections of CS222, which I have not done before. I need to think a bit this summer about what that means. Often I come to class with rough lesson plans but end up reacting more to what students are asking about or struggling with. With only one section, it doesn't matter if I shuffle the order of topics based on this interaction, but with two sections, this sounds like a recipe for a headache. I wonder if I should take a more studio-oriented approach, spending more time in class helping students with activities rather than modeling and moderating discussions. I have tinkered with producing videos to model behavior (a story for another blog post), but I find this to be very stale: so much of my in-class modeling is really an interactive performance, feeding off of the verbal and physical feedback of the crowd. If I drop a new keyboard shortcut in a live session, for example, I can see the perplexity and astonishment of the crowd and then talk about not just what I did, but how I did it. If I record a video, it's much more automatic and looks like magic, without students' being able to raise their specific questions at just the right time. On the other hand, the video does make it easier for students to rewind and hear me explain some theoretical ideas more than once instead of relying on their notes or, more likely, ephemeral memory.

I don't regret the changes I made this semester, but they certainly had some unintended consequences. I felt like I had some difficulty "reading" the class, perhaps because it was 8AM and so had more spotty attendance than usual. However, I felt that once we hit stride, I really got to know the teams, and I am proud of their final projects. As usual, there were ambitious projects that had to be scaled back, but really, all of them ended up successful.

At the end of the semester, the students rated these items as being the most important to them:
  • Test-Driven Development [11 votes]
  • Don't Repeat Yourself [11 votes]
  • Working on a team [10 votes]
  • Single-Responsibility Principle [10 votes]
Looking at the rest of the 112 items that they listed, there are specific practices identified which make up these top four, such as naming methods with verbs, respecting teammates' perspectives, and model-view separation. As the students came up to place their votes with stickers, a student asked if he could put a sticker on me, since he thought I was the most important part of the class. This was a nice compliment, and I don't think it had ever come up before in teaching this course. As another student heard this, he said that he wanted to put a sticker on my mug for the same reason, but he figured the mug was too sacred an artifact.

I will be revisiting CS222 this summer as I prepare for Fall, but for now, it's time to change gears. There are still many stories from the Spring semester that I would like to reflect on and share here. One of my early-summer tasks is to prioritize the rest of my summer tasks, and I need to be conscientious about making time for reflective writing. In the meantime, however, it's time for some breakfast. Thanks for reading, and as always, feel free to leave a note in the comments.

No comments:

Post a Comment