Creating a User without a name makes no sense. The __init__ method is Python's constructor - it runs automatically when you create an object, letting you require and validate data from the start.

Basic constructor

Initialize objects with required data.

basic_init.py
Replay: real traced execution (multi-file project)
# Basic __init__ Constructor

print("=== Basic Constructor ===\n")

class Dog:
    def __init__(self, name, breed):
        print(f"Creating dog: {name}, {breed}")
        self.name = name
        self.breed = breed

# Create dogs - __init__ called automatically
buddy = Dog("Buddy", "Golden Retriever")
max_dog = Dog("Max", "German Shepherd")

print(f"\nbuddyname: {buddy.name}, breed: {buddy.breed}")
print(f"max name: {max_dog.name}, breed: {max_dog.breed}")

print("\n=== Without Constructor ===")

class EmptyClass:
    pass

# Can still create but no initialization
obj = EmptyClass()
print(f"Empty object: {obj}")

# Must add attributes manually
obj.value = 42
print(f"After manual: {obj.value}")

print("\n=== Constructor vs Manual ===")

# With constructor - guaranteed state
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)  # Always has x and y
print(f"Point: ({p.x}, {p.y})")

# Without - inconsistent state
class BadPoint:
    pass

bp = BadPoint()
bp.x = 3
# Forgot to set y!
# print(bp.y)  # Would raise AttributeError

print("\n=== Multiple Parameters ===")

class Rectangle:
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height

    def describe(self):
        return f"Rectangle at ({self.x},{self.y}) size {self.width}x{self.height}"

rect = Rectangle(10, 20, 100, 50)
print(rect.describe())
  1. print("=== Basic Constructor === ")

    3print("=== Basic Constructor ===\n")45class Dog:6    def __init__(self, name, breed):  #?init7        print(f"Creating dog: {name}, {breed}")  #?debug8        self.name = name  #?setattr9        self.breed = breed1011# Create dogs - __init__ called automatically  #?createcall12buddy = Dog("Buddy", "Golden Retriever")  #?passargs13max_dog = Dog("Max", "German Shepherd")
    output=== Basic Constructor ===
  2. self.name ← Buddy, self.breed ← Golden Retriever

    pass 1 of 2
    5class Dog:6    def __init__(self⟨Dog A⟩, nameBuddy, breedGolden Retriever):  #?init7        print(f"Creating dog: {nameBuddy}, {breedGolden Retriever}")  #?debug8        self.name→ Buddy = nameBuddy  #?setattr9        self.breed→ Golden Retriever = breedGolden Retriever
    outputCreating dog: Buddy, Golden Retriever
  3. buddy ← ⟨Dog A⟩

    11# Create dogs - __init__ called automatically  #?createcall12buddy→ ⟨Dog A⟩ = Dog("Buddy", "Golden Retriever")  #?passargs13max_dog = Dog("Max", "German Shepherd")
  4. self.name ← Max, self.breed ← German Shepherd

    pass 2 of 2
    5class Dog:6    def __init__(self⟨Dog B⟩, nameMax, breedGerman Shepherd):  #?init7        print(f"Creating dog: {nameMax}, {breedGerman Shepherd}")  #?debug8        self.name→ Max = nameMax  #?setattr9        self.breed→ German Shepherd = breedGerman Shepherd
    outputCreating dog: Max, German Shepherd
  5. max_dog ← ⟨Dog B⟩, obj ← ⟨EmptyClass C⟩, obj.value ← 42

    12buddy = Dog("Buddy", "Golden Retriever")  #?passargs13max_dog→ ⟨Dog B⟩ = Dog("Max", "German Shepherd")1415print(f"\nbuddyname: {buddy.nameBuddy}, breed: {buddy.breedGolden Retriever}")16print(f"max name: {max_dog.nameMax}, breed: {max_dog.breedGerman Shepherd}")1718print("\n=== Without Constructor ===")1920class EmptyClass:  #?empty21    pass2223# Can still create but no initialization24obj→ ⟨EmptyClass C⟩ = EmptyClass()25print(f"Empty object: {obj⟨EmptyClass C⟩}")2627# Must add attributes manually  #?manual28obj.value→ 42 = 4229print(f"After manual: {obj.value42}")3031print("\n=== Constructor vs Manual ===")3233# With constructor - guaranteed state  #?guaranteed34class Point:35    def __init__(self, x, y):36        self.x = x37        self.y = y3839p = Point(3, 4)  # Always has x and y40print(f"Point: ({p.x}, {p.y})")
    output
    buddyname: Buddy, breed: Golden Retriever
    max name: Max, breed: German Shepherd
    
    === Without Constructor ===
    Empty object: ⟨EmptyClass C⟩
    After manual: 42
    
    === Constructor vs Manual ===
  6. self.x ← 3, self.y ← 4

    34class Point:35    def __init__(self⟨Point D⟩, x3, y4):36        self.x→ 3 = x337        self.y→ 4 = y4
  7. p ← ⟨Point D⟩, bp ← ⟨BadPoint E⟩, bp.x ← 3

    39p→ ⟨Point D⟩ = Point(3, 4)  # Always has x and y40print(f"Point: ({p.x3}, {p.y4})")4142# Without - inconsistent state  #?inconsistent43class BadPoint:44    pass4546bp→ ⟨BadPoint E⟩ = BadPoint()47bp.x→ 3 = 348# Forgot to set y!49# print(bp.y)  # Would raise AttributeError5051print("\n=== Multiple Parameters ===")5253class Rectangle:54    def __init__(self, x, y, width, height):  #?multiparams55        self.x = x56        self.y = y57        self.width = width58        self.height = height59    60    def describe(self):61        return f"Rectangle at ({self.x},{self.y}) size {self.width}x{self.height}"6263rect = Rectangle(10, 20, 100, 50)64print(rect.describe())
    outputPoint: (3, 4)
    
    === Multiple Parameters ===
  8. self.x ← 10, self.y ← 20, self.width ← 100, self.height ← 50

    53class Rectangle:54    def __init__(self⟨Rectangle F⟩, x10, y20, width100, height50):  #?multiparams55        self.x→ 10 = x1056        self.y→ 20 = y2057        self.width→ 100 = width10058        self.height→ 50 = height50
  9. rect ← ⟨Rectangle F⟩

    63rect→ ⟨Rectangle F⟩ = Rectangle(10, 20, 100, 50)64print(rect⟨Rectangle F⟩.describe())65#@help init
  10. def describe(self):

    60def describe(self⟨Rectangle F⟩):61    return f"Rectangle at ({self.x10},{self.y20}) size {self.width100}x{self.height50}"
  11. print(rect.describe())

    63rect = Rectangle(10, 20, 100, 50)64print(rect⟨Rectangle F⟩.describe())65#@help init
    outputRectangle at (10,20) size 100x50

__init__ runs when object is created. Sets up initial state.

__init__ Constructor method. Called automatically with `new Object()` in Python: `ClassName()`.

Default parameter values

Make some parameters optional.

default_values.py
Replay: real traced execution (multi-file project)
# Default Values in Constructors

print("=== Default Parameter Values ===\n")

class User:
    def __init__(self, username, role="user", active=True):
        self.username = username
        self.role = role
        self.active = active

    def describe(self):
        status = "active" if self.active else "inactive"
        return f"{self.username} ({self.role}, {status})"

# Different ways to create
admin = User("admin", "administrator", True)  # All explicit
alice = User("alice", "editor")  # Default active
bob = User("bob")  # All defaults

print(admin.describe())
print(alice.describe())
print(bob.describe())

print("\n=== Named Arguments ===")

# Use named args to skip defaults
guest = User("guest", active=False)  # Skip role
print(guest.describe())

# Mix positional and named
mod = User("mod", role="moderator")
print(mod.describe())

print("\n=== Mutable Default Values ===")

# WRONG - Shared mutable default!
class BadList:
    def __init__(self, items=[]):
        self.items = items

bad1 = BadList()
bad2 = BadList()
bad1.items.append("item1")
print(f"bad1.items: {bad1.items}")
print(f"bad2.items: {bad2.items}")  # Also has item1!

print("\n=== Correct Pattern for Mutables ===")

# CORRECT - Use None and create new list
class GoodList:
    def __init__(self, items=None):
        self.items = items if items else []

good1 = GoodList()
good2 = GoodList()
good1.items.append("item1")
print(f"good1.items: {good1.items}")
print(f"good2.items: {good2.items}")  # Empty - correct!

print("\n=== Default with Various Types ===")

class GameCharacter:
    def __init__(self, name, health=100, inventory=None,
                 position=None, multiplier=1.0):
        self.name = name
        self.health = health
        self.inventory = inventory if inventory else []
        self.position = position if position else {"x": 0, "y": 0}
        self.multiplier = multiplier

# Create with defaults
hero = GameCharacter("Hero")
print(f"{hero.name}: health={hero.health}, pos={hero.position}")
print(f"Inventory: {hero.inventory}")

# Create with custom values
wizard = GameCharacter("Wizard", 80, ["staff", "spellbook"],
                       {"x": 10, "y": 5}, 1.5)
