Day 13: OOP....

Hello, fellow learner!!👋
📝 Note from Me
Hey everyone, thank you so much for following my daily journey. I want to address the slight delay in this post. Yesterday, I dove deep into Python’s Object-Oriented Programming and honestly, it deserved more than a surface-level explanation. I didn’t just want to understand it—I wanted to own it. That meant late-night coding, revisiting concepts multiple times, and building mini prototypes to test how everything fits together. That’s why I’m publishing this today. I’d rather be a day late with depth than on time with fluff. This blog was generated with the help of AI because I did not have any time to write it down but it covers everything I would have written anyways… so follow along!!
Let’s explore one of the most powerful programming paradigms in Python: Object-Oriented Programming.
🔹 What is Object-Oriented Programming?
Object-Oriented Programming (OOP) is a coding paradigm based on the concept of “objects”. These objects represent real-world entities like students, books, or bank accounts. Each object bundles both data (attributes) and functions (methods) that operate on that data.
If procedural programming is like a list of tasks to do, OOP is more like modeling a world full of interacting entities.
🔸 Why OOP Matters
Before I understood OOP, my code looked like a collection of functions floating around. But as projects grow, this gets chaotic.
OOP helps you:
Organize code better.
Make your programs modular and reusable.
Reduce bugs and duplication.
Model real-world systems more intuitively.
🔹 The Four Pillars of OOP
The core ideas behind OOP are based on four pillars:
Encapsulation.
Abstraction.
Inheritance.
Polymorphism.
Let’s break each down with explanations and examples.
🔸 1. Encapsulation – Bundling Data with Behavior
Encapsulation means keeping data (attributes) and the methods (functions) that act on the data together in one place: a class.
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def get_info(self):
return f"{self.title} by {self.author}"
my_book = Book("1984", "George Orwell")
print(my_book.get_info()) # Output: 1984 by George Orwell
🔍 Why It Matters
The internal structure is hidden and protected.
Makes your program less error-prone.
Easier to maintain and debug.
🔸 2. Abstraction – Hiding Complexity
Abstraction means hiding internal implementation details and showing only the essential features to the user.
Think of driving a car. You don’t need to know how the engine works to drive it. You just use the steering wheel, pedals, and gears.
class Engine:
def start(self):
return "Engine is starting..."
class Car:
def __init__(self):
self.engine = Engine()
def drive(self):
return f"{self.engine.start()} Car is now driving."
my_car = Car()
print(my_car.drive())
You interact with the Car
, not with the inner Engine
.
🔸 3. Inheritance – Reusing Code
Inheritance lets you create a new class by reusing properties and methods from an existing class.
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Bark!"
class Cat(Animal):
def speak(self):
return "Meow!"
a = Animal()
d = Dog()
c = Cat()
print(a.speak()) # Some sound
print(d.speak()) # Bark!
print(c.speak()) # Meow!
✅ Benefits:
Less duplication.
Easier to add new features.
Keeps your code DRY (Don't Repeat Yourself).
🔸 4. Polymorphism – Many Forms, One Interface
Polymorphism allows methods with the same name to behave differently based on the object that calls them.
def animal_speak(animal):
print(animal.speak())
animal_speak(Dog()) # Bark!
animal_speak(Cat()) # Meow!
This makes your code more flexible and easier to scale.
🧠 OOP in Practice – Building a Real-World Example
Let’s build a mini student management system using OOP principles.
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def get_grade(self):
return self.grade
class Course:
def __init__(self, name, max_students):
self.name = name
self.max_students = max_students
self.students = []
def add_student(self, student):
if len(self.students) < self.max_students:
self.students.append(student)
return True
return False
def average_grade(self):
if not self.students:
return 0
total = sum([student.get_grade() for student in self.students])
return total / len(self.students)
s1 = Student("Alice", 95)
s2 = Student("Bob", 80)
course = Course("Math", 2)
course.add_student(s1)
course.add_student(s2)
print(course.average_grade()) # Output: 87.5
Concepts Used:
__init__
(constructor).Class attributes and methods.
Object creation.
Method calls and return values.
List of objects.
📚 More Advanced Concepts in OOP
🔸 1. Class vs. Instance Variables:
class Dog:
species = "Canis familiaris" # Class variable
def __init__(self, name):
self.name = name # Instance variable
d1 = Dog("Fido")
d2 = Dog("Buddy")
print(d1.species) # Canis familiaris
🔸 2. Static Methods & Class Methods:
class Calculator:
@staticmethod
def add(x, y):
return x + y
@classmethod
def description(cls):
return f"This is a {cls.__name__} class."
print(Calculator.add(5, 6)) # 11
print(Calculator.description()) # This is a Calculator class.
🔸 3. Dunder (Magic) Methods:
These are methods with double underscores like __init__
, __str__
, __len__
.
class Book:
def __init__(self, title):
self.title = title
def __str__(self):
return f"Book: {self.title}"
b = Book("Atomic Habits")
print(b) # Book: Atomic Habits
🔂 Composition vs. Inheritance:
Inheritance is “is a” relationship (e.g., Dog is an Animal).
Composition is “has a” relationship (e.g., Car has an Engine).
Composition is often preferred for flexibility.
class Engine:
def start(self):
return "Engine on"
class Car:
def __init__(self):
self.engine = Engine()
def run(self):
return self.engine.start()
🔄 Common Pitfalls in OOP
Overusing inheritance instead of composition.
Forgetting
self
in methods.Making everything a class when functions would do.
Not using private variables (
_var
or__var
) for encapsulation.
💡 Tips to Master OOP
Think about objects in real life: car, book, bank account.
Start by identifying nouns (objects) and verbs (methods) in your problem.
Code it first with functions, then refactor using classes.
Review and reuse your class-based code in other projects.
📦 Mini Project: Task Tracker
Try building a task manager using OOP. Here’s a small starting point:
class Task:
def __init__(self, title, status="Incomplete"):
self.title = title
self.status = status
def mark_complete(self):
self.status = "Complete"
class TaskManager:
def __init__(self):
self.tasks = []
def add_task(self, task):
self.tasks.append(task)
def show_tasks(self):
for task in self.tasks:
print(f"{task.title} - {task.status}")
# Example
t1 = Task("Learn OOP")
t2 = Task("Do SAT Math")
tm = TaskManager()
tm.add_task(t1)
tm.add_task(t2)
t1.mark_complete()
tm.show_tasks()
🧭 Reflection
Today I feel like I unlocked a new way of thinking about code.
OOP isn’t just about using classes—it’s about organizing your thoughts. It’s a powerful habit that improves everything from clarity to reusability.
I can now take almost any real-world scenario and map it into classes and methods. From games and simulations to tools and web apps, OOP is going to be at the heart of every major project I build going forward.
📌 What’s Next?
In Day 14, I’ll be covering SAT Math with a strong focus on:
Algebra and equations
Graphing functions
Advanced math
Geometry and data analysis
Subscribe to my newsletter
Read articles from Saharsh Boggarapu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Saharsh Boggarapu
Saharsh Boggarapu
I’m Saharsh, 15, starting from scratch with one goal in mind—building AGI. I’m teaching myself Python and AI from scratch, and everything I discover along the process—mistakes, epiphanies, everything—will be shared here. I’m very interested in math and physics, and I enjoy solving problems that challenge my brain to its limits. This project isn't just about me—it's about everyone who has dreams but has no idea where to begin. If you're curious, ambitious, or just beginning like I am, stick with it. We'll discover, we'll develop, and perhaps we can even revolutionize the world.