Week 9 of 16

Watch: OOP Fundamentals

Your prompts are about to become objects — things that know how to take care of themselves.

Day 41 75 minutes Watch

Day 41 of 80

The Shift in Thinking

Until now, a prompt in your Vault was just a dictionary:

{"platform": "Kling", "shot": "aerial shot", "prompt": "Wide drone..."}

A dictionary is just a bag of data. It doesn't know how to do anything. If you want to format a prompt, or validate a platform name, or get a preview — you write functions somewhere else that operate on the dictionary. The data and the behavior are separate.

This week, a prompt becomes an object:

p = Prompt(platform="Kling", shot="aerial shot", prompt_text="Wide drone...")
print(p)          # knows how to describe itself
p.preview()       # knows how to truncate itself
p.to_dict()       # knows how to serialize itself

The data and the behavior live together. That's the core idea of Object-Oriented Programming.

Today's Videos

These three videos by Corey Schafer are the gold standard for learning Python OOP. Watch them in order. Take notes.

# Video Duration Key concept
1 Classes and Instances ~15 min What a class is, creating instances, the __init__ method
2 Class Variables ~12 min Difference between class variables and instance variables
3 Classmethods and Staticmethods ~15 min @classmethod as an alternative constructor, @staticmethod as a utility

The self Mystery Solved

Before you watch, here's the one thing that confuses everyone at first:

What self Actually Is

When you call a method on an object like this:

p.preview()

Python rewrites it behind the scenes to:

Prompt.preview(p)

The object p is passed as the first argument. That argument — whatever you call it — is conventionally named self. It's not magic. It's just Python's way of saying "this method needs to know which object it's working on."

self — a concrete example Python
class Prompt:
    def __init__(self, platform, shot):
        # self IS the new object being created
        # Assign values to it with dot notation
        self.platform = platform   # instance variable
        self.shot = shot           # instance variable

    def describe(self):
        # self is the specific Prompt this method was called on
        return f"{self.platform}: {self.shot}"


# Create two separate instances
p1 = Prompt("Kling", "aerial shot")
p2 = Prompt("Runway", "close-up")

print(p1.describe())  # Kling: aerial shot
print(p2.describe())  # Runway: close-up
# Same method, different results — because self is different each time

Instance variables (set via self.x = ...) belong to one specific object. Every Prompt you create has its own platform, its own shot.

__init__ is not a constructor in the C++ sense — the object already exists when __init__ runs. It's an initializer. Its job is to set up the object's starting state.

Blueprint vs Instance

The Most Important Analogy in OOP

A class is a blueprint. It defines the structure and behavior. No actual object exists yet.

An instance is a specific object built from that blueprint. You can build as many instances as you want from the same class, each with different data.

Think of it this way: Prompt is the concept of "a prompt." p1 and p2 are specific prompts. The class describes what all prompts have in common. The instances hold the actual values.

Blueprint vs Instances Python
# The class — the blueprint (exists once)
class Prompt:
    VALID_PLATFORMS = ["Kling", "Runway", "Veo"]  # class variable: shared by all

    def __init__(self, platform, shot):
        self.platform = platform  # instance variable: unique to each object
        self.shot = shot

# Instances — each built from the blueprint (can exist many)
aerial = Prompt("Kling", "aerial over mountains")
closeup = Prompt("Runway", "close-up of hands")
drone = Prompt("Veo", "drone through forest")

# All three share the class variable
print(Prompt.VALID_PLATFORMS)  # ["Kling", "Runway", "Veo"]

# But each has its own instance variable
print(aerial.platform)   # "Kling"
print(closeup.platform)  # "Runway"

Class variables (like VALID_PLATFORMS) are defined in the class body, outside any method. They're shared by every instance — change one, change all. Good for constants and shared state.

Instance variables (set in __init__ via self) are unique to each object. Changing aerial.platform doesn't affect closeup.platform.

Preview: What You'll Build This Week

The Prompt Class — Coming in Day 43

By Day 43, you'll replace every raw dictionary in your Prompt Vault with a proper Prompt object. Here's a sneak peek at what the finished class looks like from a user's perspective:

# Creating a Prompt
p = Prompt(platform="Kling", shot="wide aerial", prompt_text="A sweeping drone shot...")

# It knows how to describe itself
print(p)         # [Kling] wide aerial

# It knows how to preview itself
p.preview()     # "A sweeping drone shot..."  (truncated at 80 chars)

# It validates its own platform on creation
Prompt(platform="Midjourney", ...)  # raises ValueError immediately

# It can serialize itself for JSON storage
p.to_dict()     # returns the dictionary for json.dump()

# It can be rebuilt from a dictionary
p2 = Prompt.from_dict(data)  # classmethod — alternative constructor

Every one of these capabilities requires something from today's videos: __init__, class variables, @classmethod. Watch carefully.

End of Day Checklist

Tomorrow

Day 42 covers inheritance and special (dunder) methods — __str__, __repr__, __len__. Another watch day. By Day 43 you'll have everything you need to build the full Prompt class.