print(f"\n{wizard.name}: health={wizard.health}, pos={wizard.position}")
print(f"Inventory: {wizard.inventory}")
  1. print("=== Default Parameter Values === ")

    3print("=== Default Parameter Values ===\n")45class User:6    def __init__(self, username, role="user", active=True):  #?defaults7        self.username = username8        self.role = role9        self.active = active10    11    def describe(self):12        status = "active" if self.active else "inactive"13        return f"{self.username} ({self.role}, {status})"1415# Different ways to create  #?createways16admin = User("admin", "administrator", True)  # All explicit  #?allexplicit17alice = User("alice", "editor")  # Default active  #?partialdefault
    output=== Default Parameter Values ===
  2. self.username ← admin, self.role ← administrator, self.active ← True

    pass 1 of 5
    5class User:6    def __init__(self⟨User A⟩, usernameadmin, roleadministrator="user", activeTrue=TrueTrue):  #?defaults7        self.username→ admin = usernameadmin8        self.role→ administrator = roleadministrator9        self.active→ True = activeTrue
    All 5 passes — pass 1 is the card above
    passselfusernameroleactiveself.usernameself.roleself.active
    1⟨User A⟩adminadministratorTrueadminadministratorTrue
    2⟨User B⟩aliceeditorTruealiceeditorTrue
    3⟨User C⟩bobuserTruebobuserTrue
    4⟨User D⟩guestuserFalseguestuserFalse
    5⟨User E⟩modmoderatorTruemodmoderatorTrue
  3. admin ← ⟨User A⟩

    15# Different ways to create  #?createways16admin→ ⟨User A⟩ = User("admin", "administrator", True)  # All explicit  #?allexplicit17alice = User("alice", "editor")  # Default active  #?partialdefault18bob = User("bob")  # All defaults  #?alldefaults
  4. alice ← ⟨User B⟩

    16admin = User("admin", "administrator", True)  # All explicit  #?allexplicit17alice→ ⟨User B⟩ = User("alice", "editor")  # Default active  #?partialdefault18bob = User("bob")  # All defaults  #?alldefaults
  5. bob ← ⟨User C⟩

    17alice = User("alice", "editor")  # Default active  #?partialdefault18bob→ ⟨User C⟩ = User("bob")  # All defaults  #?alldefaults1920print(admin⟨User A⟩.describe())21print(alice.describe())
  6. status ← active

    pass 1 of 5
    11def describe(self⟨User A⟩):12    status→ active = "active" if self.activeTrue else "inactive"13    return f"{self.usernameadmin} ({self.roleadministrator}, {statusactive})"
    All 5 passes — pass 1 is the card above
    passselfself.activeself.usernameself.rolestatus
    1⟨User A⟩Trueadminadministratoractive
    2⟨User B⟩Truealiceeditoractive
    3⟨User C⟩Truebobuseractive
    4⟨User D⟩Falseguestuserinactive
    5⟨User E⟩Truemodmoderatoractive
  7. print(admin.describe())

    20print(admin⟨User A⟩.describe())21print(alice⟨User B⟩.describe())22print(bob.describe())
    outputadmin (administrator, active)
  8. print(alice.describe())

    20print(admin.describe())21print(alice⟨User B⟩.describe())22print(bob⟨User C⟩.describe())
    outputalice (editor, active)
  9. print(bob.describe())

    21print(alice.describe())22print(bob⟨User C⟩.describe())2324print("\n=== Named Arguments ===")2526# Use named args to skip defaults  #?namedargs27guest = User("guest", active=False)  # Skip role  #?skiparg28print(guest.describe())
    outputbob (user, active)
    
    === Named Arguments ===
  10. guest ← ⟨User D⟩

    26# Use named args to skip defaults  #?namedargs27guest→ ⟨User D⟩ = User("guest", active=False)  # Skip role  #?skiparg28print(guest⟨User D⟩.describe())
  11. print(guest.describe())

    27guest = User("guest", active=False)  # Skip role  #?skiparg28print(guest⟨User D⟩.describe())2930# Mix positional and named  #?mixargs31mod = User("mod", role="moderator")32print(mod.describe())
    outputguest (user, inactive)
  12. mod ← ⟨User E⟩

    30# Mix positional and named  #?mixargs31mod→ ⟨User E⟩ = User("mod", role="moderator")32print(mod⟨User E⟩.describe())
  13. print(mod.describe())

    31mod = User("mod", role="moderator")32print(mod⟨User E⟩.describe())3334print("\n=== Mutable Default Values ===")3536# WRONG - Shared mutable default!  #?wrongmutable37class BadList:38    def __init__(self, items=[]):  #?baddefault39        self.items = items4041bad1 = BadList()42bad2 = BadList()
    outputmod (moderator, active)
    
    === Mutable Default Values ===
  14. self.items ← []

    pass 1 of 2
    37class BadList:38    def __init__(self⟨BadList F⟩, items[]=[]):  #?baddefault39        self.items→ [] = items[]
  15. bad1 ← ⟨BadList F⟩

    41bad1→ ⟨BadList F⟩ = BadList()42bad2 = BadList()43bad1.items.append("item1")
  16. self.items ← []

    pass 2 of 2
    37class BadList:38    def __init__(self⟨BadList G⟩, items[]=[]):  #?baddefault39        self.items→ [] = items[]
  17. bad2 ← ⟨BadList G⟩, bad1.items ← ['item1']

    41bad1 = BadList()42bad2→ ⟨BadList G⟩ = BadList()43bad1.items→ ['item1'].append("item1")44print(f"bad1.items: {bad1.items['item1']}")45print(f"bad2.items: {bad2.items['item1']}")  # Also has item1!  #?sharedlist4647print("\n=== Correct Pattern for Mutables ===")4849# CORRECT - Use None and create new list  #?correctmutable50class GoodList:51    def __init__(self, items=None):  #?nonedefault52        self.items = items if items else []  #?createlist5354good1 = GoodList()55good2 = GoodList()
    outputbad1.items: ['item1']
    bad2.items: ['item1']
    
    === Correct Pattern for Mutables ===
  18. self.items ← []

    pass 1 of 2
    50class GoodList:51    def __init__(self⟨GoodList H⟩, itemsNone=NoneNone):  #?nonedefault52        self.items→ [] = itemsNone if items else []  #?createlist
  19. good1 ← ⟨GoodList H⟩

    54good1→ ⟨GoodList H⟩ = GoodList()55good2 = GoodList()56good1.items.append("item1")
  20. self.items ← []

    pass 2 of 2
    50class GoodList:51    def __init__(self⟨GoodList I⟩, itemsNone=NoneNone):  #?nonedefault52        self.items→ [] = itemsNone if items else []  #?createlist
  21. good2 ← ⟨GoodList I⟩, good1.items ← ['item1']

    54good1 = GoodList()55good2→ ⟨GoodList I⟩ = GoodList()56good1.items→ ['item1'].append("item1")57print(f"good1.items: {good1.items['item1']}")58print(f"good2.items: {good2.items[]}")  # Empty - correct!5960print("\n=== Default with Various Types ===")6162class GameCharacter:63    def __init__(self, name, health=100, inventory=None, 64                 position=None, multiplier=1.0):  #?varioustypes65        self.name = name66        self.health = health67        self.inventory = inventory if inventory else []  #?safelist68        self.position = position if position else {"x": 0, "y": 0}  #?safedict69        self.multiplier = multiplier7071# Create with defaults72hero = GameCharacter("Hero")73print(f"{hero.name}: health={hero.health}, pos={hero.position}")
    outputgood1.items: ['item1']
    good2.items: []
    
    === Default with Various Types ===
  22. self.name ← Hero, self.health ← 100, self.inventory ← [], self.position ← {'x': 0, 'y': 0}

    pass 1 of 2
    62class GameCharacter:63    def __init__(self⟨GameCharacter J⟩, nameHero, health100=100, inventoryNone=NoneNone, 64                 positionNone=NoneNone, multiplier1.0=1.0):  #?varioustypes65        self.name→ Hero = nameHero66        self.health→ 100 = health10067        self.inventory→ [] = inventoryNone if inventory else []  #?safelist68        self.position→ {'x': 0, 'y': 0} = positionNone if position else {"x": 0, "y": 0}  #?safedict69        self.multiplier→ 1.0 = multiplier1.0
  23. hero ← ⟨GameCharacter J⟩

    71# Create with defaults72hero→ ⟨GameCharacter J⟩ = GameCharacter("Hero")73print(f"{hero.nameHero}: health={hero.health100}, pos={hero.position{'x': 0, 'y': 0}}")74print(f"Inventory: {hero.inventory[]}")7576# Create with custom values77wizard = GameCharacter("Wizard", 80, ["staff", "spellbook"], 78                       {"x": 10, "y": 5}, 1.5)79print(f"\n{wizard.name}: health={wizard.health}, pos={wizard.position}")
    outputHero: health=100, pos={'x': 0, 'y': 0}
    Inventory: []
  24. self.name ← Wizard, self.health ← 80, self.inventory ← ['staff', 'spellbook']

    pass 2 of 2
    62class GameCharacter:63    def __init__(self⟨GameCharacter K⟩, nameWizard, health80=100, inventory['staff', 'spellbook']=NoneNone, 64                 position{'x': 10, 'y': 5}=NoneNone, multiplier1.5=1.0):  #?varioustypes65        self.name→ Wizard = nameWizard66        self.health→ 80 = health8067        self.inventory→ ['staff', 'spellbook'] = inventory['staff', 'spellbook'] if inventory else []  #?safelist68        self.position→ {'x': 10, 'y': 5} = position{'x': 10, 'y': 5} if position else {"x": 0, "y": 0}  #?safedict69        self.multiplier→ 1.5 = multiplier1.5
  25. wizard ← ⟨GameCharacter K⟩

    76# Create with custom values77wizard→ ⟨GameCharacter K⟩ = GameCharacter("Wizard", 80, ["staff", "spellbook"], 78                       {"x": 10, "y": 5}, 1.5)79print(f"\n{wizard.nameWizard}: health={wizard.health80}, pos={wizard.position{'x': 10, 'y': 5}}")80print(f"Inventory: {wizard.inventory['staff', 'spellbook']}")81#@help defaults
    output
    Wizard: health=80, pos={'x': 10, 'y': 5}
    Inventory: ['staff', 'spellbook']

Parameters with defaults can be omitted: def __init__(self, name, age=0).

Validate input

Reject invalid data at creation time.

validation.py
Replay: real traced execution (multi-file project)
# Input Validation in Constructors

print("=== Validation with Errors ===\n")

class Age:
    def __init__(self, years):
        if not isinstance(years, int):
            raise TypeError("Age must be an integer")
        if years < 0:
            raise ValueError("Age cannot be negative")
        if years > 150:
            raise ValueError("Age cannot exceed 150")
        self.years = years

# Valid ages
age1 = Age(25)
age2 = Age(0)
print(f"Valid ages: {age1.years}, {age2.years}")

# Invalid ages (uncomment to see errors)
# Age("twenty")  # TypeError
# Age(-5)        # ValueError
# Age(200)       # ValueError

print("\n=== Validation with Correction ===")

class Username:
    def __init__(self, name):
        # Strip whitespace
        name = name.strip()

        # Convert to lowercase
        name = name.lower()

        # Validate length
        if len(name) < 3:
            raise ValueError("Username must be at least 3 characters")
        if len(name) > 20:
            name = name[:20]  # Truncate

        self.name = name

user1 = Username("  Alice  ")  # Whitespace removed
user2 = Username("BOB")  # Lowercased
user3 = Username("VeryLongUsernameThatExceedsLimit")  # Truncated

print(f"'{user1.name}'")
print(f"'{user2.name}'")
print(f"'{user3.name}' (len={len(user3.name)})")

print("\n=== Validation with Defaults ===")

class Temperature:
    def __init__(self, celsius):
        # Clamp to valid range
        if celsius < -273.15:  # Absolute zero
            print(f"Warning: {celsius} adjusted to -273.15")
            celsius = -273.15
        self.celsius = celsius

    @property
    def fahrenheit(self):
        return self.celsius * 9/5 + 32

t1 = Temperature(25)
t2 = Temperature(-300)  # Adjusted

print(f"t1: {t1.celsius}°C")
print(f"t2: {t2.celsius}°C (was adjusted)")

print("\n=== Complex Validation ===")

class Email:
    def __init__(self, address):
        # Basic email validation
        address = address.strip().lower()

        if "@" not in address:
            raise ValueError("Email must contain @")

        parts = address.split("@")
        if len(parts) != 2:
            raise ValueError("Email must have exactly one @")

        local, domain = parts

        if not local:
            raise ValueError("Email must have local part")
        if not domain or "." not in domain:
            raise ValueError("Email must have valid domain")

        self.address = address
        self.local = local
        self.domain = domain

email = Email("  User@Example.COM  ")
print(f"Address: {email.address}")
print(f"Local: {email.local}, Domain: {email.domain}")

print("\n=== Validation Summary ===")

class Product:
    def __init__(self, name, price, quantity=0):
        # Name validation
        if not name or not name.strip():
            raise ValueError("Product name cannot be empty")
        self.name = name.strip()

        # Price validation
        if not isinstance(price, (int, float)):
            raise TypeError("Price must be a number")
        if price < 0:
            raise ValueError("Price cannot be negative")
        self.price = round(price, 2)  # Round to cents

        # Quantity validation
        if not isinstance(quantity, int):
            raise TypeError("Quantity must be an integer")
        if quantity < 0:
            quantity = 0  # Auto-correct
        self.quantity = quantity

