CS50 – Harvard’s Open Computer Science Course

In June this year, a friend (Eleanor Matthews) posted on LinkedIn that her son, studying on his own during lockdown, had completed CS50 and was looking for a new opportunity. I’d never heard of CS50 before and a quick bit of Google Fu let me know it’s a Computer Science module from Harvard that they have released to the public so anyone can join in. It sounded an amazing achievement for Toby to have learned so much and completed the course. What a world we live in!

Then a couple of weeks ago, I was contemplating the best ways to help completely inexperienced people learn how to love coding and become competent in what I believe is one of the most important career skills of our modern age.

I remembered CS50 and how much I’d liked it, so I decided to immerse myself and use the experience to smash my mind into some new things. I also wanted to work out if I might be able help novices develop computer science skills by running alongside them and offering them personal coaching while they engaged directly with CS50 themselves.  If I could, it might be an amazing way for them to turbo charge their development!

Right now, I can dedicate some time to this and I hope I will be able to keep the necessary time ring fenced until I get to the end of the 12 week programme. 

In this blog, I’ll give my first impressions of the programme and also discuss my first assignment that proved more challenging than I thought! I can’t promise that I will blog about all the assignments but I really enjoyed this one so here we go! 

Week 1

It starts with a YouTube video from the course leader David Malan. He is a high energy force of nature who covers a huge amount of content in an engaging and entertaining way. It may seem like he’s not covering much in detail but if you can actually understand everything that he says, there is a tremendous amount of content. 

In the first video, David guides us from the absolute fundamentals (binary systems) through character encoding, algorithms, algorithmic efficiency and finally into the world of Scratch (a visual programming environment that lets us create real programs without typing any code). 

In this video below, I created a cat that follows the mouse around the screen and draws a dashed line tracing the route. It literally took me about 30 seconds to do that!

Our first assignment

I watched the video from David Malan, signed up and looked at our first assignment. It gave us a huge amount of scope and pretty much allowed us to do anything we wanted by writing a program in Scratch. 

It’s not my first rodeo and I knew that I’d be able to satisfy the minimum requirements of the homework in a short amount of time and I wouldn’t learn all that much in the process. I believe in the power of innovation (if you’re interested in increasing your ability to innovate on demand, you might like my blog: Five tools for innovation mastery) and setting ridiculous constraints is often a good way to force a different paradigm. I decided almost immediately to try and build some form of artificial intelligence from scratch (pun intended!) into my work. 

A few years ago when I was learning JavaScript, I built a q-learning agent from the ground up that navigated across a grid towards a goal whilst avoiding danger along the way. I also wrote a blog about that: Lessons in life from an ai agent which you might find interesting. 

So I decided to re-implement that solution in the Scratch environment. I thought it might take me about 15 hours to do it (what a poor naïve fool I was!!!) so I jumped in and started the task.

Q-learning is a form of ai that optimises actions when moving from one state to another and trying to achieve a goal that may not be realised until many moves later

There was quite bit of functionality to be written to get the solution that I had in mind:

  • Create a grid:
    • I wanted to be able to specifying the number of columns and rows so I could make it harder or easier to solve whilst I was writing / debugging
    • Although our cat can move smoothly from pixel to pixel, we need a more manageable  grid as q-learning works out the cost and benefit of moving from one state to another by following an action. A pixel based grid would have 172,800 states and with 4 actions per pixel, my instinct was that there would be too many variables to train the system in a reasonable amount of time
  • Allow the agent (our cat) to move from cell to cell in the grid 
  • Define the q-learning array that has a number of entries per cell (one for each possible move: up, up right, right, down right, down etc) and one for the reward or cost of landing in that cell 
  • Randomly allocate a number of killers to locations in the grid and update the q-array to reflect the higher cost of landing in those cells
  • Locate the goal in the top right hand corner of the grid and update the q-array to reflect the value of the reward for achieving the goal 
  • Use the q values to work out which move to take from the current cell 
  • Update the q-value in the previous cell that corresponds to the action I took to make the move
  • Transport the cat to a random new cell if it lands on the killer or the reward 

Remembering that my initial estimate was15 hours, I was just a little bit disappointed when at the end of the third day (24 working hours) the cat was romping around the grid, dying when it hit the killer bats and getting the reward when it reached the goal. 

But then the fun started as I tried to work out why it didn’t seem to be learning how to avoid death and achieve the goal!!! 

I found debugging in the Scratch environment to be very different to working in a normal coding environment. The charm of dragging blocks around started to wear thin as I realised that I couldn’t do some pretty basic things that are fundamental to debugging / writing code. Just for a quick list, I couldn’t find a way to:

  • Find all the places that a variable is used 
  • Find all the places that a function is used 
  • Single step through some code 
  • Console log messages to identify what is happening, in what order and what the variables contained at that point

After 5 solid days writing and failing to debug the q-learning system to allow my stupid cat to avoid some stupid killer bats and reach a stupid goal in the corner of a stupid grid, I’d almost had enough!!!

Over dinner that night, I explained the problem to my wife and daughter. They laughed because my misery was completely self induced and had zero sympathy. “Just abandon it and do something easier” they suggested.

Hmmmm…. 

Well, it was a possibility (a theoretical one anyway!). 

But not a route that I would be pursuing while my fingers can still reach the keyboard 🙂 

It was with fresh resolve that I headed out to “The Wendy House” next morning and systematically started to hunt down the bugs in the code. I wrote a console logger and a rubbish implementation of a single stepping debugger and these eventually helped me to get the job done.

All the pain that building and debugging my assignment caused was washed away on a tidal wave of elation when the thing actually started to work correctly! I suspect many developers will recognise that huge rush as endorphins are released and the world seems like a beautiful place once more! Perhaps like scoring the winning goal at a Wembley cup final, but even more intense 😉

In the end, the whole exercise took me about 55 hours and whilst I don’t regret it (!!!) I think that I may try to curtail my ambition for some of the future exercises 

If you are interested, you can see the solution I created here

And there’s a short video about it here: 

In summary, I would say that CS50 seems like an amazing programme for people who are considering a career change or are still in education and are curious about computers and the impact they can have on our world. 

If you’re thinking about a career change yourself and would like to talk to someone who’s been in IT for the last 40 years or so, please give me a shout. If I can help, then I will.