I started learning Python with CS50 Harvard's Introduction to Programming with Python and honestly, it wasn't part of some grand plan. I've tried a few scattered tutorials before, the kind that show you print("hello world") and then jump straight into building an app three minutes later, leaving me more confused than when you started. CS50 was different. It's completely free on YouTube, taught by David Malan, and it felt less like a tutorial and more like actually sitting in a real classroom mistakes, live debugging, audience questions and all.
This post is my personal walk-through of the course, week by week, topic by topic. Not a syllabus copy-paste just what each concept actually felt like to learn, where I got stuck, and what finally made things click. If you're thinking about starting CS50 yourself, I hope this gives you an honest picture of the road ahead.
Functions and Variables Where I Actually Started
The first lecture is where I learned that a "function" is basically an action, and a "variable" is just a labeled box for storing something. That sounds simple written out like that, but sitting there for the first time, even print() and input() felt like a small victory.
def main():
name = input("What's your name? ")
hello(name)
def hello(name):
print(f"hello, {name}")
main()
Enter fullscreen mode Exit fullscreen mode
I remember writing my own function for the first time and feeling like I'd unlocked something. It wasn't just about using tools someone else built I was building my own small piece of logic, even if it was tiny.
Conditionals My First "Aha" Moment
Conditionals were the first time programming started to feel like actual thinking instead of memorizing syntax. if, elif, else suddenly my code could react to different situations instead of just running the same way every time.
if(n%4 == 0 and n % 100 != 0 or n % 400 == 0):
print("This is a leapYear")
else:
print("This is not a leapYear")
Enter fullscreen mode Exit fullscreen mode
I'll be honest, I messed up indentation more times than I'd like to admit here. But this was the week I stopped seeing Python as "commands to memorize" and started seeing it as logic I could actually reason through.
Loops When Things Started Feeling Powerful
Loops were the point where I realized I didn't have to write the same line of code ten times if I wanted something to happen ten times. for loops and while loops felt like a genuine upgrade in what I could build.
for i in range(a):
i+=1
print("*" * i)
a -=1
Enter fullscreen mode Exit fullscreen mode
Combining loops with the conditionals I'd just learned was a turning point for me I could suddenly validate input until it was correct, or repeat something until a condition was met. It felt like my toolkit had doubled overnight.
Exceptions Learning to Expect Failure
I used to think errors meant I'd done something wrong and needed to panic. This week reframed that completely. try and except taught me that errors are something you plan for, not something you're supposed to avoid entirely.
def withdraw(balance,amount):
try:
if amount > balance:
raise NameError("Insufficient Balance")
print(f"Get your amount {amount}")
except NameError:
print("Inssuficient Balance")
Enter fullscreen mode Exit fullscreen mode
This was a genuine mindset shift for me from "my code is broken" to "my code needs to handle the moment it breaks."
Libraries Realizing I Didn't Have to Build Everything
I remember feeling almost relieved during this week. I didn't have to reinvent the wheel every time I needed something Python's standard library and third-party packages already had solutions for most common problems.
import csv
Enter fullscreen mode Exit fullscreen mode
This was also the week I learned to actually read documentation instead of guessing. It's a skill nobody tells you is a "programming skill," but it absolutely is.
Unit Tests The Week I Started Taking My Code Seriously
Before this, I'd just run my code and squint at the output to see if it "looked right." Learning pytest and writing actual assertions changed how I thought about my own work.
Writing my first test felt oddly satisfying like I was finally proving something instead of just hoping it worked.
File I/O Making My Programs Remember Things
Up until this point, everything I built forgot itself the second I closed the program. Learning to read and write files felt like giving my code a memory for the first time.
import csv
name = input("Enter student name: ")
home = input("Enter home address: ")
with open("students.csv","a") as file:
writer = csv.DictWriter(file,fieldnames=["name","home"])
writer.writerow({"name":name,"home":home})
Enter fullscreen mode Exit fullscreen mode
This is also where I learned about the with keyword, and honestly, understanding why it matters (safely closing files automatically) took me longer than actually using it correctly.
Regular Expressions this Week That Humbled Me
I won't pretend this one was easy. Regular expressions felt like learning a second, stranger language stacked on top of Python. Validating something like an email address suddenly required this dense string of symbols that looked like nonsense at first glance.
import re
if re.search(r"^\w+@\w+\.(com|edu|gov|net)$",email,re.IGNORECASE): # \w any word character
print("Email Address is valid")
else:
print("Email Address is invalid")
Enter fullscreen mode Exit fullscreen mode
It took rewatching parts of this lecture more than once for it to sink in. If you find regex confusing at first, I can tell you from experience that's a completely normal reaction, not a sign you're behind.
Object-Oriented Programming Where Everything Finally Connected
By the time I reached OOP, something clicked. Classes let me bundle variables and functions together into something that actually resembled a real-world "thing" instead of scattered logic everywhere.
class Student:
def __init__(self, name, house, pet,age=None):
self.name = name
self.house = house
self.age = age
self.pet = pet
def __str__(self):
return f"{self.name} from {self.house} is {self.age}"
@property
def name(self):
return self._name
@name.setter
def name(self,name):
if not name:
raise ValueError("Student name cannot be empty")
self._name = name
# Getter
@property # to tell python to treat this as a getter
def house(self):
return self._house
# Setter
@house.setter #to tell python this is a setter
def house(self, house):
if house not in ["Lagos", "Ikoyi", "Yaba"]:
raise ValueError("Invalid house")
self._house = house
Enter fullscreen mode Exit fullscreen mode
This was the week I looked back and realized how much everything before it had been building toward this moment. Functions became methods. Variables became attributes. Exceptions and testing suddenly applied to something bigger and more "real" than anything I'd written earlier in the course.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.