laptop = Product("  Laptop  ", 999.999, 5)
print(f"Product: {laptop.name}, ${laptop.price}, qty={laptop.quantity}")
  1. print("=== Validation with Errors === ")

    3print("=== Validation with Errors ===\n")45class Age:6    def __init__(self, years):7        if not isinstance(years, int):  #?typecheck8            raise TypeError("Age must be an integer")9        if years < 0:  #?rangecheck10            raise ValueError("Age cannot be negative")11        if years > 150:12            raise ValueError("Age cannot exceed 150")13        self.years = years  #?setvalid1415# Valid ages16age1 = Age(25)17age2 = Age(0)
    output=== Validation with Errors ===
  2. self.years ← 25

    pass 1 of 2
    5class Age:6    def __init__(self⟨Age A⟩, years25):7        if not isinstance(years, int):  #?typecheck8            raise TypeError("Age must be an integer")9        if years < 0:  #?rangecheck10            raise ValueError("Age cannot be negative")11        if years > 150:12            raise ValueError("Age cannot exceed 150")13        self.years→ 25 = years25  #?setvalid
  3. age1 ← ⟨Age A⟩

    15# Valid ages16age1→ ⟨Age A⟩ = Age(25)17age2 = Age(0)18print(f"Valid ages: {age1.years}, {age2.years}")
  4. self.years ← 0

    pass 2 of 2
    5class Age:6    def __init__(self⟨Age B⟩, years0):7        if not isinstance(years, int):  #?typecheck8            raise TypeError("Age must be an integer")9        if years < 0:  #?rangecheck10            raise ValueError("Age cannot be negative")11        if years > 150:12            raise ValueError("Age cannot exceed 150")13        self.years→ 0 = years0  #?setvalid
  5. age2 ← ⟨Age B⟩

    16age1 = Age(25)17age2→ ⟨Age B⟩ = Age(0)18print(f"Valid ages: {age1.years25}, {age2.years0}")1920# Invalid ages (uncomment to see errors)21# Age("twenty")  # TypeError22# Age(-5)        # ValueError23# Age(200)       # ValueError2425print("\n=== Validation with Correction ===")2627class Username:28    def __init__(self, name):29        # Strip whitespace  #?strip30        name = name.strip()31        32        # Convert to lowercase  #?lower33        name = name.lower()34        35        # Validate length  #?lengthcheck36        if len(name) < 3:37            raise ValueError("Username must be at least 3 characters")38        if len(name) > 20:39            name = name[:20]  # Truncate  #?truncate40        41        self.name = name4243user1 = Username("  Alice  ")  # Whitespace removed44user2 = Username("BOB")  # Lowercased
    outputValid ages: 25, 0
    
    === Validation with Correction ===
  6. name ← Alice, self.name ← alice

    pass 1 of 3
    27class Username:28    def __init__(self⟨Username C⟩, name  Alice  ):29        # Strip whitespace  #?strip30        name→ Alice = name.strip()31        32        # Convert to lowercase  #?lower33        name→ alice = name.lower()34        35        # Validate length  #?lengthcheck36        if len(name) < 3:37            raise ValueError("Username must be at least 3 characters")38        if len(name) > 20:39            name = name[:20]  # Truncate  #?truncate40        41        self.name→ alice = namealice
    All 3 passes — pass 1 is the card above
    passselfname[:20]nameself.name
    1⟨Username C⟩ Alice Alicealice
    2⟨Username D⟩BOBbob
    3⟨Username E⟩verylongusernamethatVeryLongUsernameThatExceedsLimit
  7. user1 ← ⟨Username C⟩

    43user1→ ⟨Username C⟩ = Username("  Alice  ")  # Whitespace removed44user2 = Username("BOB")  # Lowercased45user3 = Username("VeryLongUsernameThatExceedsLimit")  # Truncated
  8. user2 ← ⟨Username D⟩

    43user1 = Username("  Alice  ")  # Whitespace removed44user2→ ⟨Username D⟩ = Username("BOB")  # Lowercased45user3 = Username("VeryLongUsernameThatExceedsLimit")  # Truncated
  9. name ← verylongusernamethat

    37    raise ValueError("Username must be at least 3 characters")38if len(nameverylongusernamethatexceedslimit) > 20:39    name→ verylongusernamethat = name[:20]verylongusernamethat  # Truncate  #?truncate
  10. self.name ← verylongusernamethat

    41self.name→ verylongusernamethat = nameverylongusernamethat
  11. user3 ← ⟨Username E⟩

    44user2 = Username("BOB")  # Lowercased45user3→ ⟨Username E⟩ = Username("VeryLongUsernameThatExceedsLimit")  # Truncated4647print(f"'{user1.namealice}'")48print(f"'{user2.namebob}'")49print(f"'{user3.nameverylongusernamethat}' (len={len(user3.name)})")5051print("\n=== Validation with Defaults ===")5253class Temperature:54    def __init__(self, celsius):55        # Clamp to valid range  #?clamp56        if celsius < -273.15:  # Absolute zero  #?absoulutezero57            print(f"Warning: {celsius} adjusted to -273.15")58            celsius = -273.1559        self.celsius = celsius60    61    @property62    def fahrenheit(self):63        return self.celsius * 9/5 + 326465t1 = Temperature(25)66t2 = Temperature(-300)  # Adjusted  #?adjusted
    output'alice'
    'bob'
    'verylongusernamethat' (len=20)
    
    === Validation with Defaults ===
  12. self.celsius ← 25

    pass 1 of 2
    53class Temperature:54    def __init__(self⟨Temperature F⟩, celsius25):55        # Clamp to valid range  #?clamp56        if celsius < -273.15:  # Absolute zero  #?absoulutezero57            print(f"Warning: {celsius} adjusted to -273.15")58            celsius = -273.1559        self.celsius→ 25 = celsius25
  13. t1 ← ⟨Temperature F⟩

    65t1→ ⟨Temperature F⟩ = Temperature(25)66t2 = Temperature(-300)  # Adjusted  #?adjusted
  14. def __init__(self, celsius): # Clamp to valid range #?clamp

    pass 2 of 2
    53class Temperature:54    def __init__(self⟨Temperature G⟩, celsius-300):55        # Clamp to valid range  #?clamp56        if celsius < -273.15:  # Absolute zero  #?absoulutezero57            print(f"Warning: {celsius} adjusted to -273.15")
  15. celsius ← -273.15

    55# Clamp to valid range  #?clamp56if celsius-300 < -273.15:  # Absolute zero  #?absoulutezero57    print(f"Warning: {celsius-300} adjusted to -273.15")58    celsius→ -273.15 = -273.1559self.celsius = celsius
    outputWarning: -300 adjusted to -273.15
  16. self.celsius ← -273.15

    58    celsius = -273.1559self.celsius→ -273.15 = celsius-273.15
  17. t2 ← ⟨Temperature G⟩

    65t1 = Temperature(25)66t2→ ⟨Temperature G⟩ = Temperature(-300)  # Adjusted  #?adjusted6768print(f"t1: {t1.celsius25}°C")69print(f"t2: {t2.celsius-273.15}°C (was adjusted)")7071print("\n=== Complex Validation ===")7273class Email:74    def __init__(self, address):75        # Basic email validation  #?emailvalidation76        address = address.strip().lower()77        78        if "@" not in address:  #?checkatsign79            raise ValueError("Email must contain @")80        81        parts = address.split("@")  #?split82        if len(parts) != 2:83            raise ValueError("Email must have exactly one @")84        85        local, domain = parts  #?unpack86        87        if not local:  #?checklocal88            raise ValueError("Email must have local part")89        if not domain or "." not in domain:  #?checkdomain90            raise ValueError("Email must have valid domain")91        92        self.address = address93        self.local = local94        self.domain = domain9596email = Email("  User@Example.COM  ")97print(f"Address: {email.address}")
    outputt1: 25°C
    t2: -273.15°C (was adjusted)
    
    === Complex Validation ===
  18. address ← user@example.com, parts ← ['user', 'example.com'], local ← user

    73class Email:74    def __init__(self⟨Email H⟩, address  User@Example.COM  ):75        # Basic email validation  #?emailvalidation76        address→ user@example.com = address.strip().lower()77        78        if "@" not in address:  #?checkatsign79            raise ValueError("Email must contain @")80        81        parts→ ['user', 'example.com'] = addressuser@example.com.split("@")  #?split82        if len(parts) != 2:83            raise ValueError("Email must have exactly one @")84        85        local→ user, domain→ example.com = parts['user', 'example.com']  #?unpack86        87        if not local:  #?checklocal88            raise ValueError("Email must have local part")89        if not domain or "." not in domain:  #?checkdomain90            raise ValueError("Email must have valid domain")91        92        self.address→ user@example.com = addressuser@example.com93        self.local→ user = localuser94        self.domain→ example.com = domainexample.com
  19. email ← ⟨Email H⟩

    96email→ ⟨Email H⟩ = Email("  User@Example.COM  ")97print(f"Address: {email.addressuser@example.com}")98print(f"Local: {email.localuser}, Domain: {email.domainexample.com}")99100print("\n=== Validation Summary ===")101102class Product:103    def __init__(self, name, price, quantity=0):104        # Name validation  #?namevalidation105        if not name or not name.strip():106            raise ValueError("Product name cannot be empty")107        self.name = name.strip()108        109        # Price validation  #?pricevalidation110        if not isinstance(price, (int, float)):111            raise TypeError("Price must be a number")112        if price < 0:113            raise ValueError("Price cannot be negative")114        self.price = round(price, 2)  # Round to cents  #?round115        116        # Quantity validation  #?quantityvalidation117        if not isinstance(quantity, int):118            raise TypeError("Quantity must be an integer")119        if quantity < 0:120            quantity = 0  # Auto-correct  #?autocorrect121        self.quantity = quantity122123laptop = Product("  Laptop  ", 999.999, 5)124print(f"Product: {laptop.name}, ${laptop.price}, qty={laptop.quantity}")
    outputAddress: user@example.com
    Local: user, Domain: example.com
    
    === Validation Summary ===
  20. self.name ← Laptop, self.price ← 1000.0, self.quantity ← 5

    102class Product:103    def __init__(self⟨Product I⟩, name  Laptop  , price999.999, quantity5=0):104        # Name validation  #?namevalidation105        if not name or not name.strip():106            raise ValueError("Product name cannot be empty")107        self.name→ Laptop = name  Laptop  .strip()108        109        # Price validation  #?pricevalidation110        if not isinstance(price, (int, float)):111            raise TypeError("Price must be a number")112        if price < 0:113            raise ValueError("Price cannot be negative")114        self.price→ 1000.0 = round(price999.999, 2)  # Round to cents  #?round115        116        # Quantity validation  #?quantityvalidation117        if not isinstance(quantity, int):118            raise TypeError("Quantity must be an integer")119        if quantity < 0:120            quantity = 0  # Auto-correct  #?autocorrect121        self.quantity→ 5 = quantity5
  21. laptop ← ⟨Product I⟩

    123laptop→ ⟨Product I⟩ = Product("  Laptop  ", 999.999, 5)124print(f"Product: {laptop.nameLaptop}, ${laptop.price1000.0}, qty={laptop.quantity5}")125#@help typecheck
    outputProduct: Laptop, $1000.0, qty=5

Raise exceptions in __init__ to prevent invalid objects from existing.

Computed attributes

Calculate attributes from parameters.

example
computed_attrs.py
Replay: real traced execution (multi-file project)
# Computing Attributes in Constructor

print("=== Computed from Parameters ===\n")

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        # Computed attributes
        self.area = width * height
        self.perimeter = 2 * (width + height)
        self.diagonal = (width**2 + height**2) ** 0.5

rect = Rectangle(3, 4)
print(f"Rectangle {rect.width}x{rect.height}")
print(f"Area: {rect.area}")
print(f"Perimeter: {rect.perimeter}")
print(f"Diagonal: {rect.diagonal}")

print("\n=== Derived Attributes ===")

class Person:
    def __init__(self, first_name, last_name, birth_year):
        self.first_name = first_name
        self.last_name = last_name
        self.birth_year = birth_year
        # Derived attributes
        self.full_name = f"{first_name} {last_name}"
        self.age = 2024 - birth_year
        self.initials = f"{first_name[0]}.{last_name[0]}."

person = Person("John", "Doe", 1990)
print(f"Name: {person.full_name}")
print(f"Initials: {person.initials}")
print(f"Age: {person.age}")

print("\n=== Computed Collections ===")

class ScoreBoard:
    def __init__(self, scores):
        self.scores = list(scores)  # Copy the list
        # Compute statistics
        self.count = len(self.scores)
        self.total = sum(self.scores)
        self.average = self.total / self.count if self.count else 0
        self.highest = max(self.scores) if self.scores else None
        self.lowest = min(self.scores) if self.scores else None

board = ScoreBoard([85, 92, 78, 95, 88])
print(f"Scores: {board.scores}")
print(f"Count: {board.count}, Total: {board.total}")
print(f"Average: {board.average:.1f}")
print(f"High: {board.highest}, Low: {board.lowest}")

print("\n=== Computed Flags/Status ===")

class Order:
    def __init__(self, items, discount_code=None):
        self.items = items
        self.discount_code = discount_code

        # Compute totals
        self.subtotal = sum(item["price"] * item["qty"] for item in items)

        # Apply discount
        self.discount = 0
        if discount_code == "SAVE10":
            self.discount = self.subtotal * 0.10
        elif discount_code == "SAVE20":
            self.discount = self.subtotal * 0.20

        self.total = self.subtotal - self.discount

        # Status flags
        self.is_large_order = self.total > 100
        self.has_discount = self.discount > 0
        self.item_count = sum(item["qty"] for item in items)

items = [
    {"name": "Book", "price": 15, "qty": 2},
    {"name": "Pen", "price": 5, "qty": 5}
]
order = Order(items, "SAVE10")

print(f"Items: {order.item_count}")
print(f"Subtotal: ${order.subtotal}")
print(f"Discount: ${order.discount}")
print(f"Total: ${order.total}")
print(f"Large order? {order.is_large_order}")

print("\n=== Timestamp and ID ===")


class Event:
    _next_id = 1  # Class variable for ID generation

    def __init__(self, name, category):
        self.name = name
        self.category = category
        # Auto-generated
        self.id = Event._next_id
        Event._next_id += 1
        self.created_at = 1736937000.0

e1 = Event("Login", "auth")
e2 = Event("Click", "ui")
e3 = Event("Purchase", "sale")

for e in [e1, e2, e3]:
    print(f"Event #{e.id}: {e.name} ({e.category})")
# Computing Attributes in Constructor

print("=== Computed from Parameters ===\n")

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        # Computed attributes
        self.area = width * height
        self.perimeter = 2 * (width + height)
        self.diagonal = (width**2 + height**2) ** 0.5

rect = Rectangle(5, 12)
print(f"Rectangle {rect.width}x{rect.height}")
print(f"Area: {rect.area}")
print(f"Perimeter: {rect.perimeter}")
print(f"Diagonal: {rect.diagonal}")

print("\n=== Derived Attributes ===")

class Person:
    def __init__(self, first_name, last_name, birth_year):
        self.first_name = first_name
        self.last_name = last_name
        self.birth_year = birth_year
        # Derived attributes
        self.full_name = f"{first_name} {last_name}"
        self.age = 2024 - birth_year
        self.initials = f"{first_name[0]}.{last_name[0]}."

person = Person("John", "Doe", 1990)
print(f"Name: {person.full_name}")
print(f"Initials: {person.initials}")
print(f"Age: {person.age}")

print("\n=== Computed Collections ===")

class ScoreBoard:
    def __init__(self, scores):
        self.scores = list(scores)  # Copy the list
        # Compute statistics
        self.count = len(self.scores)
        self.total = sum(self.scores)
        self.average = self.total / self.count if self.count else 0
        self.highest = max(self.scores) if self.scores else None
        self.lowest = min(self.scores) if self.scores else None

board = ScoreBoard([85, 92, 78, 95, 88])
print(f"Scores: {board.scores}")
print(f"Count: {board.count}, Total: {board.total}")
print(f"Average: {board.average:.1f}")
print(f"High: {board.highest}, Low: {board.lowest}")

print("\n=== Computed Flags/Status ===")

class Order:
    def __init__(self, items, discount_code=None):
        self.items = items
        self.discount_code = discount_code

        # Compute totals
        self.subtotal = sum(item["price"] * item["qty"] for item in items)

        # Apply discount
        self.discount = 0
        if discount_code == "SAVE10":
            self.discount = self.subtotal * 0.10
        elif discount_code == "SAVE20":
            self.discount = self.subtotal * 0.20

        self.total = self.subtotal - self.discount

        # Status flags
        self.is_large_order = self.total > 100
        self.has_discount = self.discount > 0
        self.item_count = sum(item["qty"] for item in items)

items = [
    {"name": "Book", "price": 15, "qty": 2},
    {"name": "Pen", "price": 5, "qty": 5}
]
order = Order(items, "SAVE10")

print(f"Items: {order.item_count}")
print(f"Subtotal: ${order.subtotal}")
print(f"Discount: ${order.discount}")
print(f"Total: ${order.total}")
print(f"Large order? {order.is_large_order}")

print("\n=== Timestamp and ID ===")


class Event:
    _next_id = 1  # Class variable for ID generation

    def __init__(self, name, category):
        self.name = name
        self.category = category
        # Auto-generated
        self.id = Event._next_id
        Event._next_id += 1
        self.created_at = 1736937000.0

e1 = Event("Login", "auth")
e2 = Event("Click", "ui")
e3 = Event("Purchase", "sale")

for e in [e1, e2, e3]:
    print(f"Event #{e.id}: {e.name} ({e.category})")
# Computing Attributes in Constructor

print("=== Computed from Parameters ===\n")

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        # Computed attributes
        self.area = width * height
        self.perimeter = 2 * (width + height)
        self.diagonal = (width**2 + height**2) ** 0.5

rect = Rectangle(6, 8)
print(f"Rectangle {rect.width}x{rect.height}")
print(f"Area: {rect.area}")
print(f"Perimeter: {rect.perimeter}")
print(f"Diagonal: {rect.diagonal}")

print("\n=== Derived Attributes ===")

class Person:
    def __init__(self, first_name, last_name, birth_year):
        self.first_name = first_name
        self.last_name = last_name
        self.birth_year = birth_year
        # Derived attributes
        self.full_name = f"{first_name} {last_name}"
        self.age = 2024 - birth_year
        self.initials = f"{first_name[0]}.{last_name[0]}."

person = Person("John", "Doe", 1990)
print(f"Name: {person.full_name}")
print(f"Initials: {person.initials}")
print(f"Age: {person.age}")

print("\n=== Computed Collections ===")

