Teaching programming basics

November 1, 2013

Ah, the good old days...

Right after finishing my CS studies, I received an offer from my university to work there as a teacher. It was really unexpected and I felt flattered. It seemed a good opportunity to stay in that nice campus instead of joining a job market that I didn't find appealing at all, so I quickly accepted the offer.

Being shy and younger than some of my students, I worked hard to compensate my lack of experience and confidence. Of course, I made many mistakes during my first year, but the "programming basics" courses... well, those were one of the most rewarding experiences in my life.

At that time, the classes were given in a blackboard, exams were handwritten and the students only had access to a compiler in class after completing their first semester. Still, the students kept a great level of engagement and commitment. I've randomly bumped into many of them since then and all remember those classes with fondness, and found them to be a solid foundation for their following academical and professional duties.

Back to present

I live in USA and my wife Sandra is not allowed to work here due to visa restrictions. Interested in the internet world, she managed to learn some HTML and CSS and wanted to learn programming – given my background, you can imagine a big smile in my face when she told me. She didn't want to distract me from my full-time job to teach her though, so she's been trying a few options during the last year: a MOOC, attending self-organized classes in a local user group, video-based courses, ebooks and one of those online academies that teach web development courses in three months. I've been tracking her progress and reactions during this whole process and I think that many of those learning resources are missing something.

In this article I'll point out a few common patterns that served me well in the university. Some of them may seem obvious, but they're still partial or totally ignored in the alternatives that Sandra has tried so far and I think they can have a huge impact for a beginner.

Disclaimer

I'm speaking from my personal experience (so YMMV) and focusing on delivering the best learning experience and outcome for the student, ignoring factors like if these patterns scale (spoiler: some don't) or are aligned with a certain business model. Teaching programming basics must provide a ground floor to the students so they can keep learning by themselves with confidence. That should be the goal beyond anything else. Given the current demand of programmers, providing a great programmind education should lead to a sustainable business too: successful students become the best salesmen in a market with high demand and where the average competitors leave something to be desired.

Programming beginners 101

According to my experience, most students that haven't programmed before have some things in common:

  • They have fear of breaking something. They don't know the difference between source and compiled code. If they use an IDE, they may not know where their files are stored. They don't use versioning tools beyond Undo/Redo. Addressing this issue is crucial: feeling confident and free to experiment is key when you're learning to program. Help them to identify where the actual code is, how they can keep a safe copy of their working programs and how to discard the bad ones.

  • They need to start from familiar concepts to get new ones. Programming is different to many other things, but I've found that using metaphors based on physical actions and objects (e.g: "an algorithm is like a cooking recipe") helps a lot to introduce new concepts. There is time to mention differences and subtleties later, once the metaphors have helped to start assimilating the new concepts.

  • They don't know what is relevant and what is not. This is frequent in beginners on any domain. They pay attention to everything and that's mentally exhausting. Introduce new concepts very slowly, one by one, and keep your lessons short in theory and long in practice. Present only relevant content. If you still decide to provide secondary details, explain that those are interesting but not relevant.

  • They need consistency. Whenever we learn, we're looking for patterns. Consistency helps to identify them. Even if the language you use doesn't have a clear style guide, you should have one, follow it strictly and make sure that they follow it as well. Same goes for compiling, building or debugging instructions: consistence will help them to be methodical, develop a workflow and experiment more easily.

  • They need patience (and teachers too). All programmers do. Our society promotes quick wins, but learning to program takes time. Time to learn and time to teach. Providing a counterexample that breaks a candidate solution is not enough when they're starting. Don't anticipate the result of an exercise. Instead, debug the algorithm with them step by step, tracking the execution of the code and the state of the program. They will need to do the same when doing the exercises by themselves, so if you debug together you'll be teaching them to be patient and methodical by example.

  • They need focused practice. After introducing a new concept, always start with very short exercises focusing only on that new concept. Then introduce small variations until the students feel comfortable, then gradually mix the new concept with one of the previous ones, and keep increasing the number of concepts you combine until they feel internalized.

  • They need curated exercises. A boat load of them. You can do an excellent work on teaching theory, but exercises are key: they will help to internalize any new concept, to build confidence and will tell you when it's time to move forward. The exercises must be curated in scope (some focused on single concepts, some combining different ones), in difficulty (there is no need to introduce smart algorithms yet, expressing a simple algorithm with code is difficult enough for a beginner), in length and in execution time (students will spend a lot of time tracing the execution of every solution they come up with, so keeping things short will save them some of that time).

  • They will be wrong and feel pretty bad about it. Learning to be wrong, and to learn from your mistakes, is an important lesson. It takes time to identify your mistakes and even more to learn from them, so they need to get used to make errors and don't feel frustrated or angry about it. It's important to keep a tight feedback loop when they do their exercises and assist them before they feel really frustrated. Give them a hint until they come up with a proposal. If it doesn't work, debug it with them so they can see why. If they get stucked for a long time, providing a solution and a new exercise is better than letting them despair.

  • They will succeed, and feel just ok about it. That's wrong. It typically takes many intents to solve a problem: a syntax problem here, a logical error there, and edge case that crashes a program that seemed to work... That error/success ratio is depressing if you don't know the value of a success. If they feel that every error is a lost battle, when they solve an exercise they should feel like winning a war. They should celebrate it, at least internally, but they don't know how it because they don't know the value of a victory yet. Don't be shy and celebrate victories with them – their victories are partly yours too.

Exercise reviews

As I mentioned above, I think that reviewing exercises with the students is a fundamental part of their learning process. It helps them to learn how to test if a program works, to develop patterns for detecting edge cases and patience to debug a problem. Is in this point when students primarily need to be mentored and receive fast feedback in order to maximize their learning, learn from their errors, stay motivated and keep their momentum. Unfortunately, I think that all the online resources that Sandra tried fell short at this. Many focus on providing good content, but provide just a few exercises (if any) and poor or no feedback about their solutions.

Automated reviews

I dream with the day when we can automate the labor of teaching programming basics at mass scale but according to Sandra's experience we're not there yet: she tried several of those academies where you submit your programs through an online editor that detects issues in your code and checks if your solution works. At some point, all of them failed. I tried to help her, but there were no obvious front-end bugs and when she looked into the course forums (where forums where available), other students had reported similar bugs and were waiting the bugs to be fixed. Some were blocked for days, and in that scenario it's very difficult to stay motivated. I have no doubt about the talent of the engineers working on those online tools, but it's a difficult problem that can take some time to solve properly. On the meantime, students like Sandra accumulate frustration and look for better alternatives or run out of motivation.

Peer reviews

Some courses use peer reviews as an alternative to full automation, but it doesn't seem to work well when the peers are total beginners. They lack the experience, criteria and patience required to detect edge cases, to explain why a solution is wrong and to provide good feedback, and that is essential to make a good progress.

Mentoring

Part-time mentoring is the best alternative I've seen so far. Sandra tried an online academy with one hour of real-time mentoring per week using Google Hangouts. This was helpful, but she still missed having a higher frequency of mentoring. Waiting a week to get synchronous feedback for her exercises wasn't enough, and email-based reviews weren't as rich as she needed. I think that something around 3 synchronous mentoring meetings per week would be enough to keep students motivated and progressing at a good pace, as long as they have a large number of exercises available so they jump to a new exercise if they get blocked. I haven't seen any online academies providing such amount of real-time mentoring nor exercises though.

Fin

Software is eating the world and in a globalized market there is a huge opportunity for those willing to teach programming basics online. Some companies are creating good content but there is still a lot of room for improvement.

I look forward to seeing what's coming next.