Hi. I’m Chelsea Troy. I’m a computer science educator at the University of Chicago. I frequently write about teaching. I put it all in the teaching category for easy perusal :).
I taught a Python Programming class in the winter. Now I’m updating the class to prepare for another session in the fall, and I’m walking you through my process! In the last post, we savored some nice, crunchy data to determine which assignments I want to change. Before we change the assignments, though, I’d like to share my principles about what makes a good assignment.
I have 5 guiding principles that influence what I ask students to do.
1. Realistic Subject Matter
I’m either asking students to:
- replicate part of an existing API like pytest or pandas, or
- solve a realistic problem using APIs they would actually use.
For example, I wouldn’t say “Make a calendar, but don’t use datetime.” I also wouldn’t be like “Write a coffee maker in Java” or “Write a bicycle in Ruby.” These are not realistic problems, and they also don’t provide my students with skills that transfer to realistic problems.
Instead, I choose problems that someone would conceivably use software to solve. I’ve assigned everything from a pet store parrot database to an income tax calculator. If it’s realistic, students are into it, which helps them learn.
2. As many, and as frequent, feedback loops as possible
Every problem has automated tests and/or clear objectives. Graders provide assistance and code reviews, but that’s not the only feedback loop. We run surveys on every problem to make sure the objectives are clear.
For larger projects, we have students propose at least 2 ideas. Then we choose one and list out some things we expect the finished product to do. Students propose an execution plan and we review that, too. Then we ask how they’re doing against their plan each week.
Those kinds of expectations and guardrails mimic what they’ll have in professional projects so they can practice some self-sufficiency in meeting objectives.
That dovetails with the next principle:
3. Requiring Outside Sources
Not only do I let students consult outside sources: I lecture them on which outside sources are available and when to use each one, and we do in-class exercises where they are specifically coached to consult documentation and open source code.
Homework and projects deliberately challenge them to use things we have not covered in class so they can practice the skill we did cover in class of consulting outside sources.
There is one big pitfall with this one: You have to make it crystal clear to the students that you’re doing that on purpose. I say those words verbatim to them in lecture. That mitigates the risk that they decide the teacher screwed up by assigning something that wasn’t covered in lecture.
4. Foster Collaboration
I want to create opportunities for students to work in groups. This one is tricky, of course, because straight-A students don’t want to carry slackers, and no one (especially in graduate school) has a ton of free time to coordinate outside of class.
My solution here is to:
- Only do group activities in class
- Make sure they’re not graded for quality or completion, but
- Go around to the groups, check on them, an note participation.
The bonus here is that I can give students “stretch assignments” in class that they’re more likely to fail at, without freaking them out about tanking their grade. It tends to be more fun to try, fail, and complain together with a group of peers or colleagues.
5. Cumulative Work
I try to build on previous activities in subsequent ones. If we do debugging in class, students will get a buggy app to fix for homework. For several weeks, they’ll be assigned each week to add a new feature to an app they’re working on.
This gives them time to walk away, come back, think about what they’re building (plus, from a practical perspective, they end up with something relatively fully-featured to show to a potential employer). As a result, students get invested in their assignments, and it’s not uncommon for them to make unassigned improvements. For example, I have students load an image in each cell of a table view. I let them re-fetch the image for each display, but inevitably someone wants a smoother UI and endeavors to cache the images.
I have had a lot of success with these principles.
I do not know for sure if these guiding principles would work outside of my specific context: a professional-preparation graduate program with highly motivated students who self-selected into my classes. But for what it’s worth, for me these principles have provided ample opportunity both to push students toward improvement, and to confirm that they are improving by watching their work styles and finished products evolve throughout the quarter.
That’s it for now. In the next post, we’ll get specific about assignment redesign.
If you liked this piece, you might also like:
This post about analyzing data to decide which assignments to change
The Raft series, of course! Learn to implement a distributed system from the comfort of your home, complete with gifs and smack talk!
The debugging posts (a toolkit to help you respond to problems in software)