class ScoreBoard:
    def __init__(self, scores):
        self.scores = list(scores)  # Copy the list
        # Compute statistics
        self.count = len(self.scores)
        self.total = sum(self.scores)
        self.average = self.total / self.count if self.count else 0
        self.highest = max(self.scores) if self.scores else None
        self.lowest = min(self.scores) if self.scores else None

board = ScoreBoard([85, 92, 78, 95, 88])
print(f"Scores: {board.scores}")
print(f"Count: {board.count}, Total: {board.total}")
print(f"Average: {board.average:.1f}")
print(f"High: {board.highest}, Low: {board.lowest}")

print("\n=== Computed Flags/Status ===")

class Order:
    def __init__(self, items, discount_code=None):
        self.items = items
        self.discount_code = discount_code

        # Compute totals
        self.subtotal = sum(item["price"] * item["qty"] for item in items)

        # Apply discount
        self.discount = 0
        if discount_code == "SAVE10":
            self.discount = self.subtotal * 0.10
        elif discount_code == "SAVE20":
            self.discount = self.subtotal * 0.20

        self.total = self.subtotal - self.discount

        # Status flags
        self.is_large_order = self.total > 100
        self.has_discount = self.discount > 0
        self.item_count = sum(item["qty"] for item in items)

items = [
    {"name": "Book", "price": 15, "qty": 2},
    {"name": "Pen", "price": 5, "qty": 5}
]
order = Order(items, "SAVE10")

print(f"Items: {order.item_count}")
print(f"Subtotal: ${order.subtotal}")
print(f"Discount: ${order.discount}")
print(f"Total: ${order.total}")
print(f"Large order? {order.is_large_order}")

print("\n=== Timestamp and ID ===")


class Event:
    _next_id = 1  # Class variable for ID generation

    def __init__(self, name, category):
        self.name = name
        self.category = category
        # Auto-generated
        self.id = Event._next_id
        Event._next_id += 1
        self.created_at = 1736937000.0

e1 = Event("Login", "auth")
e2 = Event("Click", "ui")
e3 = Event("Purchase", "sale")

for e in [e1, e2, e3]:
    print(f"Event #{e.id}: {e.name} ({e.category})")
# Computing Attributes in Constructor

print("=== Computed from Parameters ===\n")

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        # Computed attributes
        self.area = width * height
        self.perimeter = 2 * (width + height)
        self.diagonal = (width**2 + height**2) ** 0.5

rect = Rectangle(3, 4)
print(f"Rectangle {rect.width}x{rect.height}")
print(f"Area: {rect.area}")
print(f"Perimeter: {rect.perimeter}")
print(f"Diagonal: {rect.diagonal}")

print("\n=== Derived Attributes ===")

class Person:
    def __init__(self, first_name, last_name, birth_year):
        self.first_name = first_name
        self.last_name = last_name
        self.birth_year = birth_year
        # Derived attributes
        self.full_name = f"{first_name} {last_name}"
        self.age = 2024 - birth_year
        self.initials = f"{first_name[0]}.{last_name[0]}."

person = Person("John", "Doe", 1990)
print(f"Name: {person.full_name}")
print(f"Initials: {person.initials}")
print(f"Age: {person.age}")

print("\n=== Computed Collections ===")

class ScoreBoard:
    def __init__(self, scores):
        self.scores = list(scores)  # Copy the list
        # Compute statistics
        self.count = len(self.scores)
        self.total = sum(self.scores)
        self.average = self.total / self.count if self.count else 0
        self.highest = max(self.scores) if self.scores else None
        self.lowest = min(self.scores) if self.scores else None

board = ScoreBoard([70, 80, 90])
print(f"Scores: {board.scores}")
print(f"Count: {board.count}, Total: {board.total}")
print(f"Average: {board.average:.1f}")
print(f"High: {board.highest}, Low: {board.lowest}")

print("\n=== Computed Flags/Status ===")

class Order:
    def __init__(self, items, discount_code=None):
        self.items = items
        self.discount_code = discount_code

        # Compute totals
        self.subtotal = sum(item["price"] * item["qty"] for item in items)

        # Apply discount
        self.discount = 0
        if discount_code == "SAVE10":
            self.discount = self.subtotal * 0.10
        elif discount_code == "SAVE20":
            self.discount = self.subtotal * 0.20

        self.total = self.subtotal - self.discount

        # Status flags
        self.is_large_order = self.total > 100
        self.has_discount = self.discount > 0
        self.item_count = sum(item["qty"] for item in items)

items = [
    {"name": "Book", "price": 15, "qty": 2},
    {"name": "Pen", "price": 5, "qty": 5}
]
order = Order(items, "SAVE10")

print(f"Items: {order.item_count}")
print(f"Subtotal: ${order.subtotal}")
print(f"Discount: ${order.discount}")
print(f"Total: ${order.total}")
print(f"Large order? {order.is_large_order}")

print("\n=== Timestamp and ID ===")


class Event:
    _next_id = 1  # Class variable for ID generation

    def __init__(self, name, category):
        self.name = name
        self.category = category
        # Auto-generated
        self.id = Event._next_id
        Event._next_id += 1
        self.created_at = 1736937000.0

e1 = Event("Login", "auth")
e2 = Event("Click", "ui")
e3 = Event("Purchase", "sale")

for e in [e1, e2, e3]:
    print(f"Event #{e.id}: {e.name} ({e.category})")
# Computing Attributes in Constructor

print("=== Computed from Parameters ===\n")

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        # Computed attributes
        self.area = width * height
        self.perimeter = 2 * (width + height)
        self.diagonal = (width**2 + height**2) ** 0.5

rect = Rectangle(3, 4)
print(f"Rectangle {rect.width}x{rect.height}")
print(f"Area: {rect.area}")
print(f"Perimeter: {rect.perimeter}")
print(f"Diagonal: {rect.diagonal}")

print("\n=== Derived Attributes ===")

class Person:
    def __init__(self, first_name, last_name, birth_year):
        self.first_name = first_name
        self.last_name = last_name
        self.birth_year = birth_year
        # Derived attributes
        self.full_name = f"{first_name} {last_name}"
        self.age = 2024 - birth_year
        self.initials = f"{first_name[0]}.{last_name[0]}."

person = Person("John", "Doe", 1990)
print(f"Name: {person.full_name}")
print(f"Initials: {person.initials}")
print(f"Age: {person.age}")

print("\n=== Computed Collections ===")

class ScoreBoard:
    def __init__(self, scores):
        self.scores = list(scores)  # Copy the list
        # Compute statistics
        self.count = len(self.scores)
        self.total = sum(self.scores)
        self.average = self.total / self.count if self.count else 0
        self.highest = max(self.scores) if self.scores else None
        self.lowest = min(self.scores) if self.scores else None

board = ScoreBoard([100, 95])
print(f"Scores: {board.scores}")
print(f"Count: {board.count}, Total: {board.total}")
print(f"Average: {board.average:.1f}")
print(f"High: {board.highest}, Low: {board.lowest}")

print("\n=== Computed Flags/Status ===")

class Order:
    def __init__(self, items, discount_code=None):
        self.items = items
        self.discount_code = discount_code

        # Compute totals
        self.subtotal = sum(item["price"] * item["qty"] for item in items)

        # Apply discount
        self.discount = 0
        if discount_code == "SAVE10":
            self.discount = self.subtotal * 0.10
        elif discount_code == "SAVE20":
            self.discount = self.subtotal * 0.20

        self.total = self.subtotal - self.discount

        # Status flags
        self.is_large_order = self.total > 100
        self.has_discount = self.discount > 0
        self.item_count = sum(item["qty"] for item in items)

items = [
    {"name": "Book", "price": 15, "qty": 2},
    {"name": "Pen", "price": 5, "qty": 5}
]
order = Order(items, "SAVE10")

print(f"Items: {order.item_count}")
print(f"Subtotal: ${order.subtotal}")
print(f"Discount: ${order.discount}")
print(f"Total: ${order.total}")
print(f"Large order? {order.is_large_order}")

print("\n=== Timestamp and ID ===")


class Event:
    _next_id = 1  # Class variable for ID generation

    def __init__(self, name, category):
        self.name = name
        self.category = category
        # Auto-generated
        self.id = Event._next_id
        Event._next_id += 1
        self.created_at = 1736937000.0

e1 = Event("Login", "auth")
e2 = Event("Click", "ui")
e3 = Event("Purchase", "sale")

