We always tell ourselves and our students to take risks. But taking risks means that we will fail at things. And generally, none of us like to fail.
Think about what it’s like to write code. Most of the time, the code is broken, and you’re failing.
This semester, I’m watching my students struggle with assignments in our sophomore-level object-orientation in C++ programming class.
We’re working through a series of two-week projects. The projects are pretty fun:
- using recursion to draw Sierpinksi’s triangle (and creating a derived object that’s “drawable” using a gaming graphics library)
- building a pseudo-random number generator using a linear feedback shift register, and then using this to encode (and decode) an image
- simulating the movements of planets in the solar system (using Newton’s fundamental laws of gravity and acceleration)
(There are more—this material is from Princeton’s COS 126 course.)
From the students’ point of view, there are a lot of steps to get to a working system:
First, to understand the basic problem. What data structures will we use? How does the algorithm we’ll use work? How will it all be organized into objects?
Next, starting to write code. What goes in the header file? What goes in the source file? Why is there this separation anyway?
OK, I have some code. Let’s try compiling it. Oh great, tons of compile errors. Of course.
OK now it compiles. Does it work? Not a chance.
Well, time to debug… where do I start? Probably printing some stuff out… how about seeing that I can read the command line arguments properly?
And so on.
Probably the most challenging part is at the very beginning—making sense of the task itself, and how it’s to be accomplished.
I encourage my students to do their work in baby steps. Just write a few lines of code, compile it, and make sure it works.
Only add more code after you have a little bit of code working.
Compile and test before moving on. Make sure you are going from a working thing to the next working thing.
But even with this strategy, as soon as a bit of code is working, the next step is to add more code, which means breaking it again!
Most of the time, things are broken.
It takes a high tolerance for failure like this.
I do believe that we learn best when we encounter challenges.
And the beauty of our practice is that we’re so readily able to get feedback on the quality of our ideas. Since our ideas are expressed in machine-executable form, we can debug them.
But it is hard, emotionally demanding work, and it’s important that we recognize how much effort our students put in to accomplish their successes.
Terry Dash, a CS educator in Massachusetts, just described to me a teaching experience she had teaching Scratch to middle school students. Midway through the school year, her student Erica cried out during class, “Now I get it! The more it breaks, the more fun it is!”
That’s the spirit!
CSTA University Representative