HarvardX CS50 - A Full Review

After nearly 6 months of study, I've finally finished CS50. These are my thoughts on the course and what I learned from it.

Cover Image

Back in February, I started studying CS50x. Whilst the course is split into 8 weeks before splitting off into specialised tracks, I took much longer to complete it. I finally finished the course on 23 July 2020, nearly 6 months after I began. The course is an introduction to computer science, algorithmic thinking, and programming. It introduces students first to Scratch, C, Python, and a few other languages depending on specialisation. The final project is a freeform assignment that can be anything the student wants, coded in absolutely any language.

I published my overviews of the various problem sets here so I won't go too much into the problems I solved beyond their impact on my learning. This article, published in 2018 gives kind of an overview of where I was at with my journey to learn to code before I took CS50. At that time I was working through a discrete mathematics book and starting to grasp some of the concepts, though not to the level where I could break out of the same patterns of solving problems.

As I mentioned in my Week 0 review of CS50, I'd been peripherally aware of the course for a few years. Similar to how I'd been aware of Drawabox for many years before I finally jumped in (you can read about my Drawabox journey here). I draw this parallel because of my experiences with both courses. Where Drawabox teaches fundamental ways of thinking about solving drawing problems, CS50 does the same for coding and programming problems. Neither is about learning to draw or code in a particular way, but rather about giving you the tools to solve problems.

I thought the course started off a bit weirdly, with the Scratch introduction but I guess this is a good visual way to introduce some of the core logical building blocks that make programming what it is. I was also a bit dubious about learning C since I have never had a reason to code in such a basic, low-level language before. As I mentioned in some of my other articles, I've mostly stuck to JavaScript and PHP, being primarily focused on web development up until now and whilst I likely won't use C again any time soon for my coding projects, I do believe the experience was absolutely invaluable. What I hadn't been exposed to in my focus on web development (and later, small Python projects), was the underlying structure of how some of these things worked. For me, a dictionary object in Python basically just worked as a JSON object, and that's certainly all I used it for. Since completing Week 5 (and the final week of C), I now understand that dictionaries are actually hash tables and a very efficient way of indexing and searching for data. As a result, I now use a wider variety of data structures to achieve my goals, now that I know what the purpose of them is.

With that greater understanding of data structures also came a better understanding of how to solve different problems. This revelation was kind of like using a rock to drive a nail and then being handed a hammer. 

As I progressed through the course, I found myself recommending CS50 more and more to people learning to code. I found quite a few of the people that were more advanced in their self-teaching resisted the idea quite a lot and it's another one of those interesting parallels I found with learning to draw. I went into CS50 with probably almost 20 years of learning to code (or trying to) behind me, but I tried to put all of that aside and assume I knew nothing. As it turned out, I knew way less than I thought I did and again, I had this same experience with Drawabox and learning to draw (much harder to put aside my pride there). 

One thing I didn't end up writing an article about during my CS50 journey was the specialist track that I chose. As you might know, Week 8 splits out into three tracks - web, app, or game development. I immediately ruled out web development since I'd been doing that since I was a child. I leaned heavily towards app development for a time but because I only use an iPhone and my Macbook is getting a bit old and slow, I didn't really want to be stuck coding on it. So I opted for the game development track. This track sees you create a Pong and Mario-esque game from scratch using Lua's game engine LÖVE.

I really enjoyed the Pong exercise, I was able to follow along with all the videos and write my own game and by the end I understood it well enough that I immediately saw how to solve the problem that was set - create an AI controlled player. I didn't enjoy the Mario exercise so much since it seemed to skim over a lot of the building of the game, which meant I had to download distribution code to finish the exercise - which was to procedurally generate a flag at the end of the level and restart or end the game once the character passed the flag. I managed to do this but it was nowhere near as elegant as I would've hoped. 

In the end, I don't think I'm that interested in pursuing games development but it was definitely an interesting insight into how games are created and how programmers push for modularity in them so that the codebase doesn't get ridiculously large. I think one of the reasons I didn't like it was because Lua is such an odd language - its only data structure is called a table and it's one-indexed (unlike most languages that are zero-indexed). There's a few other quirks that just make it kind of unpleasant to use, though that said, I didn't have trouble with the language itself as CS50 had provided me with the fundamental concepts I needed to adapt to the language.

For my final project, I opted to create a Discord bot for a small community of artists that formed around drawing every day on the Drawabox Discord server. There's a roadmap for the bot that includes time logging and goal setting capabilities however for the moment it functions as a streak counter with users able to run a daily command to increment their streak as well as personal bests and leaderboards. The bot is implemented using the Discord.py library and a MySQL backend. Whilst I've created similar kinds of coding projects before (such as this task tracker), I'd always reached a point where the level of complexity outweighed my ability to execute. In the case of this bot however, I spent quite a lot of time thinking over the implementation details, creating several Trello cards, and rubber ducking that I never felt like I was out of my depth. Finally being able to understand what I was doing and where I was going with a project was a huge turning point for me.

Overall, I cannot state enough how much this course has helped me. Learning C might not sound appealing to you, but it's not about the language, it's about learning how things work underneath the hood and you'll probably never have to use it again once you understand those concepts.

If you're looking for a course that will teach you how to code, regardless of the programming language or if you're looking to fill in gaps in your foundational knowledge. Take CS50. It's the best thing you can do to get you started off right.