for e in [e1, e2, e3]:
    print(f"Event #{e.id}: {e.name} ({e.category})")
  1. print("=== Computed from Parameters === ")

    3print("=== Computed from Parameters ===\n")45class Rectangle:6    def __init__(self, width, height):7        self.width = width8        self.height = height9        # Computed attributes  #?computed10        self.area = width * height  #?areacompute11        self.perimeter = 2 * (width + height)12        self.diagonal = (width**2 + height**2) ** 0.5  #?diagonal1314rect = Rectangle(3, 4)  #@rect=Rectangle(5, 12), Rectangle(6, 8)15print(f"Rectangle {rect.width}x{rect.height}")
    output=== Computed from Parameters ===
  2. self.width ← 3, self.height ← 4, self.area ← 12, self.perimeter ← 14

    5class Rectangle:6    def __init__(self⟨Rectangle A⟩, width3, height4):7        self.width→ 3 = width38        self.height→ 4 = height49        # Computed attributes  #?computed10        self.area→ 12 = width3 * height4  #?areacompute11        self.perimeter→ 14 = 2 * (width3 + height4)12        self.diagonal→ 5.0 = (width3**2 + height4**2) ** 0.5  #?diagonal
  3. rect ← ⟨Rectangle A⟩

    14rect→ ⟨Rectangle A⟩ = Rectangle(3, 4)  #@rect=Rectangle(5, 12), Rectangle(6, 8)15print(f"Rectangle {rect.width3}x{rect.height4}")16print(f"Area: {rect.area12}")17print(f"Perimeter: {rect.perimeter14}")18print(f"Diagonal: {rect.diagonal5.0}")1920print("\n=== Derived Attributes ===")2122class Person:23    def __init__(self, first_name, last_name, birth_year):24        self.first_name = first_name25        self.last_name = last_name26        self.birth_year = birth_year27        # Derived attributes  #?derived28        self.full_name = f"{first_name} {last_name}"  #?fullname29        self.age = 2024 - birth_year  #?age30        self.initials = f"{first_name[0]}.{last_name[0]}."  #?initials3132person = Person("John", "Doe", 1990)33print(f"Name: {person.full_name}")
    outputRectangle 3x4
    Area: 12
    Perimeter: 14
    Diagonal: 5.0
    
    === Derived Attributes ===
  4. self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990

    22class Person:23    def __init__(self⟨Person B⟩, first_nameJohn, last_nameDoe, birth_year1990):24        self.first_name→ John = first_nameJohn25        self.last_name→ Doe = last_nameDoe26        self.birth_year→ 1990 = birth_year199027        # Derived attributes  #?derived28        self.full_name→ John Doe = f"{first_nameJohn} {last_nameDoe}"  #?fullname29        self.age→ 34 = 2024 - birth_year1990  #?age30        self.initials→ J.D. = f"{first_name[0]J}.{last_name[0]D}."  #?initials
  5. person ← ⟨Person B⟩

    32person→ ⟨Person B⟩ = Person("John", "Doe", 1990)33print(f"Name: {person.full_nameJohn Doe}")34print(f"Initials: {person.initialsJ.D.}")35print(f"Age: {person.age34}")3637print("\n=== Computed Collections ===")3839class ScoreBoard:40    def __init__(self, scores):  #?listparam41        self.scores = list(scores)  # Copy the list  #?copy42        # Compute statistics  #?stats43        self.count = len(self.scores)44        self.total = sum(self.scores)45        self.average = self.total / self.count if self.count else 0  #?safeavg46        self.highest = max(self.scores) if self.scores else None47        self.lowest = min(self.scores) if self.scores else None4849board = ScoreBoard([85, 92, 78, 95, 88])  #@board=ScoreBoard([70, 80, 90]), ScoreBoard([100, 95])50print(f"Scores: {board.scores}")
    outputName: John Doe
    Initials: J.D.
    Age: 34
    
    === Computed Collections ===
  6. self.scores ← [85, 92, 78, 95, 88], self.count ← 5, self.total ← 438

    39class ScoreBoard:40    def __init__(self⟨ScoreBoard C⟩, scores[85, 92, 78, 95, 88]):  #?listparam41        self.scores→ [85, 92, 78, 95, 88] = list(scores[85, 92, 78, 95, 88])  # Copy the list  #?copy42        # Compute statistics  #?stats43        self.count→ 5 = len(self.scores[85, 92, 78, 95, 88])44        self.total→ 438 = sum(self.scores[85, 92, 78, 95, 88])45        self.average→ 87.6 = self.total438 / self.count5 if self.count else 0  #?safeavg46        self.highest→ 95 = max(self.scores[85, 92, 78, 95, 88]) if self.scores else None47        self.lowest→ 78 = min(self.scores[85, 92, 78, 95, 88]) if self.scores else None
  7. board ← ⟨ScoreBoard C⟩, items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    49board→ ⟨ScoreBoard C⟩ = ScoreBoard([85, 92, 78, 95, 88])  #@board=ScoreBoard([70, 80, 90]), ScoreBoard([100, 95])50print(f"Scores: {board.scores[85, 92, 78, 95, 88]}")51print(f"Count: {board.count5}, Total: {board.total438}")52print(f"Average: {board.average87.6:.1f}")53print(f"High: {board.highest95}, Low: {board.lowest78}")5455print("\n=== Computed Flags/Status ===")5657class Order:58    def __init__(self, items, discount_code=None):59        self.items = items60        self.discount_code = discount_code61        62        # Compute totals  #?computetotals63        self.subtotal = sum(item["price"] * item["qty"] for item in items)  #?subtotal64        65        # Apply discount  #?applydiscount66        self.discount = 067        if discount_code == "SAVE10":68            self.discount = self.subtotal * 0.1069        elif discount_code == "SAVE20":70            self.discount = self.subtotal * 0.2071        72        self.total = self.subtotal - self.discount73        74        # Status flags  #?flags75        self.is_large_order = self.total > 100  #?largeflag76        self.has_discount = self.discount > 077        self.item_count = sum(item["qty"] for item in items)7879items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = [80    {"name": "Book", "price": 15, "qty": 2},81    {"name": "Pen", "price": 5, "qty": 5}82]83order = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")
    outputScores: [85, 92, 78, 95, 88]
    Count: 5, Total: 438
    Average: 87.6
    High: 95, Low: 78
    
    === Computed Flags/Status ===
  8. self.items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    57class Order:58    def __init__(self⟨Order D⟩, items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], discount_codeSAVE10=NoneNone):59        self.items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]60        self.discount_code→ SAVE10 = discount_codeSAVE1061        62        # Compute totals  #?computetotals63        self.subtotal→ 55 = sum(item["price"](empty) * item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])  #?subtotal64        65        # Apply discount  #?applydiscount66        self.discount→ 0 = 067        if discount_code == "SAVE10":
  9. self.discount ← 5.5

    66self.discount = 067if discount_codeSAVE10 == "SAVE10":68    self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":
  10. self.total ← 49.5, self.is_large_order ← False, self.has_discount ← True

    72self.total→ 49.5 = self.subtotal55 - self.discount5.57374# Status flags  #?flags75self.is_large_order→ False = self.total49.5 > 100  #?largeflag76self.has_discount→ True = self.discount5.5 > 077self.item_count→ 7 = sum(item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])
  11. order ← ⟨Order D⟩, _next_id ← (empty)

    82]83order→ ⟨Order D⟩ = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")8485print(f"Items: {order.item_count7}")86print(f"Subtotal: ${order.subtotal55}")87print(f"Discount: ${order.discount5.5}")88print(f"Total: ${order.total49.5}")89print(f"Large order? {order.is_large_orderFalse}")9091print("\n=== Timestamp and ID ===")929394class Event:95    _next_id→ (empty) = 1  # Class variable for ID generation  #?classvar96    97    def __init__(self, name, category):98        self.name = name99        self.category = category100        # Auto-generated  #?autogen101        self.id = Event._next_id  #?assignid102        Event._next_id += 1103        self.created_at = 1736937000.0  #?timestamp104105e1 = Event("Login", "auth")106e2 = Event("Click", "ui")
    outputItems: 7
    Subtotal: $55
    Discount: $5.5
    Total: $49.5
    Large order? False
    
    === Timestamp and ID ===
  12. self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2

    pass 1 of 3
    97def __init__(self⟨Event E⟩, nameLogin, categoryauth):98    self.name→ Login = nameLogin99    self.category→ auth = categoryauth100    # Auto-generated  #?autogen101    self.id→ 1 = Event._next_id1  #?assignid102    Event._next_id→ 2 += 1103    self.created_at→ 1736937000.0 = 1736937000.0  #?timestamp
    All 3 passes — pass 1 is the card above
    passselfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at
    1⟨Event E⟩LoginauthLoginauth11 21736937000.0
    2⟨Event F⟩ClickuiClickui22 31736937000.0
    3⟨Event G⟩PurchasesalePurchasesale33 41736937000.0
  13. e1 ← ⟨Event E⟩

    105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  14. e2 ← ⟨Event F⟩

    105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  15. e3 ← ⟨Event G⟩

    106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")
  16. for e in [e1, e2, e3]:

    pass 1 of 3
    109for e⟨Event E⟩ in [e1⟨Event E⟩, e2⟨Event F⟩, e3⟨Event G⟩]:110    print(f"Event #{e.id1}: {e.nameLogin} ({e.categoryauth})")111#@help computed
    outputEvent #1: Login (auth)
    All 3 passes — pass 1 is the card above
    passee.ide.namee.category
    1⟨Event E⟩1Loginauth
    2⟨Event F⟩2Clickui
    3⟨Event G⟩3Purchasesale
  1. print("=== Computed from Parameters === ")

    3print("=== Computed from Parameters ===\n")45class Rectangle:6    def __init__(self, width, height):7        self.width = width8        self.height = height9        # Computed attributes10        self.area = width * height11        self.perimeter = 2 * (width + height)12        self.diagonal = (width**2 + height**2) ** 0.51314rect = Rectangle(5, 12)15print(f"Rectangle {rect.width}x{rect.height}")
    output=== Computed from Parameters ===
  2. self.width ← 5, self.height ← 12, self.area ← 60, self.perimeter ← 34

    5class Rectangle:6    def __init__(self⟨Rectangle A⟩, width5, height12):7        self.width→ 5 = width58        self.height→ 12 = height129        # Computed attributes10        self.area→ 60 = width5 * height1211        self.perimeter→ 34 = 2 * (width5 + height12)12        self.diagonal→ 13.0 = (width5**2 + height12**2) ** 0.5
  3. rect ← ⟨Rectangle A⟩

    14rect→ ⟨Rectangle A⟩ = Rectangle(5, 12)15print(f"Rectangle {rect.width5}x{rect.height12}")16print(f"Area: {rect.area60}")17print(f"Perimeter: {rect.perimeter34}")18print(f"Diagonal: {rect.diagonal13.0}")1920print("\n=== Derived Attributes ===")2122class Person:23    def __init__(self, first_name, last_name, birth_year):24        self.first_name = first_name25        self.last_name = last_name26        self.birth_year = birth_year27        # Derived attributes28        self.full_name = f"{first_name} {last_name}"29        self.age = 2024 - birth_year30        self.initials = f"{first_name[0]}.{last_name[0]}."3132person = Person("John", "Doe", 1990)33print(f"Name: {person.full_name}")
    outputRectangle 5x12
    Area: 60
    Perimeter: 34
    Diagonal: 13.0
    
    === Derived Attributes ===
  4. self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990

    22class Person:23    def __init__(self⟨Person B⟩, first_nameJohn, last_nameDoe, birth_year1990):24        self.first_name→ John = first_nameJohn25        self.last_name→ Doe = last_nameDoe26        self.birth_year→ 1990 = birth_year199027        # Derived attributes28        self.full_name→ John Doe = f"{first_nameJohn} {last_nameDoe}"29        self.age→ 34 = 2024 - birth_year199030        self.initials→ J.D. = f"{first_name[0]J}.{last_name[0]D}."
  5. person ← ⟨Person B⟩

    32person→ ⟨Person B⟩ = Person("John", "Doe", 1990)33print(f"Name: {person.full_nameJohn Doe}")34print(f"Initials: {person.initialsJ.D.}")35print(f"Age: {person.age34}")3637print("\n=== Computed Collections ===")3839class ScoreBoard:40    def __init__(self, scores):41        self.scores = list(scores)  # Copy the list42        # Compute statistics43        self.count = len(self.scores)44        self.total = sum(self.scores)45        self.average = self.total / self.count if self.count else 046        self.highest = max(self.scores) if self.scores else None47        self.lowest = min(self.scores) if self.scores else None4849board = ScoreBoard([85, 92, 78, 95, 88])50print(f"Scores: {board.scores}")
    outputName: John Doe
    Initials: J.D.
    Age: 34
    
    === Computed Collections ===
  6. self.scores ← [85, 92, 78, 95, 88], self.count ← 5, self.total ← 438

    39class ScoreBoard:40    def __init__(self⟨ScoreBoard C⟩, scores[85, 92, 78, 95, 88]):41        self.scores→ [85, 92, 78, 95, 88] = list(scores[85, 92, 78, 95, 88])  # Copy the list42        # Compute statistics43        self.count→ 5 = len(self.scores[85, 92, 78, 95, 88])44        self.total→ 438 = sum(self.scores[85, 92, 78, 95, 88])45        self.average→ 87.6 = self.total438 / self.count5 if self.count else 046        self.highest→ 95 = max(self.scores[85, 92, 78, 95, 88]) if self.scores else None47        self.lowest→ 78 = min(self.scores[85, 92, 78, 95, 88]) if self.scores else None
  7. board ← ⟨ScoreBoard C⟩, items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    49board→ ⟨ScoreBoard C⟩ = ScoreBoard([85, 92, 78, 95, 88])50print(f"Scores: {board.scores[85, 92, 78, 95, 88]}")51print(f"Count: {board.count5}, Total: {board.total438}")52print(f"Average: {board.average87.6:.1f}")53print(f"High: {board.highest95}, Low: {board.lowest78}")5455print("\n=== Computed Flags/Status ===")5657class Order:58    def __init__(self, items, discount_code=None):59        self.items = items60        self.discount_code = discount_code61        62        # Compute totals63        self.subtotal = sum(item["price"] * item["qty"] for item in items)64        65        # Apply discount66        self.discount = 067        if discount_code == "SAVE10":68            self.discount = self.subtotal * 0.1069        elif discount_code == "SAVE20":70            self.discount = self.subtotal * 0.2071        72        self.total = self.subtotal - self.discount73        74        # Status flags75        self.is_large_order = self.total > 10076        self.has_discount = self.discount > 077        self.item_count = sum(item["qty"] for item in items)7879items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = [80    {"name": "Book", "price": 15, "qty": 2},81    {"name": "Pen", "price": 5, "qty": 5}82]83order = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")
    outputScores: [85, 92, 78, 95, 88]
    Count: 5, Total: 438
    Average: 87.6
    High: 95, Low: 78
    
    === Computed Flags/Status ===
  8. self.items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    57class Order:58    def __init__(self⟨Order D⟩, items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], discount_codeSAVE10=NoneNone):59        self.items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]60        self.discount_code→ SAVE10 = discount_codeSAVE1061        62        # Compute totals63        self.subtotal→ 55 = sum(item["price"](empty) * item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])64        65        # Apply discount66        self.discount→ 0 = 067        if discount_code == "SAVE10":
  9. self.discount ← 5.5

    66self.discount = 067if discount_codeSAVE10 == "SAVE10":68    self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":
  10. self.total ← 49.5, self.is_large_order ← False, self.has_discount ← True

    72self.total→ 49.5 = self.subtotal55 - self.discount5.57374# Status flags75self.is_large_order→ False = self.total49.5 > 10076self.has_discount→ True = self.discount5.5 > 077self.item_count→ 7 = sum(item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])
  11. order ← ⟨Order D⟩, _next_id ← (empty)

    82]83order→ ⟨Order D⟩ = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")8485print(f"Items: {order.item_count7}")86print(f"Subtotal: ${order.subtotal55}")87print(f"Discount: ${order.discount5.5}")88print(f"Total: ${order.total49.5}")89print(f"Large order? {order.is_large_orderFalse}")9091print("\n=== Timestamp and ID ===")929394class Event:95    _next_id→ (empty) = 1  # Class variable for ID generation96    97    def __init__(self, name, category):98        self.name = name99        self.category = category100        # Auto-generated101        self.id = Event._next_id102        Event._next_id += 1103        self.created_at = 1736937000.0104105e1 = Event("Login", "auth")106e2 = Event("Click", "ui")
    outputItems: 7
    Subtotal: $55
    Discount: $5.5
    Total: $49.5
    Large order? False
    
    === Timestamp and ID ===
  12. self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2

    pass 1 of 3
    97def __init__(self⟨Event E⟩, nameLogin, categoryauth):98    self.name→ Login = nameLogin99    self.category→ auth = categoryauth100    # Auto-generated101    self.id→ 1 = Event._next_id1102    Event._next_id→ 2 += 1103    self.created_at→ 1736937000.0 = 1736937000.0
    All 3 passes — pass 1 is the card above
    passselfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at
    1⟨Event E⟩LoginauthLoginauth11 21736937000.0
    2⟨Event F⟩ClickuiClickui22 31736937000.0
    3⟨Event G⟩PurchasesalePurchasesale33 41736937000.0
  13. e1 ← ⟨Event E⟩

    105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  14. e2 ← ⟨Event F⟩

    105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  15. e3 ← ⟨Event G⟩

    106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")
  16. for e in [e1, e2, e3]:

    pass 1 of 3
    109for e⟨Event E⟩ in [e1⟨Event E⟩, e2⟨Event F⟩, e3⟨Event G⟩]:110    print(f"Event #{e.id1}: {e.nameLogin} ({e.categoryauth})")
    outputEvent #1: Login (auth)
    All 3 passes — pass 1 is the card above
    passee.ide.namee.category
    1⟨Event E⟩1Loginauth
    2⟨Event F⟩2Clickui
    3⟨Event G⟩3Purchasesale
  1. print("=== Computed from Parameters === ")

    3print("=== Computed from Parameters ===\n")45class Rectangle:6    def __init__(self, width, height):7        self.width = width8        self.height = height9        # Computed attributes10        self.area = width * height11        self.perimeter = 2 * (width + height)12        self.diagonal = (width**2 + height**2) ** 0.51314rect = Rectangle(6, 8)15print(f"Rectangle {rect.width}x{rect.height}")
    output=== Computed from Parameters ===
  2. self.width ← 6, self.height ← 8, self.area ← 48, self.perimeter ← 28

    5class Rectangle:6    def __init__(self⟨Rectangle A⟩, width6, height8):7        self.width→ 6 = width68        self.height→ 8 = height89        # Computed attributes10        self.area→ 48 = width6 * height811        self.perimeter→ 28 = 2 * (width6 + height8)12        self.diagonal→ 10.0 = (width6**2 + height8**2) ** 0.5
  3. rect ← ⟨Rectangle A⟩

    14rect→ ⟨Rectangle A⟩ = Rectangle(6, 8)15print(f"Rectangle {rect.width6}x{rect.height8}")16print(f"Area: {rect.area48}")17print(f"Perimeter: {rect.perimeter28}")18print(f"Diagonal: {rect.diagonal10.0}")1920print("\n=== Derived Attributes ===")2122class Person:23    def __init__(self, first_name, last_name, birth_year):24        self.first_name = first_name25        self.last_name = last_name26        self.birth_year = birth_year27        # Derived attributes28        self.full_name = f"{first_name} {last_name}"29        self.age = 2024 - birth_year30        self.initials = f"{first_name[0]}.{last_name[0]}."3132person = Person("John", "Doe", 1990)33print(f"Name: {person.full_name}")
    outputRectangle 6x8
    Area: 48
    Perimeter: 28
    Diagonal: 10.0
    
    === Derived Attributes ===
  4. self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990

    22class Person:23    def __init__(self⟨Person B⟩, first_nameJohn, last_nameDoe, birth_year1990):24        self.first_name→ John = first_nameJohn25        self.last_name→ Doe = last_nameDoe26        self.birth_year→ 1990 = birth_year199027        # Derived attributes28        self.full_name→ John Doe = f"{first_nameJohn} {last_nameDoe}"29        self.age→ 34 = 2024 - birth_year199030        self.initials→ J.D. = f"{first_name[0]J}.{last_name[0]D}."
  5. person ← ⟨Person B⟩

    32person→ ⟨Person B⟩ = Person("John", "Doe", 1990)33print(f"Name: {person.full_nameJohn Doe}")34print(f"Initials: {person.initialsJ.D.}")35print(f"Age: {person.age34}")3637print("\n=== Computed Collections ===")3839class ScoreBoard:40    def __init__(self, scores):41        self.scores = list(scores)  # Copy the list42        # Compute statistics43        self.count = len(self.scores)44        self.total = sum(self.scores)45        self.average = self.total / self.count if self.count else 046        self.highest = max(self.scores) if self.scores else None47        self.lowest = min(self.scores) if self.scores else None4849board = ScoreBoard([85, 92, 78, 95, 88])50print(f"Scores: {board.scores}")
    outputName: John Doe
    Initials: J.D.
    Age: 34
    
    === Computed Collections ===
  6. self.scores ← [85, 92, 78, 95, 88], self.count ← 5, self.total ← 438

    39class ScoreBoard:40    def __init__(self⟨ScoreBoard C⟩, scores[85, 92, 78, 95, 88]):41        self.scores→ [85, 92, 78, 95, 88] = list(scores[85, 92, 78, 95, 88])  # Copy the list42        # Compute statistics43        self.count→ 5 = len(self.scores[85, 92, 78, 95, 88])44        self.total→ 438 = sum(self.scores[85, 92, 78, 95, 88])45        self.average→ 87.6 = self.total438 / self.count5 if self.count else 046        self.highest→ 95 = max(self.scores[85, 92, 78, 95, 88]) if self.scores else None47        self.lowest→ 78 = min(self.scores[85, 92, 78, 95, 88]) if self.scores else None
  7. board ← ⟨ScoreBoard C⟩, items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    49board→ ⟨ScoreBoard C⟩ = ScoreBoard([85, 92, 78, 95, 88])50print(f"Scores: {board.scores[85, 92, 78, 95, 88]}")51print(f"Count: {board.count5}, Total: {board.total438}")52print(f"Average: {board.average87.6:.1f}")53print(f"High: {board.highest95}, Low: {board.lowest78}")5455print("\n=== Computed Flags/Status ===")5657class Order:58    def __init__(self, items, discount_code=None):59        self.items = items60        self.discount_code = discount_code61        62        # Compute totals63        self.subtotal = sum(item["price"] * item["qty"] for item in items)64        65        # Apply discount66        self.discount = 067        if discount_code == "SAVE10":68            self.discount = self.subtotal * 0.1069        elif discount_code == "SAVE20":70            self.discount = self.subtotal * 0.2071        72        self.total = self.subtotal - self.discount73        74        # Status flags75        self.is_large_order = self.total > 10076        self.has_discount = self.discount > 077        self.item_count = sum(item["qty"] for item in items)7879items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = [80    {"name": "Book", "price": 15, "qty": 2},81    {"name": "Pen", "price": 5, "qty": 5}82]83order = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")
    outputScores: [85, 92, 78, 95, 88]
    Count: 5, Total: 438
    Average: 87.6
    High: 95, Low: 78
    
    === Computed Flags/Status ===
  8. self.items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    57class Order:58    def __init__(self⟨Order D⟩, items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], discount_codeSAVE10=NoneNone):59        self.items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]60        self.discount_code→ SAVE10 = discount_codeSAVE1061        62        # Compute totals63        self.subtotal→ 55 = sum(item["price"](empty) * item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])64        65        # Apply discount66        self.discount→ 0 = 067        if discount_code == "SAVE10":
  9. self.discount ← 5.5

    66self.discount = 067if discount_codeSAVE10 == "SAVE10":68    self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":
  10. self.total ← 49.5, self.is_large_order ← False, self.has_discount ← True

    72self.total→ 49.5 = self.subtotal55 - self.discount5.57374# Status flags75self.is_large_order→ False = self.total49.5 > 10076self.has_discount→ True = self.discount5.5 > 077self.item_count→ 7 = sum(item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])
  11. order ← ⟨Order D⟩, _next_id ← (empty)

    82]83order→ ⟨Order D⟩ = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")8485print(f"Items: {order.item_count7}")86print(f"Subtotal: ${order.subtotal55}")87print(f"Discount: ${order.discount5.5}")88print(f"Total: ${order.total49.5}")89print(f"Large order? {order.is_large_orderFalse}")9091print("\n=== Timestamp and ID ===")929394class Event:95    _next_id→ (empty) = 1  # Class variable for ID generation96    97    def __init__(self, name, category):98        self.name = name99        self.category = category100        # Auto-generated101        self.id = Event._next_id102        Event._next_id += 1103        self.created_at = 1736937000.0104105e1 = Event("Login", "auth")106e2 = Event("Click", "ui")
    outputItems: 7
    Subtotal: $55
    Discount: $5.5
    Total: $49.5
    Large order? False
    
    === Timestamp and ID ===
  12. self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2

    pass 1 of 3
    97def __init__(self⟨Event E⟩, nameLogin, categoryauth):98    self.name→ Login = nameLogin99    self.category→ auth = categoryauth100    # Auto-generated101    self.id→ 1 = Event._next_id1102    Event._next_id→ 2 += 1103    self.created_at→ 1736937000.0 = 1736937000.0
    All 3 passes — pass 1 is the card above
    passselfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at
    1⟨Event E⟩LoginauthLoginauth11 21736937000.0
    2⟨Event F⟩ClickuiClickui22 31736937000.0
    3⟨Event G⟩PurchasesalePurchasesale33 41736937000.0
  13. e1 ← ⟨Event E⟩

    105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  14. e2 ← ⟨Event F⟩

    105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  15. e3 ← ⟨Event G⟩

    106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")
  16. for e in [e1, e2, e3]:

    pass 1 of 3
    109for e⟨Event E⟩ in [e1⟨Event E⟩, e2⟨Event F⟩, e3⟨Event G⟩]:110    print(f"Event #{e.id1}: {e.nameLogin} ({e.categoryauth})")
    outputEvent #1: Login (auth)
    All 3 passes — pass 1 is the card above
    passee.ide.namee.category
    1⟨Event E⟩1Loginauth
    2⟨Event F⟩2Clickui
    3⟨Event G⟩3Purchasesale
  1. print("=== Computed from Parameters === ")

    3print("=== Computed from Parameters ===\n")45class Rectangle:6    def __init__(self, width, height):7        self.width = width8        self.height = height9        # Computed attributes10        self.area = width * height11        self.perimeter = 2 * (width + height)12        self.diagonal = (width**2 + height**2) ** 0.51314rect = Rectangle(3, 4)15print(f"Rectangle {rect.width}x{rect.height}")
    output=== Computed from Parameters ===
  2. self.width ← 3, self.height ← 4, self.area ← 12, self.perimeter ← 14

    5class Rectangle:6    def __init__(self⟨Rectangle A⟩, width3, height4):7        self.width→ 3 = width38        self.height→ 4 = height49        # Computed attributes10        self.area→ 12 = width3 * height411        self.perimeter→ 14 = 2 * (width3 + height4)12        self.diagonal→ 5.0 = (width3**2 + height4**2) ** 0.5
  3. rect ← ⟨Rectangle A⟩

    14rect→ ⟨Rectangle A⟩ = Rectangle(3, 4)15print(f"Rectangle {rect.width3}x{rect.height4}")16print(f"Area: {rect.area12}")17print(f"Perimeter: {rect.perimeter14}")18print(f"Diagonal: {rect.diagonal5.0}")1920print("\n=== Derived Attributes ===")2122class Person:23    def __init__(self, first_name, last_name, birth_year):24        self.first_name = first_name25        self.last_name = last_name26        self.birth_year = birth_year27        # Derived attributes28        self.full_name = f"{first_name} {last_name}"29        self.age = 2024 - birth_year30        self.initials = f"{first_name[0]}.{last_name[0]}."3132person = Person("John", "Doe", 1990)33print(f"Name: {person.full_name}")
    outputRectangle 3x4
    Area: 12
    Perimeter: 14
    Diagonal: 5.0
    
    === Derived Attributes ===
  4. self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990

    22class Person:23    def __init__(self⟨Person B⟩, first_nameJohn, last_nameDoe, birth_year1990):24        self.first_name→ John = first_nameJohn25        self.last_name→ Doe = last_nameDoe26        self.birth_year→ 1990 = birth_year199027        # Derived attributes28        self.full_name→ John Doe = f"{first_nameJohn} {last_nameDoe}"29        self.age→ 34 = 2024 - birth_year199030        self.initials→ J.D. = f"{first_name[0]J}.{last_name[0]D}."
  5. person ← ⟨Person B⟩

    32person→ ⟨Person B⟩ = Person("John", "Doe", 1990)33print(f"Name: {person.full_nameJohn Doe}")34print(f"Initials: {person.initialsJ.D.}")35print(f"Age: {person.age34}")3637print("\n=== Computed Collections ===")3839class ScoreBoard:40    def __init__(self, scores):41        self.scores = list(scores)  # Copy the list42        # Compute statistics43        self.count = len(self.scores)44        self.total = sum(self.scores)45        self.average = self.total / self.count if self.count else 046        self.highest = max(self.scores) if self.scores else None47        self.lowest = min(self.scores) if self.scores else None4849board = ScoreBoard([70, 80, 90])50print(f"Scores: {board.scores}")
    outputName: John Doe
    Initials: J.D.
    Age: 34
    
    === Computed Collections ===
  6. self.scores ← [70, 80, 90], self.count ← 3, self.total ← 240, self.average ← 80.0

    39class ScoreBoard:40    def __init__(self⟨ScoreBoard C⟩, scores[70, 80, 90]):41        self.scores→ [70, 80, 90] = list(scores[70, 80, 90])  # Copy the list42        # Compute statistics43        self.count→ 3 = len(self.scores[70, 80, 90])44        self.total→ 240 = sum(self.scores[70, 80, 90])45        self.average→ 80.0 = self.total240 / self.count3 if self.count else 046        self.highest→ 90 = max(self.scores[70, 80, 90]) if self.scores else None47        self.lowest→ 70 = min(self.scores[70, 80, 90]) if self.scores else None
  7. board ← ⟨ScoreBoard C⟩, items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    49board→ ⟨ScoreBoard C⟩ = ScoreBoard([70, 80, 90])50print(f"Scores: {board.scores[70, 80, 90]}")51print(f"Count: {board.count3}, Total: {board.total240}")52print(f"Average: {board.average80.0:.1f}")53print(f"High: {board.highest90}, Low: {board.lowest70}")5455print("\n=== Computed Flags/Status ===")5657class Order:58    def __init__(self, items, discount_code=None):59        self.items = items60        self.discount_code = discount_code61        62        # Compute totals63        self.subtotal = sum(item["price"] * item["qty"] for item in items)64        65        # Apply discount66        self.discount = 067        if discount_code == "SAVE10":68            self.discount = self.subtotal * 0.1069        elif discount_code == "SAVE20":70            self.discount = self.subtotal * 0.2071        72        self.total = self.subtotal - self.discount73        74        # Status flags75        self.is_large_order = self.total > 10076        self.has_discount = self.discount > 077        self.item_count = sum(item["qty"] for item in items)7879items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = [80    {"name": "Book", "price": 15, "qty": 2},81    {"name": "Pen", "price": 5, "qty": 5}82]83order = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")
    outputScores: [70, 80, 90]
    Count: 3, Total: 240
    Average: 80.0
    High: 90, Low: 70
    
    === Computed Flags/Status ===
  8. self.items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    57class Order:58    def __init__(self⟨Order D⟩, items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], discount_codeSAVE10=NoneNone):59        self.items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]60        self.discount_code→ SAVE10 = discount_codeSAVE1061        62        # Compute totals63        self.subtotal→ 55 = sum(item["price"](empty) * item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])64        65        # Apply discount66        self.discount→ 0 = 067        if discount_code == "SAVE10":
  9. self.discount ← 5.5

    66self.discount = 067if discount_codeSAVE10 == "SAVE10":68    self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":
  10. self.total ← 49.5, self.is_large_order ← False, self.has_discount ← True

    72self.total→ 49.5 = self.subtotal55 - self.discount5.57374# Status flags75self.is_large_order→ False = self.total49.5 > 10076self.has_discount→ True = self.discount5.5 > 077self.item_count→ 7 = sum(item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])
  11. order ← ⟨Order D⟩, _next_id ← (empty)

    82]83order→ ⟨Order D⟩ = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")8485print(f"Items: {order.item_count7}")86print(f"Subtotal: ${order.subtotal55}")87print(f"Discount: ${order.discount5.5}")88print(f"Total: ${order.total49.5}")89print(f"Large order? {order.is_large_orderFalse}")9091print("\n=== Timestamp and ID ===")929394class Event:95    _next_id→ (empty) = 1  # Class variable for ID generation96    97    def __init__(self, name, category):98        self.name = name99        self.category = category100        # Auto-generated101        self.id = Event._next_id102        Event._next_id += 1103        self.created_at = 1736937000.0104105e1 = Event("Login", "auth")106e2 = Event("Click", "ui")
    outputItems: 7
    Subtotal: $55
    Discount: $5.5
    Total: $49.5
    Large order? False
    
    === Timestamp and ID ===
  12. self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2

    pass 1 of 3
    97def __init__(self⟨Event E⟩, nameLogin, categoryauth):98    self.name→ Login = nameLogin99    self.category→ auth = categoryauth100    # Auto-generated101    self.id→ 1 = Event._next_id1102    Event._next_id→ 2 += 1103    self.created_at→ 1736937000.0 = 1736937000.0
    All 3 passes — pass 1 is the card above
    passselfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at
    1⟨Event E⟩LoginauthLoginauth11 21736937000.0
    2⟨Event F⟩ClickuiClickui22 31736937000.0
    3⟨Event G⟩PurchasesalePurchasesale33 41736937000.0
  13. e1 ← ⟨Event E⟩

    105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  14. e2 ← ⟨Event F⟩

    105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  15. e3 ← ⟨Event G⟩

    106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")
  16. for e in [e1, e2, e3]:

    pass 1 of 3
    109for e⟨Event E⟩ in [e1⟨Event E⟩, e2⟨Event F⟩, e3⟨Event G⟩]:110    print(f"Event #{e.id1}: {e.nameLogin} ({e.categoryauth})")
    outputEvent #1: Login (auth)
    All 3 passes — pass 1 is the card above
    passee.ide.namee.category
    1⟨Event E⟩1Loginauth
    2⟨Event F⟩2Clickui
    3⟨Event G⟩3Purchasesale
  1. print("=== Computed from Parameters === ")

    3print("=== Computed from Parameters ===\n")45class Rectangle:6    def __init__(self, width, height):7        self.width = width8        self.height = height9        # Computed attributes10        self.area = width * height11        self.perimeter = 2 * (width + height)12        self.diagonal = (width**2 + height**2) ** 0.51314rect = Rectangle(3, 4)15print(f"Rectangle {rect.width}x{rect.height}")
    output=== Computed from Parameters ===
  2. self.width ← 3, self.height ← 4, self.area ← 12, self.perimeter ← 14

    5class Rectangle:6    def __init__(self⟨Rectangle A⟩, width3, height4):7        self.width→ 3 = width38        self.height→ 4 = height49        # Computed attributes10        self.area→ 12 = width3 * height411        self.perimeter→ 14 = 2 * (width3 + height4)12        self.diagonal→ 5.0 = (width3**2 + height4**2) ** 0.5
  3. rect ← ⟨Rectangle A⟩

    14rect→ ⟨Rectangle A⟩ = Rectangle(3, 4)15print(f"Rectangle {rect.width3}x{rect.height4}")16print(f"Area: {rect.area12}")17print(f"Perimeter: {rect.perimeter14}")18print(f"Diagonal: {rect.diagonal5.0}")1920print("\n=== Derived Attributes ===")2122class Person:23    def __init__(self, first_name, last_name, birth_year):24        self.first_name = first_name25        self.last_name = last_name26        self.birth_year = birth_year27        # Derived attributes28        self.full_name = f"{first_name} {last_name}"29        self.age = 2024 - birth_year30        self.initials = f"{first_name[0]}.{last_name[0]}."3132person = Person("John", "Doe", 1990)33print(f"Name: {person.full_name}")
    outputRectangle 3x4
    Area: 12
    Perimeter: 14
    Diagonal: 5.0
    
    === Derived Attributes ===
  4. self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990

    22class Person:23    def __init__(self⟨Person B⟩, first_nameJohn, last_nameDoe, birth_year1990):24        self.first_name→ John = first_nameJohn25        self.last_name→ Doe = last_nameDoe26        self.birth_year→ 1990 = birth_year199027        # Derived attributes28        self.full_name→ John Doe = f"{first_nameJohn} {last_nameDoe}"29        self.age→ 34 = 2024 - birth_year199030        self.initials→ J.D. = f"{first_name[0]J}.{last_name[0]D}."
  5. person ← ⟨Person B⟩

    32person→ ⟨Person B⟩ = Person("John", "Doe", 1990)33print(f"Name: {person.full_nameJohn Doe}")34print(f"Initials: {person.initialsJ.D.}")35print(f"Age: {person.age34}")3637print("\n=== Computed Collections ===")3839class ScoreBoard:40    def __init__(self, scores):41        self.scores = list(scores)  # Copy the list42        # Compute statistics43        self.count = len(self.scores)44        self.total = sum(self.scores)45        self.average = self.total / self.count if self.count else 046        self.highest = max(self.scores) if self.scores else None47        self.lowest = min(self.scores) if self.scores else None4849board = ScoreBoard([100, 95])50print(f"Scores: {board.scores}")
    outputName: John Doe
    Initials: J.D.
    Age: 34
    
    === Computed Collections ===
  6. self.scores ← [100, 95], self.count ← 2, self.total ← 195, self.average ← 97.5

    39class ScoreBoard:40    def __init__(self⟨ScoreBoard C⟩, scores[100, 95]):41        self.scores→ [100, 95] = list(scores[100, 95])  # Copy the list42        # Compute statistics43        self.count→ 2 = len(self.scores[100, 95])44        self.total→ 195 = sum(self.scores[100, 95])45        self.average→ 97.5 = self.total195 / self.count2 if self.count else 046        self.highest→ 100 = max(self.scores[100, 95]) if self.scores else None47        self.lowest→ 95 = min(self.scores[100, 95]) if self.scores else None
  7. board ← ⟨ScoreBoard C⟩, items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    49board→ ⟨ScoreBoard C⟩ = ScoreBoard([100, 95])50print(f"Scores: {board.scores[100, 95]}")51print(f"Count: {board.count2}, Total: {board.total195}")52print(f"Average: {board.average97.5:.1f}")53print(f"High: {board.highest100}, Low: {board.lowest95}")5455print("\n=== Computed Flags/Status ===")5657class Order:58    def __init__(self, items, discount_code=None):59        self.items = items60        self.discount_code = discount_code61        62        # Compute totals63        self.subtotal = sum(item["price"] * item["qty"] for item in items)64        65        # Apply discount66        self.discount = 067        if discount_code == "SAVE10":68            self.discount = self.subtotal * 0.1069        elif discount_code == "SAVE20":70            self.discount = self.subtotal * 0.2071        72        self.total = self.subtotal - self.discount73        74        # Status flags75        self.is_large_order = self.total > 10076        self.has_discount = self.discount > 077        self.item_count = sum(item["qty"] for item in items)7879items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = [80    {"name": "Book", "price": 15, "qty": 2},81    {"name": "Pen", "price": 5, "qty": 5}82]83order = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")
    outputScores: [100, 95]
    Count: 2, Total: 195
    Average: 97.5
    High: 100, Low: 95
    
    === Computed Flags/Status ===
  8. self.items ← [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]

    57class Order:58    def __init__(self⟨Order D⟩, items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], discount_codeSAVE10=NoneNone):59        self.items→ [{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}] = items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}]60        self.discount_code→ SAVE10 = discount_codeSAVE1061        62        # Compute totals63        self.subtotal→ 55 = sum(item["price"](empty) * item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])64        65        # Apply discount66        self.discount→ 0 = 067        if discount_code == "SAVE10":
  9. self.discount ← 5.5

    66self.discount = 067if discount_codeSAVE10 == "SAVE10":68    self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":
  10. self.total ← 49.5, self.is_large_order ← False, self.has_discount ← True

    72self.total→ 49.5 = self.subtotal55 - self.discount5.57374# Status flags75self.is_large_order→ False = self.total49.5 > 10076self.has_discount→ True = self.discount5.5 > 077self.item_count→ 7 = sum(item["qty"](empty) for item in items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}])
  11. order ← ⟨Order D⟩, _next_id ← (empty)

    82]83order→ ⟨Order D⟩ = Order(items[{'name': 'Book', 'price': 15, 'qty': 2}, {'name': 'Pen', 'price': 5, 'qty': 5}], "SAVE10")8485print(f"Items: {order.item_count7}")86print(f"Subtotal: ${order.subtotal55}")87print(f"Discount: ${order.discount5.5}")88print(f"Total: ${order.total49.5}")89print(f"Large order? {order.is_large_orderFalse}")9091print("\n=== Timestamp and ID ===")929394class Event:95    _next_id→ (empty) = 1  # Class variable for ID generation96    97    def __init__(self, name, category):98        self.name = name99        self.category = category100        # Auto-generated101        self.id = Event._next_id102        Event._next_id += 1103        self.created_at = 1736937000.0104105e1 = Event("Login", "auth")106e2 = Event("Click", "ui")
    outputItems: 7
    Subtotal: $55
    Discount: $5.5
    Total: $49.5
    Large order? False
    
    === Timestamp and ID ===
  12. self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2

    pass 1 of 3
    97def __init__(self⟨Event E⟩, nameLogin, categoryauth):98    self.name→ Login = nameLogin99    self.category→ auth = categoryauth100    # Auto-generated101    self.id→ 1 = Event._next_id1102    Event._next_id→ 2 += 1103    self.created_at→ 1736937000.0 = 1736937000.0
    All 3 passes — pass 1 is the card above
    passselfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at
    1⟨Event E⟩LoginauthLoginauth11 21736937000.0
    2⟨Event F⟩ClickuiClickui22 31736937000.0
    3⟨Event G⟩PurchasesalePurchasesale33 41736937000.0
  13. e1 ← ⟨Event E⟩

    105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  14. e2 ← ⟨Event F⟩

    105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")
  15. e3 ← ⟨Event G⟩

    106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")
  16. for e in [e1, e2, e3]:

    pass 1 of 3
    109for e⟨Event E⟩ in [e1⟨Event E⟩, e2⟨Event F⟩, e3⟨Event G⟩]:110    print(f"Event #{e.id1}: {e.nameLogin} ({e.categoryauth})")
    outputEvent #1: Login (auth)
    All 3 passes — pass 1 is the card above
    passee.ide.namee.category
    1⟨Event E⟩1Loginauth
    2⟨Event F⟩2Clickui
    3⟨Event G⟩3Purchasesale

