This semester I piloted an introductory programming course with the ninth grade students as an elective. What follows are some reflections on the first-run through the course—which still has about a month to go.
Originally, I toyed with using Python as the programming language of choice. Python is commonly used in undergraduate introductions to computer science and is a pretty flexible language. I taught the first few lessons with Python in the back of my mind as I introduced some basic programming concepts, but at the last minute I swapped in Ruby, which is similar to Python at a base level1, but has the added benefit of being the programming language that I’m most comfortable with.
It felt disengenuous to be teaching with a language I wasn’t completely comfortable with. I am a little rusty in Python and I thought teaching with the language would force me to bone up, but—given a busy schedule—that wasn’t happening. All of my projects currently in active development are in Ruby and it was a better fit for me.
By most objective measures, the course is humming along fine. My students are generally happy and they are creating some trivial little programs on their own, but—as I reflect on this first run—there are definitely some things that I would consider changing.
Over the last few months, I’ve learned that a good programming language should meet the following criteria:
- The distance between starting and creating something that makes you smile should be as short as possible. Teenagers are visually-oriented and have little patience for command-line programs. The sooner than can create something graphical, the better. When they think of computers, they think of games—not relational databases.
- The language should be transferable to projects outside its own little world. Scratch and similar programming languages offer a rapid learning curve and make it easy to create a graphical program, but they are niche languages relegated to their own little worlds. I want a language that is flexible enough to be used in the “real world” when the time comes.
- It has to be easily installed on students’ home computers. My students had trouble installing Ruby and Python on their home computers and it was borderline impossible to for me troubleshoot the issue blindly. For the most part, students have been writing their programs at home in a text editor and debugging in class. Even then, the thought of installing RubyGems on 32 computers with an HTTP proxy is not particularly appealing.
As much as I personally enjoy programming in Ruby, I am not sure that I would use it again as the basis for a programming course.
Reducing the Distance Between Starting and Creating
Teaching programming is an interesting challenge because there is a huge learning curve before you can do anything even remotely cool and 14-year-olds are not known for their admirable attention spans.
At the same time, you want a language that is generalizable to a wide range of challenges but also has the depth to keep students interested for the length of the course. I used Scratch with the sixth grade last year for one unit and it was a success, but ninth graders bore easily. Sometimes, it’s about dialing in the right amount of challenge. Enough to keep them interested, but not so much that they get frustrated and check out.
Rather than teaching skills in a vacuum, I want to completely rethink my curriculum. Instead of a series of lessons, it should be a series of challenges. The skills that I teach should put students just in the zone of proximal development for solving the next challenge.
Sure, this idea isn’t anything new. But many times, it’s hard to pull off when you are teaching something for the first time. It’s not always easy to see the non-obvious ways that skills link together until you’ve run through the curriculum once and made the necessary, serendipitous discoveries in how your students approach the content and how they make connections between different concepts.
This time around, it took me a few tries to figure out how to best explain a particular concept (e.g. object-oriented programming). I found myself teaching concepts in a vacuum and then providing exercises that emphasized those concepts. The assignments were based around the concepts I was teaching instead of my instruction being centered around the challenges they were faced with.
In the future, I am going to frame it as a series of challenges they must surpass or riddles that they have to figure out move forward. In a way, I want to make it more game-oriented. As they complete a challenge, they can move on to the next one.
I will still be covering core programming concepts as a group, but students will be able to move through the curriculum asynchronously. In order to do this, I need to collect a bunch of programming problems and arranging them in a way that allows the student to build up their skills as the move along.
I might really want to create a relational database to track and organize different pieces of information. That might be my (admittedly banal) impetus for wanting to learn how to program and there are plenty of resources out there to learn to do that.
For my students, that isn’t necessarily a problem that they are looking to solve. They want to make something cool. And there is nothing wrong with that. If they manage to cement their skills through making a bunch of trival games and “What Disney character are you?” surveys, fine. They will still have those skills when they want to solve an interesting problem later on.
Seeing is Believing
As much as I love the command line, it doesn’t have the same effect for a teenager. They need to be able to create a GUI and see their program work early on or else they’re going to lose interest.
You’re never going to be able to be each and every one of your students’ personal Geek Squad and there is no way to control what computers (if any) your students have at home so don’t bother trying. Chances are, you are not going to be working with the most reliable systems in the world.
I get some of my best programming done away from the computer. I will be walking along the boardwalk or eating a sandwich when an innovative solution to a problem I’ve been grappling with will pop into my head.
I used Hackety Hack while teaching Ruby. The software itself has been notoriously buggy and my students have some difficulty with the fact that—while Hackety Hack is Ruby-based—many of the functions and methods don’t translate particularly well to traditional Ruby. When Hackety Hack mysteriously implodes and will no longer launch correctly in Snow Leopard, I try to nudge them towards vanilla Ruby and it’s almost always a disaster.
NodeBox is based on Python and is capable of producing some really interesting graphics. That said, it’s Mac-only and while I don’t insist that my students install a given toolset on their home computers, it would be nice if they could.
Codea, the Lua-based programming application for the iPad, looks promising and I could give it a spin with the seventh grade (and their one-to-one iPads), but I still have to figure out the details of purchasing apps through Apple’s Volume Purchasing Program before I can move forward with any options that require the exchange of money.
Next time I teach the class, I will probably go with Processing, the Java-based and graphically-oriented programming language by Ben Fry and Casey Reas. It’s multi-platform, easy to install, and lets you create graphics from the get go. As much as the Rubyist in me dies as little every time I have to look at Java source code, Processing does contain and engage with all of the major concepts and features of a modern programming language. In addition, the Processing.js project makes student work easily sharable via the web.
I know. There are some fundamental differences—but I’m talking about the very basic foundations of programming. ↩