In the past year, many CS professors and education pundits have written about how MOOCs are scaling up CS education to hundreds of thousands of students. I'm going to take a different approach here and tell the story of how I spent nine months teaching computer programming to one student.
Between July 2011 and March 2012, I taught basic programming to Brian Goler, a veteran San Francisco Bay Area entrepreneur with an extensive background in marketing, sales, and product development. Brian started out with no prior programming experience, but within a few months, he was able to build SwearBuy, a free web application where people can share reviews of products that they love. More importantly, Brian gained the ability to seek out and learn more advanced technical material on his own. My biggest contribution was guiding him over the hurdles that usually demoralize beginners.
Brian learned about me from my personal website because it contains a few articles about computer science education. Here is an excerpt from the first email he sent to me in July 2011:
We haven't met, but I'm reaching out to see if you might have some advice for me.
I found your website while searching online for a tutor who might be able to help me learn more about computer programming. Specifically, I'm looking for someone who would be able to meet with me 1-2 times/week for short, 1-hour tutoring sessions while I work my way through the early phases of a CS curriculum.
I'm starting with MIT's OCW 6.00 course. While OCW and other online resources are great, I think I could advance more quickly and improve my understanding of concepts if there were someone I could turn to with questions and who could review my work and give me feedback.
Given your history at MIT and Stanford, I thought you might know someone who may be interested and a good fit? Or, places I should be looking? Of course, I'd pay for their time.
Since I wasn't too busy at the time, I offered to tutor Brian myself. We had our first one-hour session at his home and the second session at a nearby coffee shop. I then traveled to some academic conferences, so we did our third tutoring session over the Skype online video phone service. We used the screen sharing feature of Skype so that I could see the contents of his computer screen as we chatted. This format worked so well that we decided to do all subsequent sessions over Skype. I tutored Brian only twice in person, but we did over 50 hours of Skype video calls (spanning ~40 sessions).
At first, we were both surprised by how well the online-only Skype format worked for our sessions. It was even better than us meeting in person at a loud coffee shop and huddling around a small laptop screen. Using Skype's screen sharing features, I could view Brian's computer screen from the comfort of my own apartment and interact with him in real time. If I needed to make sketches, then I shared my computer screen with him and drew using a digital pen tablet. (Salman Khan started making his now-world-famous educational videos by tutoring his cousins in a similar way.)
Brian's goal was to learn basic programming skills for personal enrichment; he wasn't trying to get a job as a professional programmer or a computer science researcher. Before we met, Brian had already spent a few weeks teaching himself the Python programming language by following the curriculum of Introduction to Computer Science and Programming (OCW 6.00) from MIT OpenCourseWare. We spent our first few tutoring sessions going over basic programming concepts, grounded in the course lectures and homework.
However, I quickly realized that just learning from academic course materials would not keep Brian sufficiently engaged, especially since he graduated from college almost twenty years ago. He did not seem too keen on limiting himself to learning only computer science terminology and doing math-related puzzle problem sets intended for undergraduates.
Therefore, I decided to teach Brian to become a pragmatic amateur programmer rather than an erudite computer science scholar. I encouraged him to try to think of a piece of software that he would love to build for himself and his friends. My role would be to mentor him while he built his software project. It was such a simple idea, but it worked remarkably well.
Brian came up with a few ideas and ultimately committed to the concept that would eventually turn into SwearBuy. Over the next nine months, he devoted up to dozens of hours per week to building SwearBuy, often working late into the night. We scheduled 1 to 2 Skype tutoring sessions each week, each lasting 1 to 2 hours. I spent most of my time during those calls answering Brian's questions, helping him find and debug software bugs, and sometimes pair programming to write new code together with him. I rarely lectured for more than a few minutes at a time. Besides being highly engaging for him, this Q&A-based format was convenient for me as well since I rarely had to spend time preparing before our sessions.
Project-based learning was immensely effective since Brian cared deeply about his own fledgling creation. His learning was guided by necessity, not by some preset cookie-cutter academic curriculum. Since he was so passionate about SwearBuy, he would come up with lots of ideas for new features. He would inevitably need to learn new programming techniques to implement those desired features. Thus, my role was to:
There are dozens or sometimes hundreds of ways to accomplish the same task in computer programming; this multitude of choices can be paralyzing for beginners. Since the space of possibilities is so vast, they simply have no idea where to start. My main job was to narrow down the space of possibilities into a manageable set of concepts to learn at each stage of Brian's project, let him struggle with learning on his own, and then answer his questions when he gets stuck.
Brian's project was a great basis for all of our Skype conversations, since I could teach new concepts within the context of what he wanted to accomplish in his project at any given time. No amount of contrived textbook examples can make up for a real-world application in which a student is personally invested.
Brian usually did 10-15 hours of programming on his own before each 1-2 hour Skype call with me, so he always had plenty of urgent questions and newly-written code that he wanted me to help him debug or improve. If I had just given him lectures without any context, he would not have internalized the lessons as thoroughly. He would have probably nodded his head and been like, "uh huh, ok that makes sense ... cool. what's next?" Instead, because he was usually struggling with concrete, code-related problems before our tutoring sessions -- often to the point of frustration and discouragement -- he would respond more like, "OHHH, WOW! Now I totally get it!", whenever I guided him over some problem that seemed insurmountable to him at the time. His joy and relief were always unmistakable. I don't think there is any better way to internalize knowledge than first spending hours upon hours growing emotionally distraught over such struggles and only then being helped by a mentor.
To make Brian's experience less painful, I took care of I.T. infrastructure setup and other "grunge work" that did not directly contribute to his learning. I wanted him to struggle hard on the actual programming and building of SwearBuy, not to waste his time on banal unrelated issues such as setting up a web server or version control system. (Of course, if his goal were to learn to become a system administrator, then I would have let him struggle with those tasks.)
There are lots of trendy books, online courses, and live seminars that claim to teach you programming (or other skills) in 7 days or 3 weeks or whatever. It's obvious that you cannot master a new skill in a few weeks, but I don't think anyone actually believes they can. The real danger with these sorts of "get skilled quick" schemes is that they don't emphasize sustainability. These courses are like fad diets that might get you to lose 10 pounds right away, but you are not going to keep the weight off unless you develop sustainably good habits. Similarly, there is no way to get skilled at programming unless you keep struggling over many years; but in order to stay motivated to keep struggling, you must be doing something you are passionate about. Struggling isn't fun, so without the proper motivation, it's all too easy to give up prematurely.
I knew that I had succeeded as soon as Brian realized he no longer needed me as his tutor. Even though he acknowledged that it would still take years of struggle to become a skilled programmer, he began to see how he could potentially get there from his current skill level. He had learned enough over the past nine months to sustainably continue learning on his own. I am proud that I gave him enough know-how and wisdom to continue on his own rather than serving him yet another "get skilled quick" fad diet scheme.
After our tutoring sessions ended, Brian reflected that although he cherished this "learning by doing" philosophy, he still believes that there is great value to balancing project-based work with traditional computer science course-based instruction. When building SwearBuy, he often applied ad-hoc solutions "just to get things working" using lots of Google searching, technical blog reading, and copying-and-pasting code from StackOverflow threads. As a consequence, he felt like he too often settled into suboptimal solutions or used concepts that he didn't deeply understand. Some of Brian's biggest forward mental leaps came when he took a step back away from the day-to-day project grind, learned new concepts in a course or from a book, and then thought about how to apply them to SwearBuy.
Since we finished our final tutoring session in March 2012, I didn't hear from Brian for six months. He recently sent me an email mentioning that he just wrote a Python script to help him model personal stock investments: "I'm very proud of this script because it was the first thing I've done that was both practical and purely for personal use. I was evaluating a stock investment and wanted to simulate a bunch of scenarios. I started to model the scenarios in a spreadsheet before I realized that a spreadsheet wouldn't work, but python was perfect."
I loved this email because it showed how programming enabled him to accomplish a task that would have been tedious or difficult to do otherwise. I hope that everyone who learns programming has their own "crossing the precipice" moment when they start programming for themselves rather than just for school or work assignments.
The cliche I'm going to rehash is that motivation is everything. Brian was highly motivated by his own project, so he practically taught himself. All I had to do was to steadily guide him along an efficient path so that his struggles were mostly directed toward useful learning.
How well do my experiences generalize to teaching the vast majority of students who are far less self-motivated than Brian? And how well does this technique scale up beyond one-on-one tutoring? I have no idea. All I know is that if you can get students genuinely motivated, remove unnecessary barriers to learning, and give them nudges at the right times, then they will practically teach themselves.