Store computed values: self.area = width * height.

Common initialization patterns

Flexible constructors with various parameter styles.

init_patterns.py
Replay: real traced execution (multi-file project)
# Common Initialization Patterns

print("=== Factory-Style Constructor ===\n")

class Color:
    def __init__(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b

    @classmethod
    def from_hex(cls, hex_code):
        """Create Color from hex string like '#FF0000'"""
        hex_code = hex_code.lstrip('#')
        r = int(hex_code[0:2], 16)
        g = int(hex_code[2:4], 16)
        b = int(hex_code[4:6], 16)
        return cls(r, g, b)

    @classmethod
    def from_name(cls, name):
        colors = {
            "red": (255, 0, 0),
            "green": (0, 255, 0),
            "blue": (0, 0, 255),
            "white": (255, 255, 255),
            "black": (0, 0, 0)
        }
        rgb = colors.get(name.lower(), (0, 0, 0))
        return cls(*rgb)

    def __str__(self):
        return f"RGB({self.r}, {self.g}, {self.b})"

# Multiple ways to create
c1 = Color(255, 128, 0)  # Direct
c2 = Color.from_hex("#00FF00")  # From hex
c3 = Color.from_name("blue")  # From name

print(f"Direct: {c1}")
print(f"From hex: {c2}")
print(f"From name: {c3}")

print("\n=== Configuration Object ===")

class Config:
    def __init__(self, **kwargs):
        # Set defaults
        self.debug = False
        self.log_level = "INFO"
        self.max_connections = 100
        self.timeout = 30

        # Override with provided values
        for key, value in kwargs.items():
            if hasattr(self, key):
                setattr(self, key, value)
            else:
                print(f"Warning: Unknown config '{key}'")

    def display(self):
        print(f"  debug: {self.debug}")
        print(f"  log_level: {self.log_level}")
        print(f"  max_connections: {self.max_connections}")
        print(f"  timeout: {self.timeout}")

# Default config
cfg1 = Config()
print("Default config:")
cfg1.display()

# Custom config
cfg2 = Config(debug=True, timeout=60, unknown="ignored")
print("\nCustom config:")
cfg2.display()

print("\n=== Copy Constructor Pattern ===")

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def copy(self):
        """Create a copy of this point"""
        return Point(self.x, self.y)

    @classmethod
    def from_point(cls, other):
        """Create from another Point"""
        return cls(other.x, other.y)

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

p1 = Point(10, 20)
p2 = p1.copy()  # Using instance method
p3 = Point.from_point(p1)  # Using classmethod

p2.x = 100  # Change copy
print(f"Original: {p1}")
print(f"Copy (changed): {p2}")
print(f"From point: {p3}")

print("\n=== Dependent Initialization ===")

class Database:
    def __init__(self, host, port, database):
        self.host = host
        self.port = port
        self.database = database
        # Build connection string
        self.connection_string = f"db://{host}:{port}/{database}"
        # Initialize state
        self.connected = False
        self.queries_run = 0

    def connect(self):
        print(f"Connecting to {self.connection_string}...")
        self.connected = True

    def query(self, sql):
        if not self.connected:
            raise RuntimeError("Not connected")
        self.queries_run += 1
        print(f"Running query #{self.queries_run}: {sql}")

db = Database("localhost", 5432, "myapp")
print(f"Connection string: {db.connection_string}")
db.connect()
db.query("SELECT * FROM users")
  1. print("=== Factory-Style Constructor === ")

    3print("=== Factory-Style Constructor ===\n")45class Color:6    def __init__(self, r, g, b):7        self.r = r8        self.g = g9        self.b = b10    11    @classmethod12    def from_hex(cls, hex_code):  #?classmethod13        """Create Color from hex string like '#FF0000'"""  #?docstring14        hex_code = hex_code.lstrip('#')  #?striphash15        r = int(hex_code[0:2], 16)  #?parseint16        g = int(hex_code[2:4], 16)17        b = int(hex_code[4:6], 16)18        return cls(r, g, b)  #?returncls19    20    @classmethod21    def from_name(cls, name):  #?namedcolors22        colors = {23            "red": (255, 0, 0),24            "green": (0, 255, 0),25            "blue": (0, 0, 255),26            "white": (255, 255, 255),27            "black": (0, 0, 0)28        }29        rgb = colors.get(name.lower(), (0, 0, 0))30        return cls(*rgb)  #?unpacktuple31    32    def __str__(self):33        return f"RGB({self.r}, {self.g}, {self.b})"3435# Multiple ways to create  #?multiway36c1 = Color(255, 128, 0)  # Direct37c2 = Color.from_hex("#00FF00")  # From hex
    output=== Factory-Style Constructor ===
  2. self.r ← 255, self.g ← 128, self.b ← 0

    pass 1 of 3
    5class Color:6    def __init__(self(empty), r255, g128, b0):7        self.r→ 255 = r2558        self.g→ 128 = g1289        self.b→ 0 = b0
    All 3 passes — pass 1 is the card above
    passrgbself.rself.gself.b
    125512802551280
    20255002550
    30025500255
  3. c1 ← RGB(255, 128, 0)

    35# Multiple ways to create  #?multiway36c1→ RGB(255, 128, 0) = Color(255, 128, 0)  # Direct37c2 = Color<class '__main__.Color'>.from_hex("#00FF00")  # From hex38c3 = Color.from_name("blue")  # From name
  4. hex_code ← 00FF00, r ← 0, g ← 255, b ← 0

    11@classmethod12def from_hex(cls<class '__main__.Color'>, hex_code#00FF00):  #?classmethod13    """Create Color from hex string like '#FF0000'"""  #?docstring14    hex_code→ 00FF00 = hex_code.lstrip('#')  #?striphash15    r→ 0 = int(hex_code[0:2]00, 16)  #?parseint16    g→ 255 = int(hex_code[2:4]FF, 16)17    b→ 0 = int(hex_code[4:6]00, 16)18    return cls(r0, g255, b0)  #?returncls
  5. c2 ← RGB(0, 255, 0)

    36c1 = Color(255, 128, 0)  # Direct37c2→ RGB(0, 255, 0) = Color<class '__main__.Color'>.from_hex("#00FF00")  # From hex38c3 = Color<class '__main__.Color'>.from_name("blue")  # From name
  6. colors ← {'red': (255, 0, 0), 'green': (0, 255, 0), 'blue': (0, 0, 255), 'white': (255, 255, 255), 'black': (0, 0, 0)}

    20@classmethod21def from_name(cls<class '__main__.Color'>, nameblue):  #?namedcolors22    colors→ {'red': (255, 0, 0), 'green': (0, 255, 0), 'blue': (0, 0, 255), 'white': (255, 255, 255), 'black': (0, 0, 0)} = {23        "red": (255, 0, 0),24        "green": (0, 255, 0),25        "blue": (0, 0, 255),26        "white": (255, 255, 255),27        "black": (0, 0, 0)28    }29    rgb→ (0, 0, 255) = colors{'red': (255, 0, 0), 'green': (0, 255, 0), 'blue': (0, 0, 255), 'white': (255, 255, 255), 'black': (0, 0, 0)}.get(nameblue.lower(), (0, 0, 0))30    return cls(*rgb(0, 0, 255))  #?unpacktuple
  7. c3 ← RGB(0, 0, 255)

    37c2 = Color.from_hex("#00FF00")  # From hex38c3→ RGB(0, 0, 255) = Color<class '__main__.Color'>.from_name("blue")  # From name3940print(f"Direct: {c1RGB(255, 128, 0)}")41print(f"From hex: {c2RGB(0, 255, 0)}")42print(f"From name: {c3RGB(0, 0, 255)}")4344print("\n=== Configuration Object ===")4546class Config:47    def __init__(self, **kwargs):  #?kwargs48        # Set defaults  #?setdefaults49        self.debug = False50        self.log_level = "INFO"51        self.max_connections = 10052        self.timeout = 3053        54        # Override with provided values  #?override55        for key, value in kwargs.items():  #?iteratekwargs56            if hasattr(self, key):  #?hasattr57                setattr(self, key, value)  #?setattr58            else:59                print(f"Warning: Unknown config '{key}'")60    61    def display(self):62        print(f"  debug: {self.debug}")63        print(f"  log_level: {self.log_level}")64        print(f"  max_connections: {self.max_connections}")65        print(f"  timeout: {self.timeout}")6667# Default config68cfg1 = Config()69print("Default config:")
    outputDirect: RGB(255, 128, 0)
    From hex: RGB(0, 255, 0)
    From name: RGB(0, 0, 255)
    
    === Configuration Object ===
  8. self.debug ← False, self.log_level ← INFO, self.max_connections ← 100

    pass 1 of 2
    46class Config:47    def __init__(self⟨Config A⟩, **kwargs):  #?kwargs48        # Set defaults  #?setdefaults49        self.debug→ False = False50        self.log_level→ INFO = "INFO"51        self.max_connections→ 100 = 10052        self.timeout→ 30 = 30
  9. cfg1 ← ⟨Config A⟩

    67# Default config68cfg1→ ⟨Config A⟩ = Config()69print("Default config:")70cfg1⟨Config A⟩.display()
    outputDefault config:
  10. def display(self):

    pass 1 of 2
    61def display(self⟨Config A⟩):62    print(f"  debug: {self.debugFalse}")63    print(f"  log_level: {self.log_levelINFO}")64    print(f"  max_connections: {self.max_connections100}")65    print(f"  timeout: {self.timeout30}")
    output  debug: False
      log_level: INFO
      max_connections: 100
      timeout: 30
  11. cfg1.display()

    69print("Default config:")70cfg1⟨Config A⟩.display()7172# Custom config  #?customconfig73cfg2 = Config(debug=True, timeout=60, unknown="ignored")74print("\nCustom config:")
  12. self.debug ← False, self.log_level ← INFO, self.max_connections ← 100

    pass 2 of 2
    46class Config:47    def __init__(self⟨Config B⟩, **kwargs):  #?kwargs48        # Set defaults  #?setdefaults49        self.debug→ False = False50        self.log_level→ INFO = "INFO"51        self.max_connections→ 100 = 10052        self.timeout→ 30 = 30
  13. for key, value in kwargs.items(): #?iteratekwargs

    pass 1 of 3
    54# Override with provided values  #?override55for keydebug, valueTrue in kwargs{'debug': True, 'timeout': 60, 'unknown': 'ignored'}.items():  #?iteratekwargs56    if hasattr(self, key):  #?hasattr57        setattr(self, key, value)  #?setattr
    All 3 passes — pass 1 is the card above
    passkeyvalue
    1debugTrue
    2timeout60
    3unknownignored
  14. if hasattr(self, key): #?hasattr

    pass 1 of 2
    55for key, value in kwargs.items():  #?iteratekwargs56    if hasattr(self, keydebug):  #?hasattr57        setattr(self, keydebug, valueTrue)  #?setattr58    else:
  15. if hasattr(self, key): #?hasattr

    pass 2 of 2
    55for key, value in kwargs.items():  #?iteratekwargs56    if hasattr(self, keytimeout):  #?hasattr57        setattr(self, keytimeout, value60)  #?setattr58    else:
  16. #?setattr else:

    56if hasattr(self, key):  #?hasattr57    setattr(self, key, value)  #?setattr58else:59    print(f"Warning: Unknown config '{keyunknown}'")
    outputWarning: Unknown config 'unknown'
  17. cfg2 ← ⟨Config B⟩

    72# Custom config  #?customconfig73cfg2→ ⟨Config B⟩ = Config(debug=True, timeout=60, unknown="ignored")74print("\nCustom config:")75cfg2⟨Config B⟩.display()
    output
    Custom config:
  18. def display(self):

    pass 2 of 2
    61def display(self⟨Config B⟩):62    print(f"  debug: {self.debugTrue}")63    print(f"  log_level: {self.log_levelINFO}")64    print(f"  max_connections: {self.max_connections100}")65    print(f"  timeout: {self.timeout60}")
    output  debug: True
      log_level: INFO
      max_connections: 100
      timeout: 60
  19. cfg2.display()

    74print("\nCustom config:")75cfg2⟨Config B⟩.display()7677print("\n=== Copy Constructor Pattern ===")7879class Point:80    def __init__(self, x=0, y=0):81        self.x = x82        self.y = y83    84    def copy(self):  #?copymethod85        """Create a copy of this point"""86        return Point(self.x, self.y)87    88    @classmethod89    def from_point(cls, other):  #?frompoint90        """Create from another Point"""91        return cls(other.x, other.y)92    93    def __repr__(self):94        return f"Point({self.x}, {self.y})"9596p1 = Point(10, 20)97p2 = p1.copy()  # Using instance method  #?usecopy
    output
    === Copy Constructor Pattern ===
  20. self.x ← 10, self.y ← 20

    pass 1 of 3
    79class Point:80    def __init__(self(empty), x10=0, y20=0):81        self.x→ 10 = x1082        self.y→ 20 = y20
    All 3 passes — pass 1 is the card above
    passself.xself.y
    11020
    21020
    31020
  21. p1 ← Point(10, 20)

    96p1→ Point(10, 20) = Point(10, 20)97p2 = p1Point(10, 20).copy()  # Using instance method  #?usecopy98p3 = Point.from_point(p1)  # Using classmethod
  22. def copy(self): #?copymethod

    84def copy(selfPoint(10, 20)):  #?copymethod85    """Create a copy of this point"""86    return Point(self.x10, self.y20)
  23. p2 ← Point(10, 20)

    96p1 = Point(10, 20)97p2→ Point(10, 20) = p1Point(10, 20).copy()  # Using instance method  #?usecopy98p3 = Point<class '__main__.Point'>.from_point(p1Point(10, 20))  # Using classmethod
  24. def from_point(cls, other): #?frompoint

    88@classmethod89def from_point(cls<class '__main__.Point'>, otherPoint(10, 20)):  #?frompoint90    """Create from another Point"""91    return cls(other.x10, other.y20)
  25. p3 ← Point(10, 20), p2.x ← 100

    97p2 = p1.copy()  # Using instance method  #?usecopy98p3→ Point(10, 20) = Point<class '__main__.Point'>.from_point(p1Point(10, 20))  # Using classmethod99100p2.x→ 100 = 100  # Change copy101print(f"Original: {p1Point(10, 20)}")102print(f"Copy (changed): {p2Point(100, 20)}")103print(f"From point: {p3Point(10, 20)}")104105print("\n=== Dependent Initialization ===")106107class Database:108    def __init__(self, host, port, database):109        self.host = host110        self.port = port111        self.database = database112        # Build connection string  #?connstring113        self.connection_string = f"db://{host}:{port}/{database}"114        # Initialize state  #?initstate115        self.connected = False116        self.queries_run = 0117    118    def connect(self):119        print(f"Connecting to {self.connection_string}...")120        self.connected = True121    122    def query(self, sql):123        if not self.connected:124            raise RuntimeError("Not connected")125        self.queries_run += 1126        print(f"Running query #{self.queries_run}: {sql}")127128db = Database("localhost", 5432, "myapp")129print(f"Connection string: {db.connection_string}")
    outputOriginal: Point(10, 20)
    Copy (changed): Point(100, 20)
    From point: Point(10, 20)
    
    === Dependent Initialization ===
  26. self.host ← localhost, self.port ← 5432, self.database ← myapp

    107class Database:108    def __init__(self⟨Database C⟩, hostlocalhost, port5432, databasemyapp):109        self.host→ localhost = hostlocalhost110        self.port→ 5432 = port5432111        self.database→ myapp = databasemyapp112        # Build connection string  #?connstring113        self.connection_string→ db://localhost:5432/myapp = f"db://{hostlocalhost}:{port5432}/{databasemyapp}"114        # Initialize state  #?initstate115        self.connected→ False = False116        self.queries_run→ 0 = 0
  27. db ← ⟨Database C⟩

    128db→ ⟨Database C⟩ = Database("localhost", 5432, "myapp")129print(f"Connection string: {db.connection_stringdb://localhost:5432/myapp}")130db⟨Database C⟩.connect()131db.query("SELECT * FROM users")
    outputConnection string: db://localhost:5432/myapp
  28. self.connected ← True

    118def connect(self⟨Database C⟩):119    print(f"Connecting to {self.connection_stringdb://localhost:5432/myapp}...")120    self.connected→ True = True
    outputConnecting to db://localhost:5432/myapp...
  29. db.connect()

    129print(f"Connection string: {db.connection_string}")130db⟨Database C⟩.connect()131db⟨Database C⟩.query("SELECT * FROM users")132#@help classmethod
  30. self.queries_run ← 1

    122def query(self⟨Database C⟩, sqlSELECT * FROM users):123    if not self.connected:124        raise RuntimeError("Not connected")125    self.queries_run→ 1 += 1126    print(f"Running query #{self.queries_run1}: {sqlSELECT * FROM users}")
    outputRunning query #1: SELECT * FROM users
  31. db.query("SELECT * FROM users")

    130db.connect()131db⟨Database C⟩.query("SELECT * FROM users")132#@help classmethod

Use *args, **kwargs, or factory methods for flexible initialization.

Exercise: practical.py

Build a class with validation and computed attributes