Object-Oriented Basics
__init__
The Constructor
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__ 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())
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 ===self.name ← Buddy, self.breed ← Golden Retriever
pass 1 of 25class 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 RetrieveroutputCreating dog: Buddy, Golden Retrieverbuddy ← ⟨Dog A⟩
11# Create dogs - __init__ called automatically #?createcall12buddy→ ⟨Dog A⟩ = Dog("Buddy", "Golden Retriever") #?passargs13max_dog = Dog("Max", "German Shepherd")self.name ← Max, self.breed ← German Shepherd
pass 2 of 25class 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 ShepherdoutputCreating dog: Max, German Shepherdmax_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 ===self.x ← 3, self.y ← 4
34class Point:35 def __init__(self⟨Point D⟩, x3, y4):36 self.x→ 3 = x337 self.y→ 4 = y4p ← ⟨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 ===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 = height50rect ← ⟨Rectangle F⟩
63rect→ ⟨Rectangle F⟩ = Rectangle(10, 20, 100, 50)64print(rect⟨Rectangle F⟩.describe())65#@help initdef describe(self):
60def describe(self⟨Rectangle F⟩):61 return f"Rectangle at ({self.x10},{self.y20}) size {self.width100}x{self.height50}"print(rect.describe())
63rect = Rectangle(10, 20, 100, 50)64print(rect⟨Rectangle F⟩.describe())65#@help initoutputRectangle at (10,20) size 100x50
__init__ runs when object is created. Sets up initial state.
Default parameter values
Make some parameters optional.
# 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}")
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 #?partialdefaultoutput=== Default Parameter Values ===self.username ← admin, self.role ← administrator, self.active ← True
pass 1 of 55class User:6 def __init__(self⟨User A⟩, usernameadmin, roleadministrator="user", activeTrue=TrueTrue): #?defaults7 self.username→ admin = usernameadmin8 self.role→ administrator = roleadministrator9 self.active→ True = activeTrueAll 5 passes — pass 1 is the card above pass selfusernameroleactiveself.usernameself.roleself.active1 ⟨User A⟩ admin administrator True admin administrator True 2 ⟨User B⟩ alice editor True alice editor True 3 ⟨User C⟩ bob user True bob user True 4 ⟨User D⟩ guest user False guest user False 5 ⟨User E⟩ mod moderator True mod moderator True 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 #?alldefaultsalice ← ⟨User B⟩
16admin = User("admin", "administrator", True) # All explicit #?allexplicit17alice→ ⟨User B⟩ = User("alice", "editor") # Default active #?partialdefault18bob = User("bob") # All defaults #?alldefaultsbob ← ⟨User C⟩
17alice = User("alice", "editor") # Default active #?partialdefault18bob→ ⟨User C⟩ = User("bob") # All defaults #?alldefaults1920print(admin⟨User A⟩.describe())21print(alice.describe())status ← active
pass 1 of 511def 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 pass selfself.activeself.usernameself.rolestatus1 ⟨User A⟩ True admin administrator active 2 ⟨User B⟩ True alice editor active 3 ⟨User C⟩ True bob user active 4 ⟨User D⟩ False guest user inactive 5 ⟨User E⟩ True mod moderator active print(admin.describe())
20print(admin⟨User A⟩.describe())21print(alice⟨User B⟩.describe())22print(bob.describe())outputadmin (administrator, active)print(alice.describe())
20print(admin.describe())21print(alice⟨User B⟩.describe())22print(bob⟨User C⟩.describe())outputalice (editor, active)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 ===guest ← ⟨User D⟩
26# Use named args to skip defaults #?namedargs27guest→ ⟨User D⟩ = User("guest", active=False) # Skip role #?skiparg28print(guest⟨User D⟩.describe())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)mod ← ⟨User E⟩
30# Mix positional and named #?mixargs31mod→ ⟨User E⟩ = User("mod", role="moderator")32print(mod⟨User E⟩.describe())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 ===self.items ← []
pass 1 of 237class BadList:38 def __init__(self⟨BadList F⟩, items[]=[]): #?baddefault39 self.items→ [] = items[]bad1 ← ⟨BadList F⟩
41bad1→ ⟨BadList F⟩ = BadList()42bad2 = BadList()43bad1.items.append("item1")self.items ← []
pass 2 of 237class BadList:38 def __init__(self⟨BadList G⟩, items[]=[]): #?baddefault39 self.items→ [] = items[]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 ===self.items ← []
pass 1 of 250class GoodList:51 def __init__(self⟨GoodList H⟩, itemsNone=NoneNone): #?nonedefault52 self.items→ [] = itemsNone if items else [] #?createlistgood1 ← ⟨GoodList H⟩
54good1→ ⟨GoodList H⟩ = GoodList()55good2 = GoodList()56good1.items.append("item1")self.items ← []
pass 2 of 250class GoodList:51 def __init__(self⟨GoodList I⟩, itemsNone=NoneNone): #?nonedefault52 self.items→ [] = itemsNone if items else [] #?createlistgood2 ← ⟨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 ===self.name ← Hero, self.health ← 100, self.inventory ← [], self.position ← {'x': 0, 'y': 0}
pass 1 of 262class 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.0hero ← ⟨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: []self.name ← Wizard, self.health ← 80, self.inventory ← ['staff', 'spellbook']
pass 2 of 262class 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.5wizard ← ⟨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 defaultsoutput 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.
# 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}")
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 ===self.years ← 25
pass 1 of 25class 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 #?setvalidage1 ← ⟨Age A⟩
15# Valid ages16age1→ ⟨Age A⟩ = Age(25)17age2 = Age(0)18print(f"Valid ages: {age1.years}, {age2.years}")self.years ← 0
pass 2 of 25class 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 #?setvalidage2 ← ⟨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") # LowercasedoutputValid ages: 25, 0 === Validation with Correction ===name ← Alice, self.name ← alice
pass 1 of 327class 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 = namealiceAll 3 passes — pass 1 is the card above pass selfname[:20]nameself.name1 ⟨Username C⟩ — Alice → Alice alice 2 ⟨Username D⟩ — BOB bob 3 ⟨Username E⟩ verylongusernamethat VeryLongUsernameThatExceedsLimit — user1 ← ⟨Username C⟩
43user1→ ⟨Username C⟩ = Username(" Alice ") # Whitespace removed44user2 = Username("BOB") # Lowercased45user3 = Username("VeryLongUsernameThatExceedsLimit") # Truncateduser2 ← ⟨Username D⟩
43user1 = Username(" Alice ") # Whitespace removed44user2→ ⟨Username D⟩ = Username("BOB") # Lowercased45user3 = Username("VeryLongUsernameThatExceedsLimit") # Truncatedname ← verylongusernamethat
37 raise ValueError("Username must be at least 3 characters")38if len(nameverylongusernamethatexceedslimit) > 20:39 name→ verylongusernamethat = name[:20]verylongusernamethat # Truncate #?truncateself.name ← verylongusernamethat
41self.name→ verylongusernamethat = nameverylongusernamethatuser3 ← ⟨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 #?adjustedoutput'alice' 'bob' 'verylongusernamethat' (len=20) === Validation with Defaults ===self.celsius ← 25
pass 1 of 253class 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 = celsius25t1 ← ⟨Temperature F⟩
65t1→ ⟨Temperature F⟩ = Temperature(25)66t2 = Temperature(-300) # Adjusted #?adjusteddef __init__(self, celsius): # Clamp to valid range #?clamp
pass 2 of 253class 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")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 = celsiusoutputWarning: -300 adjusted to -273.15self.celsius ← -273.15
58 celsius = -273.1559self.celsius→ -273.15 = celsius-273.15t2 ← ⟨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 ===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.comemail ← ⟨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 ===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 = quantity5laptop ← ⟨Product I⟩
123laptop→ ⟨Product I⟩ = Product(" Laptop ", 999.999, 5)124print(f"Product: {laptop.nameLaptop}, ${laptop.price1000.0}, qty={laptop.quantity5}")125#@help typecheckoutputProduct: Laptop, $1000.0, qty=5
Raise exceptions in __init__ to prevent invalid objects from existing.
Computed attributes
Calculate attributes from parameters.
# 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})")
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 ===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 #?diagonalrect ← ⟨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 ===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}." #?initialsperson ← ⟨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 ===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 Noneboard ← ⟨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 ===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":self.discount ← 5.5
66self.discount = 067if discount_codeSAVE10 == "SAVE10":68 self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":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}])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 ===self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2
pass 1 of 397def __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 #?timestampAll 3 passes — pass 1 is the card above pass selfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at1 ⟨Event E⟩ Login auth Login auth 1 1 → 2 1736937000.0 2 ⟨Event F⟩ Click ui Click ui 2 2 → 3 1736937000.0 3 ⟨Event G⟩ Purchase sale Purchase sale 3 3 → 4 1736937000.0 e1 ← ⟨Event E⟩
105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")e2 ← ⟨Event F⟩
105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")e3 ← ⟨Event G⟩
106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")for e in [e1, e2, e3]:
pass 1 of 3109for 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 computedoutputEvent #1: Login (auth)All 3 passes — pass 1 is the card above pass ee.ide.namee.category1 ⟨Event E⟩ 1 Login auth 2 ⟨Event F⟩ 2 Click ui 3 ⟨Event G⟩ 3 Purchase sale
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 ===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.5rect ← ⟨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 ===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}."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 ===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 Noneboard ← ⟨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 ===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":self.discount ← 5.5
66self.discount = 067if discount_codeSAVE10 == "SAVE10":68 self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":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}])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 ===self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2
pass 1 of 397def __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.0All 3 passes — pass 1 is the card above pass selfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at1 ⟨Event E⟩ Login auth Login auth 1 1 → 2 1736937000.0 2 ⟨Event F⟩ Click ui Click ui 2 2 → 3 1736937000.0 3 ⟨Event G⟩ Purchase sale Purchase sale 3 3 → 4 1736937000.0 e1 ← ⟨Event E⟩
105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")e2 ← ⟨Event F⟩
105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")e3 ← ⟨Event G⟩
106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")for e in [e1, e2, e3]:
pass 1 of 3109for 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 pass ee.ide.namee.category1 ⟨Event E⟩ 1 Login auth 2 ⟨Event F⟩ 2 Click ui 3 ⟨Event G⟩ 3 Purchase sale
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 ===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.5rect ← ⟨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 ===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}."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 ===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 Noneboard ← ⟨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 ===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":self.discount ← 5.5
66self.discount = 067if discount_codeSAVE10 == "SAVE10":68 self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":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}])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 ===self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2
pass 1 of 397def __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.0All 3 passes — pass 1 is the card above pass selfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at1 ⟨Event E⟩ Login auth Login auth 1 1 → 2 1736937000.0 2 ⟨Event F⟩ Click ui Click ui 2 2 → 3 1736937000.0 3 ⟨Event G⟩ Purchase sale Purchase sale 3 3 → 4 1736937000.0 e1 ← ⟨Event E⟩
105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")e2 ← ⟨Event F⟩
105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")e3 ← ⟨Event G⟩
106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")for e in [e1, e2, e3]:
pass 1 of 3109for 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 pass ee.ide.namee.category1 ⟨Event E⟩ 1 Login auth 2 ⟨Event F⟩ 2 Click ui 3 ⟨Event G⟩ 3 Purchase sale
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 ===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.5rect ← ⟨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 ===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}."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 ===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 Noneboard ← ⟨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 ===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":self.discount ← 5.5
66self.discount = 067if discount_codeSAVE10 == "SAVE10":68 self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":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}])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 ===self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2
pass 1 of 397def __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.0All 3 passes — pass 1 is the card above pass selfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at1 ⟨Event E⟩ Login auth Login auth 1 1 → 2 1736937000.0 2 ⟨Event F⟩ Click ui Click ui 2 2 → 3 1736937000.0 3 ⟨Event G⟩ Purchase sale Purchase sale 3 3 → 4 1736937000.0 e1 ← ⟨Event E⟩
105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")e2 ← ⟨Event F⟩
105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")e3 ← ⟨Event G⟩
106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")for e in [e1, e2, e3]:
pass 1 of 3109for 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 pass ee.ide.namee.category1 ⟨Event E⟩ 1 Login auth 2 ⟨Event F⟩ 2 Click ui 3 ⟨Event G⟩ 3 Purchase sale
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 ===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.5rect ← ⟨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 ===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}."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 ===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 Noneboard ← ⟨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 ===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":self.discount ← 5.5
66self.discount = 067if discount_codeSAVE10 == "SAVE10":68 self.discount→ 5.5 = self.subtotal55 * 0.1069elif discount_code == "SAVE20":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}])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 ===self.name ← Login, self.category ← auth, self.id ← 1, Event._next_id ← 2
pass 1 of 397def __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.0All 3 passes — pass 1 is the card above pass selfnamecategoryself.nameself.categoryself.idEvent._next_idself.created_at1 ⟨Event E⟩ Login auth Login auth 1 1 → 2 1736937000.0 2 ⟨Event F⟩ Click ui Click ui 2 2 → 3 1736937000.0 3 ⟨Event G⟩ Purchase sale Purchase sale 3 3 → 4 1736937000.0 e1 ← ⟨Event E⟩
105e1→ ⟨Event E⟩ = Event("Login", "auth")106e2 = Event("Click", "ui")107e3 = Event("Purchase", "sale")e2 ← ⟨Event F⟩
105e1 = Event("Login", "auth")106e2→ ⟨Event F⟩ = Event("Click", "ui")107e3 = Event("Purchase", "sale")e3 ← ⟨Event G⟩
106e2 = Event("Click", "ui")107e3→ ⟨Event G⟩ = Event("Purchase", "sale")for e in [e1, e2, e3]:
pass 1 of 3109for 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 pass ee.ide.namee.category1 ⟨Event E⟩ 1 Login auth 2 ⟨Event F⟩ 2 Click ui 3 ⟨Event G⟩ 3 Purchase sale
Store computed values: self.area = width * height.
Common initialization patterns
Flexible constructors with various parameter styles.
# 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")
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 hexoutput=== Factory-Style Constructor ===self.r ← 255, self.g ← 128, self.b ← 0
pass 1 of 35class Color:6 def __init__(self(empty), r255, g128, b0):7 self.r→ 255 = r2558 self.g→ 128 = g1289 self.b→ 0 = b0All 3 passes — pass 1 is the card above pass rgbself.rself.gself.b1 255 128 0 255 128 0 2 0 255 0 0 255 0 3 0 0 255 0 0 255 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 namehex_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) #?returnclsc2 ← 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 namecolors ← {'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)) #?unpacktuplec3 ← 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 ===self.debug ← False, self.log_level ← INFO, self.max_connections ← 100
pass 1 of 246class 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 = 30cfg1 ← ⟨Config A⟩
67# Default config68cfg1→ ⟨Config A⟩ = Config()69print("Default config:")70cfg1⟨Config A⟩.display()outputDefault config:def display(self):
pass 1 of 261def 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: 30cfg1.display()
69print("Default config:")70cfg1⟨Config A⟩.display()7172# Custom config #?customconfig73cfg2 = Config(debug=True, timeout=60, unknown="ignored")74print("\nCustom config:")self.debug ← False, self.log_level ← INFO, self.max_connections ← 100
pass 2 of 246class 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 = 30for key, value in kwargs.items(): #?iteratekwargs
pass 1 of 354# 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) #?setattrAll 3 passes — pass 1 is the card above pass keyvalue1 debug True 2 timeout 60 3 unknown ignored if hasattr(self, key): #?hasattr
pass 1 of 255for key, value in kwargs.items(): #?iteratekwargs56 if hasattr(self, keydebug): #?hasattr57 setattr(self, keydebug, valueTrue) #?setattr58 else:if hasattr(self, key): #?hasattr
pass 2 of 255for key, value in kwargs.items(): #?iteratekwargs56 if hasattr(self, keytimeout): #?hasattr57 setattr(self, keytimeout, value60) #?setattr58 else:#?setattr else:
56if hasattr(self, key): #?hasattr57 setattr(self, key, value) #?setattr58else:59 print(f"Warning: Unknown config '{keyunknown}'")outputWarning: Unknown config 'unknown'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:def display(self):
pass 2 of 261def 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: 60cfg2.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 #?usecopyoutput === Copy Constructor Pattern ===self.x ← 10, self.y ← 20
pass 1 of 379class Point:80 def __init__(self(empty), x10=0, y20=0):81 self.x→ 10 = x1082 self.y→ 20 = y20All 3 passes — pass 1 is the card above pass self.xself.y1 10 20 2 10 20 3 10 20 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 classmethoddef copy(self): #?copymethod
84def copy(selfPoint(10, 20)): #?copymethod85 """Create a copy of this point"""86 return Point(self.x10, self.y20)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 classmethoddef 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)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 ===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 = 0db ← ⟨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/myappself.connected ← True
118def connect(self⟨Database C⟩):119 print(f"Connecting to {self.connection_stringdb://localhost:5432/myapp}...")120 self.connected→ True = TrueoutputConnecting to db://localhost:5432/myapp...db.connect()
129print(f"Connection string: {db.connection_string}")130db⟨Database C⟩.connect()131db⟨Database C⟩.query("SELECT * FROM users")132#@help classmethodself.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 usersdb.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