OOP Advanced
@classmethod and @staticmethod
Class-Level Methods
You want User.from_json(data) to create a User from JSON. Regular methods get
self (instance). @classmethod gets cls (class) - perfect for factory methods.
@staticmethod gets neither - just a function in the class namespace.
The three method types
Regular, classmethod, and staticmethod.
# Understanding the Three Method Types
class Counter:
"""Demonstrates all three method types."""
count = 0 # Class attribute - shared by all instances
def __init__(self, name: str):
self.name = name # Instance attribute
Counter.count += 1
# Regular method - receives self (instance)
def display(self):
print(f"Instance '{self.name}' (total count: {Counter.count})")
# Class method - receives cls (class)
@classmethod
def get_count(cls):
print(f"Class: {cls.__name__}")
print(f"Total instances: {cls.count}")
return cls.count
# Static method - receives nothing
@staticmethod
def describe():
print("Counter tracks how many instances exist")
def main():
print("=== Three Method Types ===\n")
# Static method - no instance needed
print("--- Static Method (no instance needed) ---")
Counter.describe() # Call on class
# Class method - no instance needed
print("\n--- Class Method (before any instances) ---")
Counter.get_count() # 0 instances
# Create instances
print("\n--- Creating Instances ---")
c1 = Counter("first")
c2 = Counter("second")
c3 = Counter("third")
# Regular method - needs instance
print("\n--- Regular Method (needs instance) ---")
c1.display() # Instance method
c2.display()
# Class method - after creating instances
print("\n--- Class Method (after instances) ---")
Counter.get_count() # 3 instances
# Can also call class method on instance
print("\n--- Class Method Called on Instance ---")
c1.get_count() # Still gets class
# Can also call static method on instance
print("\n--- Static Method Called on Instance ---")
c1.describe() # Works but not common
# Summary
print("\n=== Key Points ===")
print("""
Regular method:
def method(self): → receives instance
Call: instance.method()
Class method:
@classmethod
def method(cls): → receives class
Call: Class.method() or instance.method()
Static method:
@staticmethod
def method(): → receives nothing
Call: Class.method() or instance.method()
""")
if __name__ == "__main__":
main()
count ← (empty)
3class Counter:4 """Demonstrates all three method types."""56 count→ (empty) = 0 # Class attribute - shared by all instancesdef main():
29def main():30 print("=== Three Method Types ===\n")3132 # Static method - no instance needed #?static_demo33 print("--- Static Method (no instance needed) ---")34 Counter<class '__main__.Counter'>.describe() # Call on classoutput=== Three Method Types === --- Static Method (no instance needed) ---def describe(): #?describe_def
pass 1 of 224@staticmethod #?staticmethod_decorator25def describe(): #?describe_def26 print("Counter tracks how many instances exist") #?describe_bodyoutputCounter tracks how many instances existCounter.describe() # Call on class
33print("--- Static Method (no instance needed) ---")34Counter<class '__main__.Counter'>.describe() # Call on class3536# Class method - no instance needed #?classmethod_demo37print("\n--- Class Method (before any instances) ---")38Counter<class '__main__.Counter'>.get_count() # 0 instancesoutput --- Class Method (before any instances) ---def get_count(cls): #?get_count_def
pass 1 of 317@classmethod #?classmethod_decorator18def get_count(cls<class '__main__.Counter'>): #?get_count_def19 print(f"Class: {cls.__name__Counter}") #?print_class_name20 print(f"Total instances: {cls.count0}") #?print_count21 return cls.count0 #?return_countoutputClass: Counter Total instances: 0All 3 passes — pass 1 is the card above pass cls.count1 0 2 3 3 3 Counter.get_count() # 0 instances
37print("\n--- Class Method (before any instances) ---")38Counter<class '__main__.Counter'>.get_count() # 0 instances3940# Create instances #?create_instances41print("\n--- Creating Instances ---")42c1 = Counter("first") #?create_c143c2 = Counter("second") #?create_c2output --- Creating Instances ---self.name ← first, Counter.count ← 1
pass 1 of 38def __init__(self⟨Counter A⟩, namefirst: str): #?init9 self.name→ first = namefirst # Instance attribute10 Counter.count→ 1 += 1 #?incrementAll 3 passes — pass 1 is the card above pass selfnameself.nameCounter.count1 ⟨Counter A⟩ first first 0 → 1 2 ⟨Counter B⟩ second second 1 → 2 3 ⟨Counter C⟩ third third 2 → 3 c1 ← ⟨Counter A⟩
41print("\n--- Creating Instances ---")42c1→ ⟨Counter A⟩ = Counter("first") #?create_c143c2 = Counter("second") #?create_c244c3 = Counter("third") #?create_c3c2 ← ⟨Counter B⟩
42c1 = Counter("first") #?create_c143c2→ ⟨Counter B⟩ = Counter("second") #?create_c244c3 = Counter("third") #?create_c3c3 ← ⟨Counter C⟩
43c2 = Counter("second") #?create_c244c3→ ⟨Counter C⟩ = Counter("third") #?create_c34546# Regular method - needs instance #?regular_demo47print("\n--- Regular Method (needs instance) ---")48c1⟨Counter A⟩.display() # Instance method49c2.display() #?call_display_c2output --- Regular Method (needs instance) ---def display(self): #?display_def
pass 1 of 212# Regular method - receives self (instance) #?regular_method13def display(self⟨Counter A⟩): #?display_def14 print(f"Instance '{self.namefirst}' (total count: {Counter.count3})") #?display_bodyoutputInstance 'first' (total count: 3)c1.display() # Instance method
47print("\n--- Regular Method (needs instance) ---")48c1⟨Counter A⟩.display() # Instance method49c2⟨Counter B⟩.display() #?call_display_c2def display(self): #?display_def
pass 2 of 212# Regular method - receives self (instance) #?regular_method13def display(self⟨Counter B⟩): #?display_def14 print(f"Instance '{self.namesecond}' (total count: {Counter.count3})") #?display_bodyoutputInstance 'second' (total count: 3)c2.display() #?call_display_c2
48c1.display() # Instance method49c2⟨Counter B⟩.display() #?call_display_c25051# Class method - after creating instances #?classmethod_after52print("\n--- Class Method (after instances) ---")53Counter<class '__main__.Counter'>.get_count() # 3 instancesoutput --- Class Method (after instances) ---Counter.get_count() # 3 instances
52print("\n--- Class Method (after instances) ---")53Counter<class '__main__.Counter'>.get_count() # 3 instances5455# Can also call class method on instance #?classmethod_on_instance56print("\n--- Class Method Called on Instance ---")57c1⟨Counter A⟩.get_count() # Still gets classoutput --- Class Method Called on Instance ---c1.get_count() # Still gets class
56print("\n--- Class Method Called on Instance ---")57c1⟨Counter A⟩.get_count() # Still gets class5859# Can also call static method on instance #?static_on_instance60print("\n--- Static Method Called on Instance ---")61c1⟨Counter A⟩.describe() # Works but not commonoutput --- Static Method Called on Instance ---def describe(): #?describe_def
pass 2 of 224@staticmethod #?staticmethod_decorator25def describe(): #?describe_def26 print("Counter tracks how many instances exist") #?describe_bodyoutputCounter tracks how many instances existc1.describe() # Works but not common
60print("\n--- Static Method Called on Instance ---")61c1⟨Counter A⟩.describe() # Works but not common6263# Summary #?summary64print("\n=== Key Points ===")65print("""66Regular method:67 def method(self): → receives instance68 Call: instance.method()6970Class method:71 @classmethod72 def method(cls): → receives class73 Call: Class.method() or instance.method()7475Static method:76 @staticmethod77 def method(): → receives nothing78 Call: Class.method() or instance.method()79""")output === Key Points === Regular method: def method(self): → receives instance Call: instance.method() Class method: @classmethod def method(cls): → receives class Call: Class.method() or instance.method() Static method: @staticmethod def method(): → receives nothing Call: Class.method() or instance.method()main()
82if __name__ == "__main__":83 main()
Regular: self. Classmethod: cls. Staticmethod: neither.
Factory methods with @classmethod
Alternative constructors that return instances.
# Using @classmethod for Factory Methods
class Product:
"""Product with factory methods."""
def __init__(self, name: str, price: float, category: str):
self.name = name
self.price = price
self.category = category
def __repr__(self):
return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"
# Factory method: create from dictionary
@classmethod
def from_dict(cls, data: dict):
"""Create Product from a dictionary."""
return cls(
name=data["name"],
price=data["price"],
category=data.get("category", "general")
)
# Factory method: create from string
@classmethod
def from_string(cls, s: str):
"""Create Product from 'name:price:category' string."""
parts = s.split(":")
name = parts[0]
price = float(parts[1])
category = parts[2] if len(parts) > 2 else "general"
return cls(name, price, category)
# Factory method: create with defaults
@classmethod
def create_digital(cls, name: str, price: float):
"""Create a digital product."""
return cls(name, price, "digital")
@classmethod
def create_physical(cls, name: str, price: float):
"""Create a physical product."""
return cls(name, price, "physical")
class User:
"""User with factory methods for different user types."""
def __init__(self, username: str, email: str, role: str, is_active: bool = True):
self.username = username
self.email = email
self.role = role
self.is_active = is_active
def __repr__(self):
status = "active" if self.is_active else "inactive"
return f"User({self.username}, {self.role}, {status})"
@classmethod
def create_admin(cls, username: str, email: str):
"""Factory method for admin users."""
return cls(username, email, role="admin")
@classmethod
def create_guest(cls):
"""Factory method for guest users."""
return cls("guest", "guest@example.com", role="guest", is_active=False)
@classmethod
def from_dict(cls, data: dict):
"""Create User from dictionary."""
return cls(**data) # Unpack dict as keyword args
def main():
print("=== Factory Methods with @classmethod ===\n")
# Standard constructor
print("--- Standard Constructor ---")
p1 = Product("Laptop", 999.99, "electronics")
print(f"Standard: {p1}")
# Factory: from dictionary
print("\n--- Factory: from_dict ---")
data = {"name": "Mouse", "price": 29.99, "category": "electronics"}
p2 = Product.from_dict(data)
print(f"From dict: {p2}")
# Factory: from string
print("\n--- Factory: from_string ---")
p3 = Product.from_string("Keyboard:79.99:electronics")
print(f"From string: {p3}")
p4 = Product.from_string("Sticker:2.99")
print(f"From string (default category): {p4}")
# Factory: preset categories
print("\n--- Factory: Preset Categories ---")
p5 = Product.create_digital("E-book", 14.99)
p6 = Product.create_physical("T-shirt", 24.99)
print(f"Digital: {p5}")
print(f"Physical: {p6}")
# User factory methods
print("\n--- User Factory Methods ---")
admin = User.create_admin("admin", "admin@example.com")
guest = User.create_guest()
user_data = {"username": "john", "email": "john@example.com", "role": "user"}
regular = User.from_dict(user_data)
print(f"Admin: {admin}")
print(f"Guest: {guest}")
print(f"Regular: {regular}")
print("\n=== Key Points ===")
print("""
Factory methods (@classmethod):
• Return new instances of the class
• Use cls() instead of ClassName()
• Provide alternative ways to create objects
• Can have descriptive names like from_dict, create_admin
• Handle data conversion/validation
""")
if __name__ == "__main__":
main()
# Using @classmethod for Factory Methods
class Product:
"""Product with factory methods."""
def __init__(self, name: str, price: float, category: str):
self.name = name
self.price = price
self.category = category
def __repr__(self):
return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"
# Factory method: create from dictionary
@classmethod
def from_dict(cls, data: dict):
"""Create Product from a dictionary."""
return cls(
name=data["name"],
price=data["price"],
category=data.get("category", "general")
)
# Factory method: create from string
@classmethod
def from_string(cls, s: str):
"""Create Product from 'name:price:category' string."""
parts = s.split(":")
name = parts[0]
price = float(parts[1])
category = parts[2] if len(parts) > 2 else "general"
return cls(name, price, category)
# Factory method: create with defaults
@classmethod
def create_digital(cls, name: str, price: float):
"""Create a digital product."""
return cls(name, price, "digital")
@classmethod
def create_physical(cls, name: str, price: float):
"""Create a physical product."""
return cls(name, price, "physical")
class User:
"""User with factory methods for different user types."""
def __init__(self, username: str, email: str, role: str, is_active: bool = True):
self.username = username
self.email = email
self.role = role
self.is_active = is_active
def __repr__(self):
status = "active" if self.is_active else "inactive"
return f"User({self.username}, {self.role}, {status})"
@classmethod
def create_admin(cls, username: str, email: str):
"""Factory method for admin users."""
return cls(username, email, role="admin")
@classmethod
def create_guest(cls):
"""Factory method for guest users."""
return cls("guest", "guest@example.com", role="guest", is_active=False)
@classmethod
def from_dict(cls, data: dict):
"""Create User from dictionary."""
return cls(**data) # Unpack dict as keyword args
def main():
print("=== Factory Methods with @classmethod ===\n")
# Standard constructor
print("--- Standard Constructor ---")
p1 = Product("Laptop", 999.99, "electronics")
print(f"Standard: {p1}")
# Factory: from dictionary
print("\n--- Factory: from_dict ---")
data = {"name": "Mouse", "price": 29.99, "category": "electronics"}
p2 = Product.from_dict(data)
print(f"From dict: {p2}")
# Factory: from string
print("\n--- Factory: from_string ---")
p3 = Product.from_string("Cable:9.99:accessories")
print(f"From string: {p3}")
p4 = Product.from_string("Sticker:2.99")
print(f"From string (default category): {p4}")
# Factory: preset categories
print("\n--- Factory: Preset Categories ---")
p5 = Product.create_digital("E-book", 14.99)
p6 = Product.create_physical("T-shirt", 24.99)
print(f"Digital: {p5}")
print(f"Physical: {p6}")
# User factory methods
print("\n--- User Factory Methods ---")
admin = User.create_admin("admin", "admin@example.com")
guest = User.create_guest()
user_data = {"username": "john", "email": "john@example.com", "role": "user"}
regular = User.from_dict(user_data)
print(f"Admin: {admin}")
print(f"Guest: {guest}")
print(f"Regular: {regular}")
print("\n=== Key Points ===")
print("""
Factory methods (@classmethod):
• Return new instances of the class
• Use cls() instead of ClassName()
• Provide alternative ways to create objects
• Can have descriptive names like from_dict, create_admin
• Handle data conversion/validation
""")
if __name__ == "__main__":
main()
# Using @classmethod for Factory Methods
class Product:
"""Product with factory methods."""
def __init__(self, name: str, price: float, category: str):
self.name = name
self.price = price
self.category = category
def __repr__(self):
return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"
# Factory method: create from dictionary
@classmethod
def from_dict(cls, data: dict):
"""Create Product from a dictionary."""
return cls(
name=data["name"],
price=data["price"],
category=data.get("category", "general")
)
# Factory method: create from string
@classmethod
def from_string(cls, s: str):
"""Create Product from 'name:price:category' string."""
parts = s.split(":")
name = parts[0]
price = float(parts[1])
category = parts[2] if len(parts) > 2 else "general"
return cls(name, price, category)
# Factory method: create with defaults
@classmethod
def create_digital(cls, name: str, price: float):
"""Create a digital product."""
return cls(name, price, "digital")
@classmethod
def create_physical(cls, name: str, price: float):
"""Create a physical product."""
return cls(name, price, "physical")
class User:
"""User with factory methods for different user types."""
def __init__(self, username: str, email: str, role: str, is_active: bool = True):
self.username = username
self.email = email
self.role = role
self.is_active = is_active
def __repr__(self):
status = "active" if self.is_active else "inactive"
return f"User({self.username}, {self.role}, {status})"
@classmethod
def create_admin(cls, username: str, email: str):
"""Factory method for admin users."""
return cls(username, email, role="admin")
@classmethod
def create_guest(cls):
"""Factory method for guest users."""
return cls("guest", "guest@example.com", role="guest", is_active=False)
@classmethod
def from_dict(cls, data: dict):
"""Create User from dictionary."""
return cls(**data) # Unpack dict as keyword args
def main():
print("=== Factory Methods with @classmethod ===\n")
# Standard constructor
print("--- Standard Constructor ---")
p1 = Product("Laptop", 999.99, "electronics")
print(f"Standard: {p1}")
# Factory: from dictionary
print("\n--- Factory: from_dict ---")
data = {"name": "Mouse", "price": 29.99, "category": "electronics"}
p2 = Product.from_dict(data)
print(f"From dict: {p2}")
# Factory: from string
print("\n--- Factory: from_string ---")
p3 = Product.from_string("Sticker:2.99")
print(f"From string: {p3}")
p4 = Product.from_string("Sticker:2.99")
print(f"From string (default category): {p4}")
# Factory: preset categories
print("\n--- Factory: Preset Categories ---")
p5 = Product.create_digital("E-book", 14.99)
p6 = Product.create_physical("T-shirt", 24.99)
print(f"Digital: {p5}")
print(f"Physical: {p6}")
# User factory methods
print("\n--- User Factory Methods ---")
admin = User.create_admin("admin", "admin@example.com")
guest = User.create_guest()
user_data = {"username": "john", "email": "john@example.com", "role": "user"}
regular = User.from_dict(user_data)
print(f"Admin: {admin}")
print(f"Guest: {guest}")
print(f"Regular: {regular}")
print("\n=== Key Points ===")
print("""
Factory methods (@classmethod):
• Return new instances of the class
• Use cls() instead of ClassName()
• Provide alternative ways to create objects
• Can have descriptive names like from_dict, create_admin
• Handle data conversion/validation
""")
if __name__ == "__main__":
main()
# Using @classmethod for Factory Methods
class Product:
"""Product with factory methods."""
def __init__(self, name: str, price: float, category: str):
self.name = name
self.price = price
self.category = category
def __repr__(self):
return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"
# Factory method: create from dictionary
@classmethod
def from_dict(cls, data: dict):
"""Create Product from a dictionary."""
return cls(
name=data["name"],
price=data["price"],
category=data.get("category", "general")
)
# Factory method: create from string
@classmethod
def from_string(cls, s: str):
"""Create Product from 'name:price:category' string."""
parts = s.split(":")
name = parts[0]
price = float(parts[1])
category = parts[2] if len(parts) > 2 else "general"
return cls(name, price, category)
# Factory method: create with defaults
@classmethod
def create_digital(cls, name: str, price: float):
"""Create a digital product."""
return cls(name, price, "digital")
@classmethod
def create_physical(cls, name: str, price: float):
"""Create a physical product."""
return cls(name, price, "physical")
class User:
"""User with factory methods for different user types."""
def __init__(self, username: str, email: str, role: str, is_active: bool = True):
self.username = username
self.email = email
self.role = role
self.is_active = is_active
def __repr__(self):
status = "active" if self.is_active else "inactive"
return f"User({self.username}, {self.role}, {status})"
@classmethod
def create_admin(cls, username: str, email: str):
"""Factory method for admin users."""
return cls(username, email, role="admin")
@classmethod
def create_guest(cls):
"""Factory method for guest users."""
return cls("guest", "guest@example.com", role="guest", is_active=False)
@classmethod
def from_dict(cls, data: dict):
"""Create User from dictionary."""
return cls(**data) # Unpack dict as keyword args
def main():
print("=== Factory Methods with @classmethod ===\n")
# Standard constructor
print("--- Standard Constructor ---")
p1 = Product("Laptop", 999.99, "electronics")
print(f"Standard: {p1}")
# Factory: from dictionary
print("\n--- Factory: from_dict ---")
data = {"name": "Mouse", "price": 29.99, "category": "electronics"}
p2 = Product.from_dict(data)
print(f"From dict: {p2}")
# Factory: from string
print("\n--- Factory: from_string ---")
p3 = Product.from_string("Keyboard:79.99:electronics")
print(f"From string: {p3}")
p4 = Product.from_string("Sticker:2.99")
print(f"From string (default category): {p4}")
# Factory: preset categories
print("\n--- Factory: Preset Categories ---")
p5 = Product.create_digital("E-book", 14.99)
p6 = Product.create_physical("T-shirt", 24.99)
print(f"Digital: {p5}")
print(f"Physical: {p6}")
# User factory methods
print("\n--- User Factory Methods ---")
admin = User.create_admin("admin", "admin@example.com")
guest = User.create_guest()
user_data = {"username": "maya", "email": "maya@example.com", "role": "editor"}
regular = User.from_dict(user_data)
print(f"Admin: {admin}")
print(f"Guest: {guest}")
print(f"Regular: {regular}")
print("\n=== Key Points ===")
print("""
Factory methods (@classmethod):
• Return new instances of the class
• Use cls() instead of ClassName()
• Provide alternative ways to create objects
• Can have descriptive names like from_dict, create_admin
• Handle data conversion/validation
""")
if __name__ == "__main__":
main()
"""Product with factory methods."""
3class Product:4 """Product with factory methods."""56 def __init__(self, name: str, price: float, category: str): #?init7 self.name = name #?set_name8 self.price = price #?set_price9 self.category = category #?set_category1011 def __repr__(self): #?repr12 return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"1314 # Factory method: create from dictionary #?from_dict_comment15 @classmethod #?from_dict_decorator16 def from_dict(cls, data: dict): #?from_dict_def17 """Create Product from a dictionary."""18 return cls( #?from_dict_return19 name=data["name"],20 price=data["price"],21 category=data.get("category", "general")22 )2324 # Factory method: create from string #?from_string_comment25 @classmethod #?from_string_decorator26 def from_string(cls, s: str): #?from_string_def27 """Create Product from 'name:price:category' string."""28 parts = s.split(":") #?split_string29 name = parts[0] #?get_name30 price = float(parts[1]) #?get_price31 category = parts[2] if len(parts) > 2 else "general" #?get_category32 return cls(name, price, category) #?from_string_return3334 # Factory method: create with defaults #?create_preset_comment35 @classmethod #?create_preset_decorator36 def create_digital(cls, name: str, price: float): #?create_digital_def37 """Create a digital product."""38 return cls(name, price, "digital") #?create_digital_return3940 @classmethod #?create_physical_decorator41 def create_physical(cls, name: str, price: float): #?create_physical_def42 """Create a physical product."""43 return cls(name, price, "physical") #?create_physical_return444546class User:47 """User with factory methods for different user types."""def main():
75def main():76 print("=== Factory Methods with @classmethod ===\n")7778 # Standard constructor #?standard_constructor79 print("--- Standard Constructor ---")80 p1 = Product("Laptop", 999.99, "electronics") #?create_p181 print(f"Standard: {p1}") #?print_p1output=== Factory Methods with @classmethod === --- Standard Constructor ---self.name ← Laptop, self.price ← 999.99, self.category ← electronics
pass 1 of 66def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str): #?init7 self.name→ Laptop = nameLaptop #?set_name8 self.price→ 999.99 = price999.99 #?set_price9 self.category→ electronics = categoryelectronics #?set_categoryAll 6 passes — pass 1 is the card above pass namepricecategoryself.nameself.priceself.category1 Laptop 999.99 electronics Laptop 999.99 electronics 2 Mouse 29.99 electronics Mouse 29.99 electronics 3 Keyboard 79.99 electronics Keyboard 79.99 electronics 4 Sticker 2.99 general Sticker 2.99 general 5 E-book 14.99 digital E-book 14.99 digital 6 T-shirt 24.99 physical T-shirt 24.99 physical p1 ← Product('Laptop', $999.99, electronics), data ← {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}
79print("--- Standard Constructor ---")80p1→ Product('Laptop', $999.99, electronics) = Product("Laptop", 999.99, "electronics") #?create_p181print(f"Standard: {p1Product('Laptop', $999.99, electronics)}") #?print_p18283# Factory: from dictionary #?from_dict_demo84print("\n--- Factory: from_dict ---")85data→ {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'} = {"name": "Mouse", "price": 29.99, "category": "electronics"} #?create_dict86p2 = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}) #?call_from_dict87print(f"From dict: {p2}") #?print_p2outputStandard: Product('Laptop', $999.99, electronics) --- Factory: from_dict ---def from_dict(cls, data: dict): #?from_dict_def
15@classmethod #?from_dict_decorator16def from_dict(cls<class '__main__.Product'>, data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}: dict): #?from_dict_def17 """Create Product from a dictionary."""18 return cls( #?from_dict_return19 name=data["name"]Mouse,20 price=data["price"]29.99,21 category=data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}.get("category", "general")22 )p2 ← Product('Mouse', $29.99, electronics)
85data = {"name": "Mouse", "price": 29.99, "category": "electronics"} #?create_dict86p2→ Product('Mouse', $29.99, electronics) = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}) #?call_from_dict87print(f"From dict: {p2Product('Mouse', $29.99, electronics)}") #?print_p28889# Factory: from string #?from_string_demo90print("\n--- Factory: from_string ---")91p3 = Product<class '__main__.Product'>.from_string("Keyboard:79.99:electronics") #?call_from_string92#@p3=Product.from_string("Cable:9.99:accessories"), Product.from_string("Sticker:2.99")outputFrom dict: Product('Mouse', $29.99, electronics) --- Factory: from_string ---parts ← ['Keyboard', '79.99', 'electronics'], name ← Keyboard
pass 1 of 225@classmethod #?from_string_decorator26def from_string(cls<class '__main__.Product'>, sKeyboard:79.99:electronics: str): #?from_string_def27 """Create Product from 'name:price:category' string."""28 parts→ ['Keyboard', '79.99', 'electronics'] = sKeyboard:79.99:electronics.split(":") #?split_string29 name→ Keyboard = parts[0]Keyboard #?get_name30 price→ 79.99 = float(parts[1]79.99) #?get_price31 category→ electronics = parts[2]electronics if len(parts['Keyboard', '79.99', 'electronics']) > 2 else "general" #?get_category32 return cls(nameKeyboard, price79.99, categoryelectronics) #?from_string_returnp3 ← Product('Keyboard', $79.99, electronics)
90print("\n--- Factory: from_string ---")91p3→ Product('Keyboard', $79.99, electronics) = Product<class '__main__.Product'>.from_string("Keyboard:79.99:electronics") #?call_from_string92#@p3=Product.from_string("Cable:9.99:accessories"), Product.from_string("Sticker:2.99")93print(f"From string: {p3Product('Keyboard', $79.99, electronics)}") #?print_p39495p4 = Product<class '__main__.Product'>.from_string("Sticker:2.99") #?call_from_string_default96print(f"From string (default category): {p4}") #?print_p4outputFrom string: Product('Keyboard', $79.99, electronics)parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general
pass 2 of 225@classmethod #?from_string_decorator26def from_string(cls<class '__main__.Product'>, sSticker:2.99: str): #?from_string_def27 """Create Product from 'name:price:category' string."""28 parts→ ['Sticker', '2.99'] = sSticker:2.99.split(":") #?split_string29 name→ Sticker = parts[0]Sticker #?get_name30 price→ 2.99 = float(parts[1]2.99) #?get_price31 category→ general = parts[2](empty) if len(parts['Sticker', '2.99']) > 2 else "general" #?get_category32 return cls(nameSticker, price2.99, categorygeneral) #?from_string_returnp4 ← Product('Sticker', $2.99, general)
95p4→ Product('Sticker', $2.99, general) = Product<class '__main__.Product'>.from_string("Sticker:2.99") #?call_from_string_default96print(f"From string (default category): {p4Product('Sticker', $2.99, general)}") #?print_p49798# Factory: preset categories #?preset_demo99print("\n--- Factory: Preset Categories ---")100p5 = Product<class '__main__.Product'>.create_digital("E-book", 14.99) #?call_create_digital101p6 = Product.create_physical("T-shirt", 24.99) #?call_create_physicaloutputFrom string (default category): Product('Sticker', $2.99, general) --- Factory: Preset Categories ---def create_digital(cls, name: str, price: float): #?create_digital_de…
35@classmethod #?create_preset_decorator36def create_digital(cls<class '__main__.Product'>, nameE-book: str, price14.99: float): #?create_digital_def37 """Create a digital product."""38 return cls(nameE-book, price14.99, "digital") #?create_digital_returnp5 ← Product('E-book', $14.99, digital)
99print("\n--- Factory: Preset Categories ---")100p5→ Product('E-book', $14.99, digital) = Product<class '__main__.Product'>.create_digital("E-book", 14.99) #?call_create_digital101p6 = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99) #?call_create_physical102print(f"Digital: {p5}") #?print_p5def create_physical(cls, name: str, price: float): #?create_physical_…
40@classmethod #?create_physical_decorator41def create_physical(cls<class '__main__.Product'>, nameT-shirt: str, price24.99: float): #?create_physical_def42 """Create a physical product."""43 return cls(nameT-shirt, price24.99, "physical") #?create_physical_returnp6 ← Product('T-shirt', $24.99, physical)
100p5 = Product.create_digital("E-book", 14.99) #?call_create_digital101p6→ Product('T-shirt', $24.99, physical) = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99) #?call_create_physical102print(f"Digital: {p5Product('E-book', $14.99, digital)}") #?print_p5103print(f"Physical: {p6Product('T-shirt', $24.99, physical)}") #?print_p6104105# User factory methods #?user_factory_demo106print("\n--- User Factory Methods ---")107admin = User<class '__main__.User'>.create_admin("admin", "admin@example.com") #?create_admin108guest = User.create_guest() #?create_guestoutputDigital: Product('E-book', $14.99, digital) Physical: Product('T-shirt', $24.99, physical) --- User Factory Methods ---def create_admin(cls, username: str, email: str): #?create_admin_def
59@classmethod #?create_admin_decorator60def create_admin(cls<class '__main__.User'>, usernameadmin: str, emailadmin@example.com: str): #?create_admin_def61 """Factory method for admin users."""62 return cls(usernameadmin, emailadmin@example.com, role="admin") #?create_admin_returnself.username ← admin, self.email ← admin@example.com, self.role ← admin
pass 1 of 349def __init__(self(empty), usernameadmin: str, emailadmin@example.com: str, roleadmin: str, is_activeTrue: bool = TrueTrue): #?user_init50 self.username→ admin = usernameadmin51 self.email→ admin@example.com = emailadmin@example.com52 self.role→ admin = roleadmin53 self.is_active→ True = is_activeTrueAll 3 passes — pass 1 is the card above pass usernameemailroleis_activeself.usernameself.emailself.roleself.is_active1 admin admin@example.com admin True admin admin@example.com admin True 2 guest guest@example.com guest False guest guest@example.com guest False 3 john john@example.com user True john john@example.com user True admin ← User(admin, admin, active)
106print("\n--- User Factory Methods ---")107admin→ User(admin, admin, active) = User<class '__main__.User'>.create_admin("admin", "admin@example.com") #?create_admin108guest = User<class '__main__.User'>.create_guest() #?create_guestdef create_guest(cls): #?create_guest_def
64@classmethod #?create_guest_decorator65def create_guest(cls<class '__main__.User'>): #?create_guest_def66 """Factory method for guest users."""67 return cls("guest", "guest@example.com", role="guest", is_active=False) #?create_guest_returnguest ← User(guest, guest, inactive), user_data ← {'username': 'john', 'email': 'john@example.com', 'role': 'user'}
107admin = User.create_admin("admin", "admin@example.com") #?create_admin108guest→ User(guest, guest, inactive) = User<class '__main__.User'>.create_guest() #?create_guest109110user_data→ {'username': 'john', 'email': 'john@example.com', 'role': 'user'} = {"username": "john", "email": "john@example.com", "role": "user"} #?user_dict111#@user_data={"username": "maya", "email": "maya@example.com", "role": "editor"}112regular = User<class '__main__.User'>.from_dict(user_data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}) #?create_from_dictdef from_dict(cls, data: dict): #?from_dict_user_def
69@classmethod #?from_dict_user_decorator70def from_dict(cls<class '__main__.User'>, data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}: dict): #?from_dict_user_def71 """Create User from dictionary."""72 return cls(**data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}) # Unpack dict as keyword argsregular ← User(john, user, active)
111#@user_data={"username": "maya", "email": "maya@example.com", "role": "editor"}112regular→ User(john, user, active) = User<class '__main__.User'>.from_dict(user_data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}) #?create_from_dict113114print(f"Admin: {adminUser(admin, admin, active)}") #?print_admin115print(f"Guest: {guestUser(guest, guest, inactive)}") #?print_guest116print(f"Regular: {regularUser(john, user, active)}") #?print_regular117118print("\n=== Key Points ===")119print("""120Factory methods (@classmethod):121• Return new instances of the class122• Use cls() instead of ClassName()123• Provide alternative ways to create objects124• Can have descriptive names like from_dict, create_admin125• Handle data conversion/validation126""")outputAdmin: User(admin, admin, active) Guest: User(guest, guest, inactive) Regular: User(john, user, active) === Key Points === Factory methods (@classmethod): • Return new instances of the class • Use cls() instead of ClassName() • Provide alternative ways to create objects • Can have descriptive names like from_dict, create_admin • Handle data conversion/validationmain()
129if __name__ == "__main__":130 main()
"""Product with factory methods."""
3class Product:4 """Product with factory methods."""56 def __init__(self, name: str, price: float, category: str):7 self.name = name8 self.price = price9 self.category = category1011 def __repr__(self):12 return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"1314 # Factory method: create from dictionary15 @classmethod16 def from_dict(cls, data: dict):17 """Create Product from a dictionary."""18 return cls(19 name=data["name"],20 price=data["price"],21 category=data.get("category", "general")22 )2324 # Factory method: create from string25 @classmethod26 def from_string(cls, s: str):27 """Create Product from 'name:price:category' string."""28 parts = s.split(":")29 name = parts[0]30 price = float(parts[1])31 category = parts[2] if len(parts) > 2 else "general"32 return cls(name, price, category)3334 # Factory method: create with defaults35 @classmethod36 def create_digital(cls, name: str, price: float):37 """Create a digital product."""38 return cls(name, price, "digital")3940 @classmethod41 def create_physical(cls, name: str, price: float):42 """Create a physical product."""43 return cls(name, price, "physical")444546class User:47 """User with factory methods for different user types."""def main():
75def main():76 print("=== Factory Methods with @classmethod ===\n")7778 # Standard constructor79 print("--- Standard Constructor ---")80 p1 = Product("Laptop", 999.99, "electronics")81 print(f"Standard: {p1}")output=== Factory Methods with @classmethod === --- Standard Constructor ---self.name ← Laptop, self.price ← 999.99, self.category ← electronics
pass 1 of 66def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str):7 self.name→ Laptop = nameLaptop8 self.price→ 999.99 = price999.999 self.category→ electronics = categoryelectronicsAll 6 passes — pass 1 is the card above pass namepricecategoryself.nameself.priceself.category1 Laptop 999.99 electronics Laptop 999.99 electronics 2 Mouse 29.99 electronics Mouse 29.99 electronics 3 Cable 9.99 accessories Cable 9.99 accessories 4 Sticker 2.99 general Sticker 2.99 general 5 E-book 14.99 digital E-book 14.99 digital 6 T-shirt 24.99 physical T-shirt 24.99 physical p1 ← Product('Laptop', $999.99, electronics), data ← {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}
79print("--- Standard Constructor ---")80p1→ Product('Laptop', $999.99, electronics) = Product("Laptop", 999.99, "electronics")81print(f"Standard: {p1Product('Laptop', $999.99, electronics)}")8283# Factory: from dictionary84print("\n--- Factory: from_dict ---")85data→ {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'} = {"name": "Mouse", "price": 29.99, "category": "electronics"}86p2 = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'})87print(f"From dict: {p2}")outputStandard: Product('Laptop', $999.99, electronics) --- Factory: from_dict ---def from_dict(cls, data: dict):
15@classmethod16def from_dict(cls<class '__main__.Product'>, data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}: dict):17 """Create Product from a dictionary."""18 return cls(19 name=data["name"]Mouse,20 price=data["price"]29.99,21 category=data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}.get("category", "general")22 )p2 ← Product('Mouse', $29.99, electronics)
85data = {"name": "Mouse", "price": 29.99, "category": "electronics"}86p2→ Product('Mouse', $29.99, electronics) = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'})87print(f"From dict: {p2Product('Mouse', $29.99, electronics)}")8889# Factory: from string90print("\n--- Factory: from_string ---")91p3 = Product<class '__main__.Product'>.from_string("Cable:9.99:accessories")92print(f"From string: {p3}")outputFrom dict: Product('Mouse', $29.99, electronics) --- Factory: from_string ---parts ← ['Cable', '9.99', 'accessories'], name ← Cable, price ← 9.99
pass 1 of 225@classmethod26def from_string(cls<class '__main__.Product'>, sCable:9.99:accessories: str):27 """Create Product from 'name:price:category' string."""28 parts→ ['Cable', '9.99', 'accessories'] = sCable:9.99:accessories.split(":")29 name→ Cable = parts[0]Cable30 price→ 9.99 = float(parts[1]9.99)31 category→ accessories = parts[2]accessories if len(parts['Cable', '9.99', 'accessories']) > 2 else "general"32 return cls(nameCable, price9.99, categoryaccessories)p3 ← Product('Cable', $9.99, accessories)
90print("\n--- Factory: from_string ---")91p3→ Product('Cable', $9.99, accessories) = Product<class '__main__.Product'>.from_string("Cable:9.99:accessories")92print(f"From string: {p3Product('Cable', $9.99, accessories)}")9394p4 = Product<class '__main__.Product'>.from_string("Sticker:2.99")95print(f"From string (default category): {p4}")outputFrom string: Product('Cable', $9.99, accessories)parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general
pass 2 of 225@classmethod26def from_string(cls<class '__main__.Product'>, sSticker:2.99: str):27 """Create Product from 'name:price:category' string."""28 parts→ ['Sticker', '2.99'] = sSticker:2.99.split(":")29 name→ Sticker = parts[0]Sticker30 price→ 2.99 = float(parts[1]2.99)31 category→ general = parts[2](empty) if len(parts['Sticker', '2.99']) > 2 else "general"32 return cls(nameSticker, price2.99, categorygeneral)p4 ← Product('Sticker', $2.99, general)
94p4→ Product('Sticker', $2.99, general) = Product<class '__main__.Product'>.from_string("Sticker:2.99")95print(f"From string (default category): {p4Product('Sticker', $2.99, general)}")9697# Factory: preset categories98print("\n--- Factory: Preset Categories ---")99p5 = Product<class '__main__.Product'>.create_digital("E-book", 14.99)100p6 = Product.create_physical("T-shirt", 24.99)outputFrom string (default category): Product('Sticker', $2.99, general) --- Factory: Preset Categories ---def create_digital(cls, name: str, price: float):
35@classmethod36def create_digital(cls<class '__main__.Product'>, nameE-book: str, price14.99: float):37 """Create a digital product."""38 return cls(nameE-book, price14.99, "digital")p5 ← Product('E-book', $14.99, digital)
98print("\n--- Factory: Preset Categories ---")99p5→ Product('E-book', $14.99, digital) = Product<class '__main__.Product'>.create_digital("E-book", 14.99)100p6 = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99)101print(f"Digital: {p5}")def create_physical(cls, name: str, price: float):
40@classmethod41def create_physical(cls<class '__main__.Product'>, nameT-shirt: str, price24.99: float):42 """Create a physical product."""43 return cls(nameT-shirt, price24.99, "physical")p6 ← Product('T-shirt', $24.99, physical)
99p5 = Product.create_digital("E-book", 14.99)100p6→ Product('T-shirt', $24.99, physical) = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99)101print(f"Digital: {p5Product('E-book', $14.99, digital)}")102print(f"Physical: {p6Product('T-shirt', $24.99, physical)}")103104# User factory methods105print("\n--- User Factory Methods ---")106admin = User<class '__main__.User'>.create_admin("admin", "admin@example.com")107guest = User.create_guest()outputDigital: Product('E-book', $14.99, digital) Physical: Product('T-shirt', $24.99, physical) --- User Factory Methods ---def create_admin(cls, username: str, email: str):
59@classmethod60def create_admin(cls<class '__main__.User'>, usernameadmin: str, emailadmin@example.com: str):61 """Factory method for admin users."""62 return cls(usernameadmin, emailadmin@example.com, role="admin")self.username ← admin, self.email ← admin@example.com, self.role ← admin
pass 1 of 349def __init__(self(empty), usernameadmin: str, emailadmin@example.com: str, roleadmin: str, is_activeTrue: bool = TrueTrue):50 self.username→ admin = usernameadmin51 self.email→ admin@example.com = emailadmin@example.com52 self.role→ admin = roleadmin53 self.is_active→ True = is_activeTrueAll 3 passes — pass 1 is the card above pass usernameemailroleis_activeself.usernameself.emailself.roleself.is_active1 admin admin@example.com admin True admin admin@example.com admin True 2 guest guest@example.com guest False guest guest@example.com guest False 3 john john@example.com user True john john@example.com user True admin ← User(admin, admin, active)
105print("\n--- User Factory Methods ---")106admin→ User(admin, admin, active) = User<class '__main__.User'>.create_admin("admin", "admin@example.com")107guest = User<class '__main__.User'>.create_guest()def create_guest(cls):
64@classmethod65def create_guest(cls<class '__main__.User'>):66 """Factory method for guest users."""67 return cls("guest", "guest@example.com", role="guest", is_active=False)guest ← User(guest, guest, inactive), user_data ← {'username': 'john', 'email': 'john@example.com', 'role': 'user'}
106admin = User.create_admin("admin", "admin@example.com")107guest→ User(guest, guest, inactive) = User<class '__main__.User'>.create_guest()108109user_data→ {'username': 'john', 'email': 'john@example.com', 'role': 'user'} = {"username": "john", "email": "john@example.com", "role": "user"}110regular = User<class '__main__.User'>.from_dict(user_data{'username': 'john', 'email': 'john@example.com', 'role': 'user'})def from_dict(cls, data: dict):
69@classmethod70def from_dict(cls<class '__main__.User'>, data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}: dict):71 """Create User from dictionary."""72 return cls(**data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}) # Unpack dict as keyword argsregular ← User(john, user, active)
109user_data = {"username": "john", "email": "john@example.com", "role": "user"}110regular→ User(john, user, active) = User<class '__main__.User'>.from_dict(user_data{'username': 'john', 'email': 'john@example.com', 'role': 'user'})111112print(f"Admin: {adminUser(admin, admin, active)}")113print(f"Guest: {guestUser(guest, guest, inactive)}")114print(f"Regular: {regularUser(john, user, active)}")115116print("\n=== Key Points ===")117print("""118Factory methods (@classmethod):119• Return new instances of the class120• Use cls() instead of ClassName()121• Provide alternative ways to create objects122• Can have descriptive names like from_dict, create_admin123• Handle data conversion/validation124""")outputAdmin: User(admin, admin, active) Guest: User(guest, guest, inactive) Regular: User(john, user, active) === Key Points === Factory methods (@classmethod): • Return new instances of the class • Use cls() instead of ClassName() • Provide alternative ways to create objects • Can have descriptive names like from_dict, create_admin • Handle data conversion/validationmain()
127if __name__ == "__main__":128 main()
"""Product with factory methods."""
3class Product:4 """Product with factory methods."""56 def __init__(self, name: str, price: float, category: str):7 self.name = name8 self.price = price9 self.category = category1011 def __repr__(self):12 return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"1314 # Factory method: create from dictionary15 @classmethod16 def from_dict(cls, data: dict):17 """Create Product from a dictionary."""18 return cls(19 name=data["name"],20 price=data["price"],21 category=data.get("category", "general")22 )2324 # Factory method: create from string25 @classmethod26 def from_string(cls, s: str):27 """Create Product from 'name:price:category' string."""28 parts = s.split(":")29 name = parts[0]30 price = float(parts[1])31 category = parts[2] if len(parts) > 2 else "general"32 return cls(name, price, category)3334 # Factory method: create with defaults35 @classmethod36 def create_digital(cls, name: str, price: float):37 """Create a digital product."""38 return cls(name, price, "digital")3940 @classmethod41 def create_physical(cls, name: str, price: float):42 """Create a physical product."""43 return cls(name, price, "physical")444546class User:47 """User with factory methods for different user types."""def main():
75def main():76 print("=== Factory Methods with @classmethod ===\n")7778 # Standard constructor79 print("--- Standard Constructor ---")80 p1 = Product("Laptop", 999.99, "electronics")81 print(f"Standard: {p1}")output=== Factory Methods with @classmethod === --- Standard Constructor ---self.name ← Laptop, self.price ← 999.99, self.category ← electronics
pass 1 of 66def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str):7 self.name→ Laptop = nameLaptop8 self.price→ 999.99 = price999.999 self.category→ electronics = categoryelectronicsAll 6 passes — pass 1 is the card above pass namepricecategoryself.nameself.priceself.category1 Laptop 999.99 electronics Laptop 999.99 electronics 2 Mouse 29.99 electronics Mouse 29.99 electronics 3 Sticker 2.99 general Sticker 2.99 general 4 Sticker 2.99 general Sticker 2.99 general 5 E-book 14.99 digital E-book 14.99 digital 6 T-shirt 24.99 physical T-shirt 24.99 physical p1 ← Product('Laptop', $999.99, electronics), data ← {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}
79print("--- Standard Constructor ---")80p1→ Product('Laptop', $999.99, electronics) = Product("Laptop", 999.99, "electronics")81print(f"Standard: {p1Product('Laptop', $999.99, electronics)}")8283# Factory: from dictionary84print("\n--- Factory: from_dict ---")85data→ {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'} = {"name": "Mouse", "price": 29.99, "category": "electronics"}86p2 = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'})87print(f"From dict: {p2}")outputStandard: Product('Laptop', $999.99, electronics) --- Factory: from_dict ---def from_dict(cls, data: dict):
15@classmethod16def from_dict(cls<class '__main__.Product'>, data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}: dict):17 """Create Product from a dictionary."""18 return cls(19 name=data["name"]Mouse,20 price=data["price"]29.99,21 category=data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}.get("category", "general")22 )p2 ← Product('Mouse', $29.99, electronics)
85data = {"name": "Mouse", "price": 29.99, "category": "electronics"}86p2→ Product('Mouse', $29.99, electronics) = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'})87print(f"From dict: {p2Product('Mouse', $29.99, electronics)}")8889# Factory: from string90print("\n--- Factory: from_string ---")91p3 = Product<class '__main__.Product'>.from_string("Sticker:2.99")92print(f"From string: {p3}")outputFrom dict: Product('Mouse', $29.99, electronics) --- Factory: from_string ---parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general
pass 1 of 225@classmethod26def from_string(cls<class '__main__.Product'>, sSticker:2.99: str):27 """Create Product from 'name:price:category' string."""28 parts→ ['Sticker', '2.99'] = sSticker:2.99.split(":")29 name→ Sticker = parts[0]Sticker30 price→ 2.99 = float(parts[1]2.99)31 category→ general = parts[2](empty) if len(parts['Sticker', '2.99']) > 2 else "general"32 return cls(nameSticker, price2.99, categorygeneral)p3 ← Product('Sticker', $2.99, general)
90print("\n--- Factory: from_string ---")91p3→ Product('Sticker', $2.99, general) = Product<class '__main__.Product'>.from_string("Sticker:2.99")92print(f"From string: {p3Product('Sticker', $2.99, general)}")9394p4 = Product<class '__main__.Product'>.from_string("Sticker:2.99")95print(f"From string (default category): {p4}")outputFrom string: Product('Sticker', $2.99, general)parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general
pass 2 of 225@classmethod26def from_string(cls<class '__main__.Product'>, sSticker:2.99: str):27 """Create Product from 'name:price:category' string."""28 parts→ ['Sticker', '2.99'] = sSticker:2.99.split(":")29 name→ Sticker = parts[0]Sticker30 price→ 2.99 = float(parts[1]2.99)31 category→ general = parts[2](empty) if len(parts['Sticker', '2.99']) > 2 else "general"32 return cls(nameSticker, price2.99, categorygeneral)p4 ← Product('Sticker', $2.99, general)
94p4→ Product('Sticker', $2.99, general) = Product<class '__main__.Product'>.from_string("Sticker:2.99")95print(f"From string (default category): {p4Product('Sticker', $2.99, general)}")9697# Factory: preset categories98print("\n--- Factory: Preset Categories ---")99p5 = Product<class '__main__.Product'>.create_digital("E-book", 14.99)100p6 = Product.create_physical("T-shirt", 24.99)outputFrom string (default category): Product('Sticker', $2.99, general) --- Factory: Preset Categories ---def create_digital(cls, name: str, price: float):
35@classmethod36def create_digital(cls<class '__main__.Product'>, nameE-book: str, price14.99: float):37 """Create a digital product."""38 return cls(nameE-book, price14.99, "digital")p5 ← Product('E-book', $14.99, digital)
98print("\n--- Factory: Preset Categories ---")99p5→ Product('E-book', $14.99, digital) = Product<class '__main__.Product'>.create_digital("E-book", 14.99)100p6 = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99)101print(f"Digital: {p5}")def create_physical(cls, name: str, price: float):
40@classmethod41def create_physical(cls<class '__main__.Product'>, nameT-shirt: str, price24.99: float):42 """Create a physical product."""43 return cls(nameT-shirt, price24.99, "physical")p6 ← Product('T-shirt', $24.99, physical)
99p5 = Product.create_digital("E-book", 14.99)100p6→ Product('T-shirt', $24.99, physical) = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99)101print(f"Digital: {p5Product('E-book', $14.99, digital)}")102print(f"Physical: {p6Product('T-shirt', $24.99, physical)}")103104# User factory methods105print("\n--- User Factory Methods ---")106admin = User<class '__main__.User'>.create_admin("admin", "admin@example.com")107guest = User.create_guest()outputDigital: Product('E-book', $14.99, digital) Physical: Product('T-shirt', $24.99, physical) --- User Factory Methods ---def create_admin(cls, username: str, email: str):
59@classmethod60def create_admin(cls<class '__main__.User'>, usernameadmin: str, emailadmin@example.com: str):61 """Factory method for admin users."""62 return cls(usernameadmin, emailadmin@example.com, role="admin")self.username ← admin, self.email ← admin@example.com, self.role ← admin
pass 1 of 349def __init__(self(empty), usernameadmin: str, emailadmin@example.com: str, roleadmin: str, is_activeTrue: bool = TrueTrue):50 self.username→ admin = usernameadmin51 self.email→ admin@example.com = emailadmin@example.com52 self.role→ admin = roleadmin53 self.is_active→ True = is_activeTrueAll 3 passes — pass 1 is the card above pass usernameemailroleis_activeself.usernameself.emailself.roleself.is_active1 admin admin@example.com admin True admin admin@example.com admin True 2 guest guest@example.com guest False guest guest@example.com guest False 3 john john@example.com user True john john@example.com user True admin ← User(admin, admin, active)
105print("\n--- User Factory Methods ---")106admin→ User(admin, admin, active) = User<class '__main__.User'>.create_admin("admin", "admin@example.com")107guest = User<class '__main__.User'>.create_guest()def create_guest(cls):
64@classmethod65def create_guest(cls<class '__main__.User'>):66 """Factory method for guest users."""67 return cls("guest", "guest@example.com", role="guest", is_active=False)guest ← User(guest, guest, inactive), user_data ← {'username': 'john', 'email': 'john@example.com', 'role': 'user'}
106admin = User.create_admin("admin", "admin@example.com")107guest→ User(guest, guest, inactive) = User<class '__main__.User'>.create_guest()108109user_data→ {'username': 'john', 'email': 'john@example.com', 'role': 'user'} = {"username": "john", "email": "john@example.com", "role": "user"}110regular = User<class '__main__.User'>.from_dict(user_data{'username': 'john', 'email': 'john@example.com', 'role': 'user'})def from_dict(cls, data: dict):
69@classmethod70def from_dict(cls<class '__main__.User'>, data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}: dict):71 """Create User from dictionary."""72 return cls(**data{'username': 'john', 'email': 'john@example.com', 'role': 'user'}) # Unpack dict as keyword argsregular ← User(john, user, active)
109user_data = {"username": "john", "email": "john@example.com", "role": "user"}110regular→ User(john, user, active) = User<class '__main__.User'>.from_dict(user_data{'username': 'john', 'email': 'john@example.com', 'role': 'user'})111112print(f"Admin: {adminUser(admin, admin, active)}")113print(f"Guest: {guestUser(guest, guest, inactive)}")114print(f"Regular: {regularUser(john, user, active)}")115116print("\n=== Key Points ===")117print("""118Factory methods (@classmethod):119• Return new instances of the class120• Use cls() instead of ClassName()121• Provide alternative ways to create objects122• Can have descriptive names like from_dict, create_admin123• Handle data conversion/validation124""")outputAdmin: User(admin, admin, active) Guest: User(guest, guest, inactive) Regular: User(john, user, active) === Key Points === Factory methods (@classmethod): • Return new instances of the class • Use cls() instead of ClassName() • Provide alternative ways to create objects • Can have descriptive names like from_dict, create_admin • Handle data conversion/validationmain()
127if __name__ == "__main__":128 main()
"""Product with factory methods."""
3class Product:4 """Product with factory methods."""56 def __init__(self, name: str, price: float, category: str):7 self.name = name8 self.price = price9 self.category = category1011 def __repr__(self):12 return f"Product({self.name!r}, ${self.price:.2f}, {self.category})"1314 # Factory method: create from dictionary15 @classmethod16 def from_dict(cls, data: dict):17 """Create Product from a dictionary."""18 return cls(19 name=data["name"],20 price=data["price"],21 category=data.get("category", "general")22 )2324 # Factory method: create from string25 @classmethod26 def from_string(cls, s: str):27 """Create Product from 'name:price:category' string."""28 parts = s.split(":")29 name = parts[0]30 price = float(parts[1])31 category = parts[2] if len(parts) > 2 else "general"32 return cls(name, price, category)3334 # Factory method: create with defaults35 @classmethod36 def create_digital(cls, name: str, price: float):37 """Create a digital product."""38 return cls(name, price, "digital")3940 @classmethod41 def create_physical(cls, name: str, price: float):42 """Create a physical product."""43 return cls(name, price, "physical")444546class User:47 """User with factory methods for different user types."""def main():
75def main():76 print("=== Factory Methods with @classmethod ===\n")7778 # Standard constructor79 print("--- Standard Constructor ---")80 p1 = Product("Laptop", 999.99, "electronics")81 print(f"Standard: {p1}")output=== Factory Methods with @classmethod === --- Standard Constructor ---self.name ← Laptop, self.price ← 999.99, self.category ← electronics
pass 1 of 66def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str):7 self.name→ Laptop = nameLaptop8 self.price→ 999.99 = price999.999 self.category→ electronics = categoryelectronicsAll 6 passes — pass 1 is the card above pass namepricecategoryself.nameself.priceself.category1 Laptop 999.99 electronics Laptop 999.99 electronics 2 Mouse 29.99 electronics Mouse 29.99 electronics 3 Keyboard 79.99 electronics Keyboard 79.99 electronics 4 Sticker 2.99 general Sticker 2.99 general 5 E-book 14.99 digital E-book 14.99 digital 6 T-shirt 24.99 physical T-shirt 24.99 physical p1 ← Product('Laptop', $999.99, electronics), data ← {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}
79print("--- Standard Constructor ---")80p1→ Product('Laptop', $999.99, electronics) = Product("Laptop", 999.99, "electronics")81print(f"Standard: {p1Product('Laptop', $999.99, electronics)}")8283# Factory: from dictionary84print("\n--- Factory: from_dict ---")85data→ {'name': 'Mouse', 'price': 29.99, 'category': 'electronics'} = {"name": "Mouse", "price": 29.99, "category": "electronics"}86p2 = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'})87print(f"From dict: {p2}")outputStandard: Product('Laptop', $999.99, electronics) --- Factory: from_dict ---def from_dict(cls, data: dict):
15@classmethod16def from_dict(cls<class '__main__.Product'>, data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}: dict):17 """Create Product from a dictionary."""18 return cls(19 name=data["name"]Mouse,20 price=data["price"]29.99,21 category=data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'}.get("category", "general")22 )p2 ← Product('Mouse', $29.99, electronics)
85data = {"name": "Mouse", "price": 29.99, "category": "electronics"}86p2→ Product('Mouse', $29.99, electronics) = Product<class '__main__.Product'>.from_dict(data{'name': 'Mouse', 'price': 29.99, 'category': 'electronics'})87print(f"From dict: {p2Product('Mouse', $29.99, electronics)}")8889# Factory: from string90print("\n--- Factory: from_string ---")91p3 = Product<class '__main__.Product'>.from_string("Keyboard:79.99:electronics")92print(f"From string: {p3}")outputFrom dict: Product('Mouse', $29.99, electronics) --- Factory: from_string ---parts ← ['Keyboard', '79.99', 'electronics'], name ← Keyboard
pass 1 of 225@classmethod26def from_string(cls<class '__main__.Product'>, sKeyboard:79.99:electronics: str):27 """Create Product from 'name:price:category' string."""28 parts→ ['Keyboard', '79.99', 'electronics'] = sKeyboard:79.99:electronics.split(":")29 name→ Keyboard = parts[0]Keyboard30 price→ 79.99 = float(parts[1]79.99)31 category→ electronics = parts[2]electronics if len(parts['Keyboard', '79.99', 'electronics']) > 2 else "general"32 return cls(nameKeyboard, price79.99, categoryelectronics)p3 ← Product('Keyboard', $79.99, electronics)
90print("\n--- Factory: from_string ---")91p3→ Product('Keyboard', $79.99, electronics) = Product<class '__main__.Product'>.from_string("Keyboard:79.99:electronics")92print(f"From string: {p3Product('Keyboard', $79.99, electronics)}")9394p4 = Product<class '__main__.Product'>.from_string("Sticker:2.99")95print(f"From string (default category): {p4}")outputFrom string: Product('Keyboard', $79.99, electronics)parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general
pass 2 of 225@classmethod26def from_string(cls<class '__main__.Product'>, sSticker:2.99: str):27 """Create Product from 'name:price:category' string."""28 parts→ ['Sticker', '2.99'] = sSticker:2.99.split(":")29 name→ Sticker = parts[0]Sticker30 price→ 2.99 = float(parts[1]2.99)31 category→ general = parts[2](empty) if len(parts['Sticker', '2.99']) > 2 else "general"32 return cls(nameSticker, price2.99, categorygeneral)p4 ← Product('Sticker', $2.99, general)
94p4→ Product('Sticker', $2.99, general) = Product<class '__main__.Product'>.from_string("Sticker:2.99")95print(f"From string (default category): {p4Product('Sticker', $2.99, general)}")9697# Factory: preset categories98print("\n--- Factory: Preset Categories ---")99p5 = Product<class '__main__.Product'>.create_digital("E-book", 14.99)100p6 = Product.create_physical("T-shirt", 24.99)outputFrom string (default category): Product('Sticker', $2.99, general) --- Factory: Preset Categories ---def create_digital(cls, name: str, price: float):
35@classmethod36def create_digital(cls<class '__main__.Product'>, nameE-book: str, price14.99: float):37 """Create a digital product."""38 return cls(nameE-book, price14.99, "digital")p5 ← Product('E-book', $14.99, digital)
98print("\n--- Factory: Preset Categories ---")99p5→ Product('E-book', $14.99, digital) = Product<class '__main__.Product'>.create_digital("E-book", 14.99)100p6 = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99)101print(f"Digital: {p5}")def create_physical(cls, name: str, price: float):
40@classmethod41def create_physical(cls<class '__main__.Product'>, nameT-shirt: str, price24.99: float):42 """Create a physical product."""43 return cls(nameT-shirt, price24.99, "physical")p6 ← Product('T-shirt', $24.99, physical)
99p5 = Product.create_digital("E-book", 14.99)100p6→ Product('T-shirt', $24.99, physical) = Product<class '__main__.Product'>.create_physical("T-shirt", 24.99)101print(f"Digital: {p5Product('E-book', $14.99, digital)}")102print(f"Physical: {p6Product('T-shirt', $24.99, physical)}")103104# User factory methods105print("\n--- User Factory Methods ---")106admin = User<class '__main__.User'>.create_admin("admin", "admin@example.com")107guest = User.create_guest()outputDigital: Product('E-book', $14.99, digital) Physical: Product('T-shirt', $24.99, physical) --- User Factory Methods ---def create_admin(cls, username: str, email: str):
59@classmethod60def create_admin(cls<class '__main__.User'>, usernameadmin: str, emailadmin@example.com: str):61 """Factory method for admin users."""62 return cls(usernameadmin, emailadmin@example.com, role="admin")self.username ← admin, self.email ← admin@example.com, self.role ← admin
pass 1 of 349def __init__(self(empty), usernameadmin: str, emailadmin@example.com: str, roleadmin: str, is_activeTrue: bool = TrueTrue):50 self.username→ admin = usernameadmin51 self.email→ admin@example.com = emailadmin@example.com52 self.role→ admin = roleadmin53 self.is_active→ True = is_activeTrueAll 3 passes — pass 1 is the card above pass usernameemailroleis_activeself.usernameself.emailself.roleself.is_active1 admin admin@example.com admin True admin admin@example.com admin True 2 guest guest@example.com guest False guest guest@example.com guest False 3 maya maya@example.com editor True maya maya@example.com editor True admin ← User(admin, admin, active)
105print("\n--- User Factory Methods ---")106admin→ User(admin, admin, active) = User<class '__main__.User'>.create_admin("admin", "admin@example.com")107guest = User<class '__main__.User'>.create_guest()def create_guest(cls):
64@classmethod65def create_guest(cls<class '__main__.User'>):66 """Factory method for guest users."""67 return cls("guest", "guest@example.com", role="guest", is_active=False)guest ← User(guest, guest, inactive), user_data ← {'username': 'maya', 'email': 'maya@example.com', 'role': 'editor'}
106admin = User.create_admin("admin", "admin@example.com")107guest→ User(guest, guest, inactive) = User<class '__main__.User'>.create_guest()108109user_data→ {'username': 'maya', 'email': 'maya@example.com', 'role': 'editor'} = {"username": "maya", "email": "maya@example.com", "role": "editor"}110regular = User<class '__main__.User'>.from_dict(user_data{'username': 'maya', 'email': 'maya@example.com', 'role': 'editor'})def from_dict(cls, data: dict):
69@classmethod70def from_dict(cls<class '__main__.User'>, data{'username': 'maya', 'email': 'maya@example.com', 'role': 'editor'}: dict):71 """Create User from dictionary."""72 return cls(**data{'username': 'maya', 'email': 'maya@example.com', 'role': 'editor'}) # Unpack dict as keyword argsregular ← User(maya, editor, active)
109user_data = {"username": "maya", "email": "maya@example.com", "role": "editor"}110regular→ User(maya, editor, active) = User<class '__main__.User'>.from_dict(user_data{'username': 'maya', 'email': 'maya@example.com', 'role': 'editor'})111112print(f"Admin: {adminUser(admin, admin, active)}")113print(f"Guest: {guestUser(guest, guest, inactive)}")114print(f"Regular: {regularUser(maya, editor, active)}")115116print("\n=== Key Points ===")117print("""118Factory methods (@classmethod):119• Return new instances of the class120• Use cls() instead of ClassName()121• Provide alternative ways to create objects122• Can have descriptive names like from_dict, create_admin123• Handle data conversion/validation124""")outputAdmin: User(admin, admin, active) Guest: User(guest, guest, inactive) Regular: User(maya, editor, active) === Key Points === Factory methods (@classmethod): • Return new instances of the class • Use cls() instead of ClassName() • Provide alternative ways to create objects • Can have descriptive names like from_dict, create_admin • Handle data conversion/validationmain()
127if __name__ == "__main__":128 main()
cls(...) creates instance of whatever class called it. Works with subclasses.
Alternative constructors
Multiple ways to create objects.
# Alternative Constructors with @classmethod
from datetime import date, datetime
class Date:
"""Custom date class with alternative constructors."""
def __init__(self, year: int, month: int, day: int):
self.year = year
self.month = month
self.day = day
def __repr__(self):
return f"Date({self.year}, {self.month}, {self.day})"
def __str__(self):
return f"{self.year}-{self.month:02d}-{self.day:02d}"
# Alternative constructor: from string
@classmethod
def from_string(cls, date_string: str, sep: str = "-"):
"""Create Date from 'YYYY-MM-DD' string."""
parts = date_string.split(sep)
year, month, day = int(parts[0]), int(parts[1]), int(parts[2])
return cls(year, month, day)
# Alternative constructor: from timestamp
@classmethod
def from_timestamp(cls, timestamp: float):
"""Create Date from Unix timestamp."""
dt = datetime.fromtimestamp(timestamp)
return cls(dt.year, dt.month, dt.day)
# Alternative constructor: today
@classmethod
def today(cls):
"""Create Date for today."""
t = date.today().replace(year=2025, month=1, day=15)
return cls(t.year, t.month, t.day)
class Person:
"""Person with multiple ways to construct."""
def __init__(self, first_name: str, last_name: str, birth_year: int):
self.first_name = first_name
self.last_name = last_name
self.birth_year = birth_year
@property
def full_name(self) -> str:
return f"{self.first_name} {self.last_name}"
@property
def age(self) -> int:
return 2025 - self.birth_year
def __repr__(self):
return f"Person({self.full_name!r}, age={self.age})"
# Alternative: from full name string
@classmethod
def from_full_name(cls, full_name: str, birth_year: int):
"""Create Person from 'First Last' string."""
parts = full_name.split()
first = parts[0]
last = " ".join(parts[1:]) if len(parts) > 1 else ""
return cls(first, last, birth_year)
# Alternative: from birth date (calculate year)
@classmethod
def from_birth_date(cls, first: str, last: str, birth_date: date):
"""Create Person from birth date."""
return cls(first, last, birth_date.year)
class Rectangle:
"""Rectangle with different construction methods."""
def __init__(self, width: float, height: float):
self.width = width
self.height = height
@property
def area(self) -> float:
return self.width * self.height
def __repr__(self):
return f"Rectangle({self.width}x{self.height}, area={self.area})"
# Alternative: create square
@classmethod
def square(cls, side: float):
"""Create a square (width == height)."""
return cls(side, side)
# Alternative: from area with aspect ratio
@classmethod
def from_area(cls, area: float, aspect_ratio: float = 1.0):
"""Create Rectangle from area and aspect ratio (width/height)."""
height = (area / aspect_ratio) ** 0.5
width = height * aspect_ratio
return cls(width, height)
def main():
print("=== Alternative Constructors ===\n")
# Date constructors
print("--- Date Constructors ---")
d1 = Date(2025, 1, 15)
print(f"Standard: {d1}")
d2 = Date.from_string("2025-06-20")
print(f"From string: {d2}")
d3 = Date.from_string("2025/12/25", sep="/")
print(f"From string (custom sep): {d3}")
d4 = Date.from_timestamp(1735689600) # Jan 1, 2025
print(f"From timestamp: {d4}")
d5 = Date.today()
print(f"Today: {d5}")
# Person constructors
print("\n--- Person Constructors ---")
p1 = Person("John", "Doe", 1990)
print(f"Standard: {p1}")
p2 = Person.from_full_name("Jane Smith", 1985)
print(f"From full name: {p2}")
p3 = Person.from_birth_date("Bob", "Johnson", date(1995, 6, 15))
print(f"From birth date: {p3}")
# Rectangle constructors
print("\n--- Rectangle Constructors ---")
r1 = Rectangle(10, 5)
print(f"Standard: {r1}")
r2 = Rectangle.square(7)
print(f"Square: {r2}")
r3 = Rectangle.from_area(100, aspect_ratio=2.0)
print(f"From area (2:1): {r3}")
r4 = Rectangle.from_area(100, aspect_ratio=1.0)
print(f"From area (1:1): {r4}")
print("\n=== Key Points ===")
print("""
Alternative constructors:
• Provide different ways to create objects
• Handle format conversion (string → object)
• Create special cases (square from Rectangle)
• Perform calculations during creation
• Named clearly: from_*, create_*, today, etc.
""")
if __name__ == "__main__":
main()
"""Custom date class with alternative constructors."""
6class Date:7 """Custom date class with alternative constructors."""89 def __init__(self, year: int, month: int, day: int): #?init10 self.year = year #?set_year11 self.month = month #?set_month12 self.day = day #?set_day1314 def __repr__(self): #?repr15 return f"Date({self.year}, {self.month}, {self.day})"1617 def __str__(self): #?str18 return f"{self.year}-{self.month:02d}-{self.day:02d}"1920 # Alternative constructor: from string #?from_string_comment21 @classmethod #?from_string_decorator22 def from_string(cls, date_string: str, sep: str = "-"): #?from_string_def23 """Create Date from 'YYYY-MM-DD' string."""24 parts = date_string.split(sep) #?split_parts25 year, month, day = int(parts[0]), int(parts[1]), int(parts[2]) #?unpack_parts26 return cls(year, month, day) #?return_from_string2728 # Alternative constructor: from timestamp #?from_timestamp_comment29 @classmethod #?from_timestamp_decorator30 def from_timestamp(cls, timestamp: float): #?from_timestamp_def31 """Create Date from Unix timestamp."""32 dt = datetime.fromtimestamp(timestamp) #?convert_timestamp33 return cls(dt.year, dt.month, dt.day) #?return_from_timestamp3435 # Alternative constructor: today #?today_comment36 @classmethod #?today_decorator37 def today(cls): #?today_def38 """Create Date for today."""39 t = date.today().replace(year=2025, month=1, day=15) #?get_today40 return cls(t.year, t.month, t.day) #?return_today414243class Person:44 """Person with multiple ways to construct."""4546 def __init__(self, first_name: str, last_name: str, birth_year: int): #?person_init47 self.first_name = first_name48 self.last_name = last_name49 self.birth_year = birth_year5051 @property #?full_name_property52 def full_name(self) -> str: #?full_name_def53 return f"{self.first_name} {self.last_name}"5455 @property #?age_property56 def age(self) -> int: #?age_def57 return 2025 - self.birth_year #?calc_age5859 def __repr__(self): #?person_repr60 return f"Person({self.full_name!r}, age={self.age})"6162 # Alternative: from full name string #?from_full_name_comment63 @classmethod #?from_full_name_decorator64 def from_full_name(cls, full_name: str, birth_year: int): #?from_full_name_def65 """Create Person from 'First Last' string."""66 parts = full_name.split() #?split_name67 first = parts[0] #?get_first68 last = " ".join(parts[1:]) if len(parts) > 1 else "" #?get_last69 return cls(first, last, birth_year) #?return_from_full_name7071 # Alternative: from birth date (calculate year) #?from_birth_date_comment72 @classmethod #?from_birth_date_decorator73 def from_birth_date(cls, first: str, last: str, birth_date: date): #?from_birth_date_def74 """Create Person from birth date."""75 return cls(first, last, birth_date.year) #?return_from_birth_date767778class Rectangle:79 """Rectangle with different construction methods."""def main():
107def main():108 print("=== Alternative Constructors ===\n")109110 # Date constructors #?date_demo111 print("--- Date Constructors ---")112113 d1 = Date(2025, 1, 15) #?create_d1114 print(f"Standard: {d1}") #?print_d1output=== Alternative Constructors === --- Date Constructors ---self.year ← 2025, self.month ← 1, self.day ← 15
pass 1 of 59def __init__(self(empty), year2025: int, month1: int, day15: int): #?init10 self.year→ 2025 = year2025 #?set_year11 self.month→ 1 = month1 #?set_month12 self.day→ 15 = day15 #?set_dayAll 5 passes — pass 1 is the card above pass monthdayself.yearself.monthself.day1 1 15 2025 1 15 2 6 20 2025 6 20 3 12 25 2025 12 25 4 1 1 2025 1 1 5 1 15 2025 1 15 d1 ← 2025-01-15
113d1→ 2025-01-15 = Date(2025, 1, 15) #?create_d1114print(f"Standard: {d12025-01-15}") #?print_d1115116d2 = Date<class '__main__.Date'>.from_string("2025-06-20") #?create_d2117print(f"From string: {d2}") #?print_d2outputStandard: 2025-01-15parts ← ['2025', '06', '20'], year ← 2025, month ← 6, day ← 20
pass 1 of 221@classmethod #?from_string_decorator22def from_string(cls<class '__main__.Date'>, date_string2025-06-20: str, sep-: str = "-"): #?from_string_def23 """Create Date from 'YYYY-MM-DD' string."""24 parts→ ['2025', '06', '20'] = date_string2025-06-20.split(sep-) #?split_parts25 year→ 2025, month→ 6, day→ 20 = int(parts[0]2025), int(parts[1]06), int(parts[2]20) #?unpack_parts26 return cls(year2025, month6, day20) #?return_from_stringd2 ← 2025-06-20
116d2→ 2025-06-20 = Date<class '__main__.Date'>.from_string("2025-06-20") #?create_d2117print(f"From string: {d22025-06-20}") #?print_d2118119d3 = Date<class '__main__.Date'>.from_string("2025/12/25", sep="/") #?create_d3120print(f"From string (custom sep): {d3}") #?print_d3outputFrom string: 2025-06-20parts ← ['2025', '12', '25'], year ← 2025, month ← 12, day ← 25
pass 2 of 221@classmethod #?from_string_decorator22def from_string(cls<class '__main__.Date'>, date_string2025/12/25: str, sep/: str = "-"): #?from_string_def23 """Create Date from 'YYYY-MM-DD' string."""24 parts→ ['2025', '12', '25'] = date_string2025/12/25.split(sep/) #?split_parts25 year→ 2025, month→ 12, day→ 25 = int(parts[0]2025), int(parts[1]12), int(parts[2]25) #?unpack_parts26 return cls(year2025, month12, day25) #?return_from_stringd3 ← 2025-12-25
119d3→ 2025-12-25 = Date<class '__main__.Date'>.from_string("2025/12/25", sep="/") #?create_d3120print(f"From string (custom sep): {d32025-12-25}") #?print_d3121122d4 = Date<class '__main__.Date'>.from_timestamp(1735689600) # Jan 1, 2025123print(f"From timestamp: {d4}") #?print_d4outputFrom string (custom sep): 2025-12-25dt ← 2025-01-01 00:00:00
29@classmethod #?from_timestamp_decorator30def from_timestamp(cls<class '__main__.Date'>, timestamp1735689600: float): #?from_timestamp_def31 """Create Date from Unix timestamp."""32 dt→ 2025-01-01 00:00:00 = datetime<class 'datetime.datetime'>.fromtimestamp(timestamp1735689600) #?convert_timestamp33 return cls(dt.year2025, dt.month1, dt.day1) #?return_from_timestampd4 ← 2025-01-01
122d4→ 2025-01-01 = Date<class '__main__.Date'>.from_timestamp(1735689600) # Jan 1, 2025123print(f"From timestamp: {d42025-01-01}") #?print_d4124125d5 = Date<class '__main__.Date'>.today() #?create_d5126print(f"Today: {d5}") #?print_d5outputFrom timestamp: 2025-01-01t ← 2025-01-15
36@classmethod #?today_decorator37def today(cls<class '__main__.Date'>): #?today_def38 """Create Date for today."""39 t→ 2025-01-15 = date<class 'datetime.date'>.today().replace(year=2025, month=1, day=15) #?get_today40 return cls(t.year2025, t.month1, t.day15) #?return_todayd5 ← 2025-01-15
125d5→ 2025-01-15 = Date<class '__main__.Date'>.today() #?create_d5126print(f"Today: {d52025-01-15}") #?print_d5127128# Person constructors #?person_demo129print("\n--- Person Constructors ---")130131p1 = Person("John", "Doe", 1990) #?create_p1132print(f"Standard: {p1}") #?print_p1outputToday: 2025-01-15 --- Person Constructors ---self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990
pass 1 of 346def __init__(self(empty), first_nameJohn: str, last_nameDoe: str, birth_year1990: int): #?person_init47 self.first_name→ John = first_nameJohn48 self.last_name→ Doe = last_nameDoe49 self.birth_year→ 1990 = birth_year1990All 3 passes — pass 1 is the card above pass first_namelast_namebirth_yearself.first_nameself.last_nameself.birth_year1 John Doe 1990 John Doe 1990 2 Jane Smith 1985 Jane Smith 1985 3 Bob Johnson 1995 Bob Johnson 1995 p1 ← Person('John Doe', age=35)
131p1→ Person('John Doe', age=35) = Person("John", "Doe", 1990) #?create_p1132print(f"Standard: {p1Person('John Doe', age=35)}") #?print_p1def full_name(self) -> str: #?full_name_def
pass 1 of 351@property #?full_name_property52def full_name(selfPerson('John Doe', age=35)) -> str: #?full_name_def53 return f"{self.first_nameJohn} {self.last_nameDoe}"All 3 passes — pass 1 is the card above pass selfself.first_nameself.last_name1 Person('John Doe', age=35) John Doe 2 Person('Jane Smith', age=40) Jane Smith 3 Person('Bob Johnson', age=30) Bob Johnson def age(self) -> int: #?age_def
pass 1 of 355@property #?age_property56def age(selfPerson('John Doe', age=35)) -> int: #?age_def57 return 2025 - self.birth_year1990 #?calc_ageAll 3 passes — pass 1 is the card above pass selfself.birth_year1 Person('John Doe', age=35) 1990 2 Person('Jane Smith', age=40) 1985 3 Person('Bob Johnson', age=30) 1995 print(f"Standard: {p1}") #?print_p1
131p1 = Person("John", "Doe", 1990) #?create_p1132print(f"Standard: {p1Person('John Doe', age=35)}") #?print_p1133134p2 = Person<class '__main__.Person'>.from_full_name("Jane Smith", 1985) #?create_p2135print(f"From full name: {p2}") #?print_p2outputStandard: Person('John Doe', age=35)parts ← ['Jane', 'Smith'], first ← Jane, last ← Smith
63@classmethod #?from_full_name_decorator64def from_full_name(cls<class '__main__.Person'>, full_nameJane Smith: str, birth_year1985: int): #?from_full_name_def65 """Create Person from 'First Last' string."""66 parts→ ['Jane', 'Smith'] = full_nameJane Smith.split() #?split_name67 first→ Jane = parts[0]Jane #?get_first68 last→ Smith = " ".join(parts[1:]['Smith']) if len(parts['Jane', 'Smith']) > 1 else "" #?get_last69 return cls(firstJane, lastSmith, birth_year1985) #?return_from_full_namep2 ← Person('Jane Smith', age=40)
134p2→ Person('Jane Smith', age=40) = Person<class '__main__.Person'>.from_full_name("Jane Smith", 1985) #?create_p2135print(f"From full name: {p2Person('Jane Smith', age=40)}") #?print_p2print(f"From full name: {p2}") #?print_p2
134p2 = Person.from_full_name("Jane Smith", 1985) #?create_p2135print(f"From full name: {p2Person('Jane Smith', age=40)}") #?print_p2136137p3 = Person<class '__main__.Person'>.from_birth_date("Bob", "Johnson", date(1995, 6, 15)) #?create_p3138print(f"From birth date: {p3}") #?print_p3outputFrom full name: Person('Jane Smith', age=40)def from_birth_date(cls, first: str, last: str, birth_date: date): #?…
72@classmethod #?from_birth_date_decorator73def from_birth_date(cls<class '__main__.Person'>, firstBob: str, lastJohnson: str, birth_date1995-06-15: date): #?from_birth_date_def74 """Create Person from birth date."""75 return cls(firstBob, lastJohnson, birth_date.year1995) #?return_from_birth_datep3 ← Person('Bob Johnson', age=30)
137p3→ Person('Bob Johnson', age=30) = Person<class '__main__.Person'>.from_birth_date("Bob", "Johnson", date(1995, 6, 15)) #?create_p3138print(f"From birth date: {p3Person('Bob Johnson', age=30)}") #?print_p3print(f"From birth date: {p3}") #?print_p3
137p3 = Person.from_birth_date("Bob", "Johnson", date(1995, 6, 15)) #?create_p3138print(f"From birth date: {p3Person('Bob Johnson', age=30)}") #?print_p3139140# Rectangle constructors #?rect_demo141print("\n--- Rectangle Constructors ---")142143r1 = Rectangle(10, 5) #?create_r1144print(f"Standard: {r1}") #?print_r1outputFrom birth date: Person('Bob Johnson', age=30) --- Rectangle Constructors ---self.width ← 10, self.height ← 5
pass 1 of 481def __init__(self(empty), width10: float, height5: float): #?rect_init82 self.width→ 10 = width1083 self.height→ 5 = height5All 4 passes — pass 1 is the card above pass widthheightself.widthself.height1 10 5 10 5 2 7 7 7 7 3 14.142135623730951 7.0710678118654755 14.142135623730951 7.0710678118654755 4 10.0 10.0 10.0 10.0 r1 ← Rectangle(10x5, area=50)
143r1→ Rectangle(10x5, area=50) = Rectangle(10, 5) #?create_r1144print(f"Standard: {r1Rectangle(10x5, area=50)}") #?print_r1def area(self) -> float: #?area_def
pass 1 of 485@property #?area_property86def area(selfRectangle(10x5, area=50)) -> float: #?area_def87 return self.width10 * self.height5All 4 passes — pass 1 is the card above pass selfself.widthself.height1 Rectangle(10x5, area=50) 10 5 2 Rectangle(7x7, area=49) 7 7 3 Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001) 14.142135623730951 7.0710678118654755 4 Rectangle(10.0x10.0, area=100.0) 10.0 10.0 print(f"Standard: {r1}") #?print_r1
143r1 = Rectangle(10, 5) #?create_r1144print(f"Standard: {r1Rectangle(10x5, area=50)}") #?print_r1145146r2 = Rectangle<class '__main__.Rectangle'>.square(7) #?create_r2147print(f"Square: {r2}") #?print_r2outputStandard: Rectangle(10x5, area=50)def square(cls, side: float): #?square_def
93@classmethod #?square_decorator94def square(cls<class '__main__.Rectangle'>, side7: float): #?square_def95 """Create a square (width == height)."""96 return cls(side7, side) #?return_squarer2 ← Rectangle(7x7, area=49)
146r2→ Rectangle(7x7, area=49) = Rectangle<class '__main__.Rectangle'>.square(7) #?create_r2147print(f"Square: {r2Rectangle(7x7, area=49)}") #?print_r2print(f"Square: {r2}") #?print_r2
146r2 = Rectangle.square(7) #?create_r2147print(f"Square: {r2Rectangle(7x7, area=49)}") #?print_r2148149r3 = Rectangle<class '__main__.Rectangle'>.from_area(100, aspect_ratio=2.0) #?create_r3150print(f"From area (2:1): {r3}") #?print_r3outputSquare: Rectangle(7x7, area=49)height ← 7.0710678118654755, width ← 14.142135623730951
pass 1 of 299@classmethod #?from_area_decorator100def from_area(cls<class '__main__.Rectangle'>, area100: float, aspect_ratio2.0: float = 1.0): #?from_area_def101 """Create Rectangle from area and aspect ratio (width/height)."""102 height→ 7.0710678118654755 = (area100 / aspect_ratio2.0) ** 0.5 #?calc_height103 width→ 14.142135623730951 = height7.0710678118654755 * aspect_ratio2.0 #?calc_width104 return cls(width14.142135623730951, height7.0710678118654755) #?return_from_arear3 ← Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001)
149r3→ Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001) = Rectangle<class '__main__.Rectangle'>.from_area(100, aspect_ratio=2.0) #?create_r3150print(f"From area (2:1): {r3Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001)}") #?print_r3print(f"From area (2:1): {r3}") #?print_r3
149r3 = Rectangle.from_area(100, aspect_ratio=2.0) #?create_r3150print(f"From area (2:1): {r3Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001)}") #?print_r3151152r4 = Rectangle<class '__main__.Rectangle'>.from_area(100, aspect_ratio=1.0) #?create_r4153print(f"From area (1:1): {r4}") #?print_r4outputFrom area (2:1): Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001)height ← 10.0, width ← 10.0
pass 2 of 299@classmethod #?from_area_decorator100def from_area(cls<class '__main__.Rectangle'>, area100: float, aspect_ratio1.0: float = 1.0): #?from_area_def101 """Create Rectangle from area and aspect ratio (width/height)."""102 height→ 10.0 = (area100 / aspect_ratio1.0) ** 0.5 #?calc_height103 width→ 10.0 = height10.0 * aspect_ratio1.0 #?calc_width104 return cls(width10.0, height10.0) #?return_from_arear4 ← Rectangle(10.0x10.0, area=100.0)
152r4→ Rectangle(10.0x10.0, area=100.0) = Rectangle<class '__main__.Rectangle'>.from_area(100, aspect_ratio=1.0) #?create_r4153print(f"From area (1:1): {r4Rectangle(10.0x10.0, area=100.0)}") #?print_r4print(f"From area (1:1): {r4}") #?print_r4
152r4 = Rectangle.from_area(100, aspect_ratio=1.0) #?create_r4153print(f"From area (1:1): {r4Rectangle(10.0x10.0, area=100.0)}") #?print_r4154155print("\n=== Key Points ===")156print("""157Alternative constructors:158• Provide different ways to create objects159• Handle format conversion (string → object)160• Create special cases (square from Rectangle)161• Perform calculations during creation162• Named clearly: from_*, create_*, today, etc.163""")outputFrom area (1:1): Rectangle(10.0x10.0, area=100.0) === Key Points === Alternative constructors: • Provide different ways to create objects • Handle format conversion (string → object) • Create special cases (square from Rectangle) • Perform calculations during creation • Named clearly: from_*, create_*, today, etc.main()
166if __name__ == "__main__":167 main()
from_json(), from_string(), from_file() - all return new instances.
Utility functions with @staticmethod
Helper functions that don't need class or instance.
# Using @staticmethod for Utility Functions
import re
from typing import List
class StringUtils:
"""Utility class with static methods for string operations."""
@staticmethod
def is_palindrome(s: str) -> bool:
"""Check if string is a palindrome."""
cleaned = s.lower().replace(" ", "")
return cleaned == cleaned[::-1]
@staticmethod
def count_vowels(s: str) -> int:
"""Count vowels in a string."""
return sum(1 for c in s.lower() if c in "aeiou")
@staticmethod
def is_valid_email(email: str) -> bool:
"""Check if email format is valid."""
pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
return bool(re.match(pattern, email))
@staticmethod
def slugify(s: str) -> str:
"""Convert string to URL-friendly slug."""
s = s.lower().strip()
s = re.sub(r"[^\w\s-]", "", s)
s = re.sub(r"[\s_-]+", "-", s)
return s
class MathUtils:
"""Utility class for math operations."""
@staticmethod
def factorial(n: int) -> int:
"""Calculate factorial of n."""
if n < 0:
raise ValueError("Factorial not defined for negative numbers")
result = 1
for i in range(2, n + 1):
result *= i
return result
@staticmethod
def is_prime(n: int) -> bool:
"""Check if n is prime."""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
@staticmethod
def gcd(a: int, b: int) -> int:
"""Calculate greatest common divisor."""
while b:
a, b = b, a % b
return abs(a)
@staticmethod
def clamp(value: float, min_val: float, max_val: float) -> float:
"""Clamp value between min and max."""
return max(min_val, min(max_val, value))
class Validator:
"""Validation utility class."""
@staticmethod
def is_valid_username(username: str) -> tuple[bool, str]:
"""Validate username, return (valid, message)."""
if len(username) < 3:
return False, "Username must be at least 3 characters"
if len(username) > 20:
return False, "Username must be at most 20 characters"
if not username[0].isalpha():
return False, "Username must start with a letter"
if not re.match(r"^[a-zA-Z0-9_]+$", username):
return False, "Username can only contain letters, numbers, and underscores"
return True, "Valid username"
@staticmethod
def is_strong_password(password: str) -> tuple[bool, List[str]]:
"""Check password strength, return (strong, issues)."""
issues = []
if len(password) < 8:
issues.append("Must be at least 8 characters")
if not re.search(r"[A-Z]", password):
issues.append("Must contain uppercase letter")
if not re.search(r"[a-z]", password):
issues.append("Must contain lowercase letter")
if not re.search(r"\d", password):
issues.append("Must contain digit")
if not re.search(r"[!@#$%^&*]", password):
issues.append("Must contain special character (!@#$%^&*)")
return len(issues) == 0, issues
def main():
print("=== Static Methods for Utilities ===\n")
# String utilities
print("--- StringUtils ---")
print(f"'radar' is palindrome: {StringUtils.is_palindrome('radar')}")
print(f"'hello' is palindrome: {StringUtils.is_palindrome('hello')}")
print(f"'A man a plan a canal Panama': {StringUtils.is_palindrome('A man a plan a canal Panama')}")
print(f"\nVowels in 'hello world': {StringUtils.count_vowels('hello world')}")
print(f"\n'user@example.com' valid: {StringUtils.is_valid_email('user@example.com')}")
print(f"'invalid-email' valid: {StringUtils.is_valid_email('invalid-email')}")
print(f"\nSlugify 'Hello World!': {StringUtils.slugify('Hello World!')}")
print(f"Slugify ' My Blog Post ': {StringUtils.slugify(' My Blog Post ')}")
# Math utilities
print("\n--- MathUtils ---")
print(f"5! = {MathUtils.factorial(5)}")
primes = [n for n in range(20) if MathUtils.is_prime(n)]
print(f"Primes under 20: {primes}")
print(f"GCD(48, 18) = {MathUtils.gcd(48, 18)}")
print(f"Clamp 15 to [0, 10]: {MathUtils.clamp(15, 0, 10)}")
print(f"Clamp -5 to [0, 10]: {MathUtils.clamp(-5, 0, 10)}")
print(f"Clamp 5 to [0, 10]: {MathUtils.clamp(5, 0, 10)}")
# Validation utilities
print("\n--- Validator ---")
usernames = ["alice", "ab", "user_123", "1invalid", "valid_user_name_here_now"]
for username in usernames:
valid, message = Validator.is_valid_username(username)
status = "✓" if valid else "✗"
print(f" {status} '{username}': {message}")
print("\nPassword strength:")
passwords = ["weak", "Better123", "Strong@Pass1"]
for password in passwords:
strong, issues = Validator.is_strong_password(password)
if strong:
print(f" ✓ '{password}': Strong password")
else:
print(f" ✗ '{password}': {', '.join(issues)}")
print("\n=== Key Points ===")
print("""
@staticmethod is good for:
• Utility functions that don't need self/cls
• Functions logically related to the class
• Validation helpers
• Math/string operations
• Pure functions (no side effects)
Why use static instead of module function?
• Logical grouping (StringUtils.is_palindrome)
• Namespace organization
• Can be overridden in subclasses
""")
if __name__ == "__main__":
main()
"""Utility class with static methods for string operations."""
7class StringUtils:8 """Utility class with static methods for string operations."""910 @staticmethod #?is_palindrome_decorator11 def is_palindrome(s: str) -> bool: #?is_palindrome_def12 """Check if string is a palindrome."""13 cleaned = s.lower().replace(" ", "") #?clean_string14 return cleaned == cleaned[::-1] #?check_palindrome1516 @staticmethod #?count_vowels_decorator17 def count_vowels(s: str) -> int: #?count_vowels_def18 """Count vowels in a string."""19 return sum(1 for c in s.lower() if c in "aeiou") #?count_vowels_body2021 @staticmethod #?is_valid_email_decorator22 def is_valid_email(email: str) -> bool: #?is_valid_email_def23 """Check if email format is valid."""24 pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" #?email_pattern25 return bool(re.match(pattern, email)) #?match_email2627 @staticmethod #?slugify_decorator28 def slugify(s: str) -> str: #?slugify_def29 """Convert string to URL-friendly slug."""30 s = s.lower().strip() #?lowercase_strip31 s = re.sub(r"[^\w\s-]", "", s) #?remove_special32 s = re.sub(r"[\s_-]+", "-", s) #?replace_spaces33 return s #?return_slug343536class MathUtils:37 """Utility class for math operations."""3839 @staticmethod #?factorial_decorator40 def factorial(n: int) -> int: #?factorial_def41 """Calculate factorial of n."""42 if n < 0: #?check_negative43 raise ValueError("Factorial not defined for negative numbers")44 result = 1 #?init_result45 for i in range(2, n + 1): #?factorial_loop46 result *= i47 return result #?return_factorial4849 @staticmethod #?is_prime_decorator50 def is_prime(n: int) -> bool: #?is_prime_def51 """Check if n is prime."""52 if n < 2: #?check_less_than_253 return False54 for i in range(2, int(n ** 0.5) + 1): #?prime_loop55 if n % i == 0: #?divisible_check56 return False57 return True #?is_prime_return5859 @staticmethod #?gcd_decorator60 def gcd(a: int, b: int) -> int: #?gcd_def61 """Calculate greatest common divisor."""62 while b: #?gcd_loop63 a, b = b, a % b #?gcd_swap64 return abs(a) #?return_gcd6566 @staticmethod #?clamp_decorator67 def clamp(value: float, min_val: float, max_val: float) -> float: #?clamp_def68 """Clamp value between min and max."""69 return max(min_val, min(max_val, value)) #?clamp_return707172class Validator:73 """Validation utility class."""def main():
107def main():108 print("=== Static Methods for Utilities ===\n")109110 # String utilities #?string_demo111 print("--- StringUtils ---")112113 print(f"'radar' is palindrome: {StringUtils<class '__main__.StringUtils'>.is_palindrome('radar')}") #?test_palindrome1114 print(f"'hello' is palindrome: {StringUtils.is_palindrome('hello')}") #?test_palindrome2output=== Static Methods for Utilities === --- StringUtils ---cleaned ← radar
pass 1 of 310@staticmethod #?is_palindrome_decorator11def is_palindrome(sradar: str) -> bool: #?is_palindrome_def12 """Check if string is a palindrome."""13 cleaned→ radar = sradar.lower().replace(" ", "") #?clean_string14 return cleanedradar == cleaned[::-1]radar #?check_palindromeAll 3 passes — pass 1 is the card above pass scleaned[::-1]cleaned1 radar radar radar 2 hello olleh hello 3 A man a plan a canal Panama amanaplanacanalpanama amanaplanacanalpanama print(f"'radar' is palindrome: {StringUtils.is_palindrome('radar')}") …
113print(f"'radar' is palindrome: {StringUtils<class '__main__.StringUtils'>.is_palindrome('radar')}") #?test_palindrome1114print(f"'hello' is palindrome: {StringUtils<class '__main__.StringUtils'>.is_palindrome('hello')}") #?test_palindrome2115print(f"'A man a plan a canal Panama': {StringUtils.is_palindrome('A man a plan a canal Panama')}") #?test_palindrome3output'radar' is palindrome: Trueprint(f"'hello' is palindrome: {StringUtils.is_palindrome('hello')}") …
113print(f"'radar' is palindrome: {StringUtils.is_palindrome('radar')}") #?test_palindrome1114print(f"'hello' is palindrome: {StringUtils<class '__main__.StringUtils'>.is_palindrome('hello')}") #?test_palindrome2115print(f"'A man a plan a canal Panama': {StringUtils<class '__main__.StringUtils'>.is_palindrome('A man a plan a canal Panama')}") #?test_palindrome3output'hello' is palindrome: Falseprint(f"'A man a plan a canal Panama': {StringUtils.is_palindrome('A m…
114print(f"'hello' is palindrome: {StringUtils.is_palindrome('hello')}") #?test_palindrome2115print(f"'A man a plan a canal Panama': {StringUtils<class '__main__.StringUtils'>.is_palindrome('A man a plan a canal Panama')}") #?test_palindrome3116117print(f"\nVowels in 'hello world': {StringUtils<class '__main__.StringUtils'>.count_vowels('hello world')}") #?test_vowelsoutput'A man a plan a canal Panama': Truedef count_vowels(s: str) -> int: #?count_vowels_def
16@staticmethod #?count_vowels_decorator17def count_vowels(shello world: str) -> int: #?count_vowels_def18 """Count vowels in a string."""19 return sum(1 for c in shello world.lower() if c in "aeiou") #?count_vowels_bodyprint(f" Vowels in 'hello world': {StringUtils.count_vowels('hello wor…
117print(f"\nVowels in 'hello world': {StringUtils<class '__main__.StringUtils'>.count_vowels('hello world')}") #?test_vowels118119print(f"\n'user@example.com' valid: {StringUtils<class '__main__.StringUtils'>.is_valid_email('user@example.com')}") #?test_email1120print(f"'invalid-email' valid: {StringUtils.is_valid_email('invalid-email')}") #?test_email2output Vowels in 'hello world': 3pattern ← ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
pass 1 of 221@staticmethod #?is_valid_email_decorator22def is_valid_email(emailuser@example.com: str) -> bool: #?is_valid_email_def23 """Check if email format is valid."""24 pattern→ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" #?email_pattern25 return bool(re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.match(pattern^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$, emailuser@example.com)) #?match_emailprint(f" 'user@example.com' valid: {StringUtils.is_valid_email('user@e…
119print(f"\n'user@example.com' valid: {StringUtils<class '__main__.StringUtils'>.is_valid_email('user@example.com')}") #?test_email1120print(f"'invalid-email' valid: {StringUtils<class '__main__.StringUtils'>.is_valid_email('invalid-email')}") #?test_email2output 'user@example.com' valid: Truepattern ← ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
pass 2 of 221@staticmethod #?is_valid_email_decorator22def is_valid_email(emailinvalid-email: str) -> bool: #?is_valid_email_def23 """Check if email format is valid."""24 pattern→ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" #?email_pattern25 return bool(re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.match(pattern^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$, emailinvalid-email)) #?match_emailprint(f"'invalid-email' valid: {StringUtils.is_valid_email('invalid-em…
119print(f"\n'user@example.com' valid: {StringUtils.is_valid_email('user@example.com')}") #?test_email1120print(f"'invalid-email' valid: {StringUtils<class '__main__.StringUtils'>.is_valid_email('invalid-email')}") #?test_email2121122print(f"\nSlugify 'Hello World!': {StringUtils<class '__main__.StringUtils'>.slugify('Hello World!')}") #?test_slugify1123print(f"Slugify ' My Blog Post ': {StringUtils.slugify(' My Blog Post ')}") #?test_slugify2output'invalid-email' valid: Falses ← hello world!
pass 1 of 227@staticmethod #?slugify_decorator28def slugify(sHello World!: str) -> str: #?slugify_def29 """Convert string to URL-friendly slug."""30 s→ hello world! = s.lower().strip() #?lowercase_strip31 s→ hello world = re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.sub(r"[^\w\s-]", "", s) #?remove_special32 s→ hello-world = re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.sub(r"[\s_-]+", "-", s) #?replace_spaces33 return shello-world #?return_slugprint(f" Slugify 'Hello World!': {StringUtils.slugify('Hello World!')}…
122print(f"\nSlugify 'Hello World!': {StringUtils<class '__main__.StringUtils'>.slugify('Hello World!')}") #?test_slugify1123print(f"Slugify ' My Blog Post ': {StringUtils<class '__main__.StringUtils'>.slugify(' My Blog Post ')}") #?test_slugify2output Slugify 'Hello World!': hello-worlds ← my blog post
pass 2 of 227@staticmethod #?slugify_decorator28def slugify(s My Blog Post : str) -> str: #?slugify_def29 """Convert string to URL-friendly slug."""30 s→ my blog post = s.lower().strip() #?lowercase_strip31 s→ my blog post = re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.sub(r"[^\w\s-]", "", s) #?remove_special32 s→ my-blog-post = re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.sub(r"[\s_-]+", "-", s) #?replace_spaces33 return smy-blog-post #?return_slugprint(f"Slugify ' My Blog Post ': {StringUtils.slugify(' My Blog Po…
122print(f"\nSlugify 'Hello World!': {StringUtils.slugify('Hello World!')}") #?test_slugify1123print(f"Slugify ' My Blog Post ': {StringUtils<class '__main__.StringUtils'>.slugify(' My Blog Post ')}") #?test_slugify2124125# Math utilities #?math_demo126print("\n--- MathUtils ---")127128print(f"5! = {MathUtils<class '__main__.MathUtils'>.factorial(5)}") #?test_factorialoutputSlugify ' My Blog Post ': my-blog-post --- MathUtils ---result ← 1
39@staticmethod #?factorial_decorator40def factorial(n5: int) -> int: #?factorial_def41 """Calculate factorial of n."""42 if n < 0: #?check_negative43 raise ValueError("Factorial not defined for negative numbers")44 result→ 1 = 1 #?init_result45 for i in range(2, n + 1): #?factorial_loopresult ← 2
pass 1 of 444result = 1 #?init_result45for i2 in range(2, n5 + 1): #?factorial_loop46 result→ 2 *= i247return result #?return_factorialAll 4 passes — pass 1 is the card above pass iresult1 2 1 → 2 2 3 2 → 6 3 4 6 → 24 4 5 24 → 120 return result #?return_factorial
46 result *= i47return result120 #?return_factorialprint(f"5! = {MathUtils.factorial(5)}") #?test_factorial
128print(f"5! = {MathUtils<class '__main__.MathUtils'>.factorial(5)}") #?test_factorial129130primes = [n for n in range(20) if MathUtils<class '__main__.MathUtils'>.is_prime(n)] #?find_primes131print(f"Primes under 20: {primes}") #?print_primesoutput5! = 120def is_prime(n: int) -> bool: #?is_prime_def
pass 1 of 2049@staticmethod #?is_prime_decorator50def is_prime(n0: int) -> bool: #?is_prime_def51 """Check if n is prime."""52 if n < 2: #?check_less_than_220 passes — pass 1 is the card above pass n1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 ⋯ 9 more passes ⋯ 19 18 20 19 if n < 2: #?check_less_than_2
pass 1 of 251"""Check if n is prime."""52if n0 < 2: #?check_less_than_253 return False54for i in range(2, int(n ** 0.5) + 1): #?prime_loopif n < 2: #?check_less_than_2
pass 2 of 251"""Check if n is prime."""52if n1 < 2: #?check_less_than_253 return False54for i in range(2, int(n ** 0.5) + 1): #?prime_loopfor i in range(2, int(n ** 0.5) + 1): #?prime_loop
pass 1 of 2453 return False54for i2 in range(2, int(n4 ** 0.5) + 1): #?prime_loop55 if n % i == 0: #?divisible_check56 return False24 passes — pass 1 is the card above pass in1 2 4 2 2 5 3 2 6 4 2 7 5 2 8 6 2 9 7 3 9 8 2 10 9 2 11 ⋯ 13 more passes ⋯ 23 3 19 24 4 19 if n % i == 0: #?divisible_check
pass 1 of 1054for i in range(2, int(n ** 0.5) + 1): #?prime_loop55 if n4 % i2 == 0: #?divisible_check56 return False57return True #?is_prime_returnAll 10 passes — pass 1 is the card above pass ni1 4 2 2 6 2 3 8 2 4 9 3 5 10 2 6 12 2 7 14 2 8 15 3 9 16 2 10 18 2 return True #?is_prime_return
56 return False57return True #?is_prime_returnreturn True #?is_prime_return
56 return False57return True #?is_prime_returnreturn True #?is_prime_return
56 return False57return True #?is_prime_returnreturn True #?is_prime_return
56 return False57return True #?is_prime_returnreturn True #?is_prime_return
56 return False57return True #?is_prime_returnreturn True #?is_prime_return
56 return False57return True #?is_prime_returnprimes ← [2, 3, 5, 7, 11, 13, 17, 19]
130primes→ [2, 3, 5, 7, 11, 13, 17, 19] = [n for n in range(20) if MathUtils<class '__main__.MathUtils'>.is_prime(n)] #?find_primes131print(f"Primes under 20: {primes[2, 3, 5, 7, 11, 13, 17, 19]}") #?print_primes132133print(f"GCD(48, 18) = {MathUtils<class '__main__.MathUtils'>.gcd(48, 18)}") #?test_gcdoutputPrimes under 20: [2, 3, 5, 7, 11, 13, 17, 19]def gcd(a: int, b: int) -> int: #?gcd_def
59@staticmethod #?gcd_decorator60def gcd(a48: int, b18: int) -> int: #?gcd_def61 """Calculate greatest common divisor."""62 while b: #?gcd_loopa ← 18, b ← 12
pass 1 of 361"""Calculate greatest common divisor."""62while b18: #?gcd_loop63 a→ 18, b→ 12 = b, a % b #?gcd_swap64return abs(a) #?return_gcdAll 3 passes — pass 1 is the card above pass ab1 48 → 18 18 → 12 2 18 → 12 12 → 6 3 12 → 6 6 → 0 return abs(a) #?return_gcd
63 a, b = b, a % b #?gcd_swap64return abs(a6) #?return_gcdprint(f"GCD(48, 18) = {MathUtils.gcd(48, 18)}") #?test_gcd
133print(f"GCD(48, 18) = {MathUtils<class '__main__.MathUtils'>.gcd(48, 18)}") #?test_gcd134135print(f"Clamp 15 to [0, 10]: {MathUtils<class '__main__.MathUtils'>.clamp(15, 0, 10)}") #?test_clamp1136print(f"Clamp -5 to [0, 10]: {MathUtils.clamp(-5, 0, 10)}") #?test_clamp2outputGCD(48, 18) = 6def clamp(value: float, min_val: float, max_val: float) -> float: #?c…
pass 1 of 366@staticmethod #?clamp_decorator67def clamp(value15: float, min_val0: float, max_val10: float) -> float: #?clamp_def68 """Clamp value between min and max."""69 return max(min_val0, min(max_val10, value15)) #?clamp_returnAll 3 passes — pass 1 is the card above pass value1 15 2 -5 3 5 print(f"Clamp 15 to [0, 10]: {MathUtils.clamp(15, 0, 10)}") #?test_cl…
135print(f"Clamp 15 to [0, 10]: {MathUtils<class '__main__.MathUtils'>.clamp(15, 0, 10)}") #?test_clamp1136print(f"Clamp -5 to [0, 10]: {MathUtils<class '__main__.MathUtils'>.clamp(-5, 0, 10)}") #?test_clamp2137print(f"Clamp 5 to [0, 10]: {MathUtils.clamp(5, 0, 10)}") #?test_clamp3outputClamp 15 to [0, 10]: 10print(f"Clamp -5 to [0, 10]: {MathUtils.clamp(-5, 0, 10)}") #?test_cl…
135print(f"Clamp 15 to [0, 10]: {MathUtils.clamp(15, 0, 10)}") #?test_clamp1136print(f"Clamp -5 to [0, 10]: {MathUtils<class '__main__.MathUtils'>.clamp(-5, 0, 10)}") #?test_clamp2137print(f"Clamp 5 to [0, 10]: {MathUtils<class '__main__.MathUtils'>.clamp(5, 0, 10)}") #?test_clamp3outputClamp -5 to [0, 10]: 0usernames ← ['alice', 'ab', 'user_123', '1invalid', 'valid_user_name_here_now']
136print(f"Clamp -5 to [0, 10]: {MathUtils.clamp(-5, 0, 10)}") #?test_clamp2137print(f"Clamp 5 to [0, 10]: {MathUtils<class '__main__.MathUtils'>.clamp(5, 0, 10)}") #?test_clamp3138139# Validation utilities #?validation_demo140print("\n--- Validator ---")141142usernames→ ['alice', 'ab', 'user_123', '1invalid', 'valid_user_name_here_now'] = ["alice", "ab", "user_123", "1invalid", "valid_user_name_here_now"] #?test_usernames143for username in usernames: #?username_loopoutputClamp 5 to [0, 10]: 5 --- Validator ---for username in usernames: #?username_loop
pass 1 of 5142usernames = ["alice", "ab", "user_123", "1invalid", "valid_user_name_here_now"] #?test_usernames143for usernamealice in usernames['alice', 'ab', 'user_123', '1invalid', 'valid_user_name_here_now']: #?username_loop144 valid, message = Validator<class '__main__.Validator'>.is_valid_username(usernamealice) #?validate_username145 status = "✓" if valid else "✗" #?status_symbolAll 5 passes — pass 1 is the card above pass usernameusername[0]1 alice — 2 ab — 3 user_123 — 4 1invalid 1 5 valid_user_name_here_now — def is_valid_username(username: str) -> tuple[bool, str]: #?is_valid_…
pass 1 of 575@staticmethod #?is_valid_username_decorator76def is_valid_username(usernamealice: str) -> tuple[bool, str]: #?is_valid_username_def77 """Validate username, return (valid, message)."""78 if len(username) < 3: #?check_min_length79 return False, "Username must be at least 3 characters"80 if len(username) > 20: #?check_max_length81 return False, "Username must be at most 20 characters"82 if not username[0].isalpha(): #?check_first_char83 return False, "Username must start with a letter"84 if not re.match(r"^[a-zA-Z0-9_]+$", username): #?check_valid_chars85 return False, "Username can only contain letters, numbers, and underscores"86 return True, "Valid username" #?valid_usernameAll 5 passes — pass 1 is the card above pass usernameusername[0]1 alice — 2 ab — 3 user_123 — 4 1invalid 1 5 valid_user_name_here_now — valid ← True, message ← Valid username, status ← ✓
143for username in usernames: #?username_loop144 valid→ True, message→ Valid username = Validator<class '__main__.Validator'>.is_valid_username(usernamealice) #?validate_username145 status→ ✓ = "✓" if validTrue else "✗" #?status_symbol146 print(f" {status✓} '{usernamealice}': {messageValid username}") #?print_username_resultoutput ✓ 'alice': Valid usernameif len(username) < 3: #?check_min_length
77"""Validate username, return (valid, message)."""78if len(usernameab) < 3: #?check_min_length79 return False, "Username must be at least 3 characters"80if len(username) > 20: #?check_max_lengthvalid ← False, message ← Username must be at least 3 characters
143for username in usernames: #?username_loop144 valid→ False, message→ Username must be at least 3 characters = Validator<class '__main__.Validator'>.is_valid_username(usernameab) #?validate_username145 status→ ✗ = "✓" if validFalse else "✗" #?status_symbol146 print(f" {status✗} '{usernameab}': {messageUsername must be at least 3 characters}") #?print_username_resultoutput ✗ 'ab': Username must be at least 3 charactersvalid ← True, message ← Valid username, status ← ✓
143for username in usernames: #?username_loop144 valid→ True, message→ Valid username = Validator<class '__main__.Validator'>.is_valid_username(usernameuser_123) #?validate_username145 status→ ✓ = "✓" if validTrue else "✗" #?status_symbol146 print(f" {status✓} '{usernameuser_123}': {messageValid username}") #?print_username_resultoutput ✓ 'user_123': Valid usernameif not username[0].isalpha(): #?check_first_char
81 return False, "Username must be at most 20 characters"82if not username[0]1.isalpha(): #?check_first_char83 return False, "Username must start with a letter"84if not re.match(r"^[a-zA-Z0-9_]+$", username): #?check_valid_charsvalid ← False, message ← Username must start with a letter, status ← ✗
143for username in usernames: #?username_loop144 valid→ False, message→ Username must start with a letter = Validator<class '__main__.Validator'>.is_valid_username(username1invalid) #?validate_username145 status→ ✗ = "✓" if validFalse else "✗" #?status_symbol146 print(f" {status✗} '{username1invalid}': {messageUsername must start with a letter}") #?print_username_resultoutput ✗ '1invalid': Username must start with a letterif len(username) > 20: #?check_max_length
79 return False, "Username must be at least 3 characters"80if len(usernamevalid_user_name_here_now) > 20: #?check_max_length81 return False, "Username must be at most 20 characters"82if not username[0].isalpha(): #?check_first_charvalid ← False, message ← Username must be at most 20 characters
143for username in usernames: #?username_loop144 valid→ False, message→ Username must be at most 20 characters = Validator<class '__main__.Validator'>.is_valid_username(usernamevalid_user_name_here_now) #?validate_username145 status→ ✗ = "✓" if validFalse else "✗" #?status_symbol146 print(f" {status✗} '{usernamevalid_user_name_here_now}': {messageUsername must be at most 20 characters}") #?print_username_resultoutput ✗ 'valid_user_name_here_now': Username must be at most 20 characterspasswords ← ['weak', 'Better123', 'Strong@Pass1']
148print("\nPassword strength:") #?password_header149passwords→ ['weak', 'Better123', 'Strong@Pass1'] = ["weak", "Better123", "Strong@Pass1"] #?test_passwords150for password in passwords: #?password_loopoutput Password strength:for password in passwords: #?password_loop
pass 1 of 3149passwords = ["weak", "Better123", "Strong@Pass1"] #?test_passwords150for passwordweak in passwords['weak', 'Better123', 'Strong@Pass1']: #?password_loop151 strong, issues = Validator<class '__main__.Validator'>.is_strong_password(passwordweak) #?validate_password152 if strong: #?check_strongAll 3 passes — pass 1 is the card above pass passwordreissues1 weak <module 're' from '/usr/local/lib/python3.12/re/__init__.py'> [] → ['Must be at least 8 characters'] 2 Better123 <module 're' from '/usr/local/lib/python3.12/re/__init__.py'> [] → ['Must contain special character (!@#$%^&*)'] 3 Strong@Pass1 — — issues ← []
pass 1 of 388@staticmethod #?is_strong_password_decorator89def is_strong_password(passwordweak: str) -> tuple[bool, List[str]]: #?is_strong_password_def90 """Check password strength, return (strong, issues)."""91 issues→ [] = [] #?init_issuesAll 3 passes — pass 1 is the card above pass passwordreissues1 weak <module 're' from '/usr/local/lib/python3.12/re/__init__.py'> [] 2 Better123 <module 're' from '/usr/local/lib/python3.12/re/__init__.py'> [] 3 Strong@Pass1 — [] issues ← ['Must be at least 8 characters']
93if len(passwordweak) < 8: #?pw_min_length94 issues→ ['Must be at least 8 characters'].append("Must be at least 8 characters")95if not re.search(r"[A-Z]", password): #?pw_uppercaseissues ← ['Must be at least 8 characters', 'Must contain uppercase letter']
94 issues.append("Must be at least 8 characters")95if not re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.search(r"[A-Z]", passwordweak): #?pw_uppercase96 issues→ ['Must be at least 8 characters', 'Must contain uppercase letter'].append("Must contain uppercase letter")97if not re.search(r"[a-z]", password): #?pw_lowercaseissues ← ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit']
98 issues.append("Must contain lowercase letter")99if not re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.search(r"\d", passwordweak): #?pw_digit100 issues→ ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit'].append("Must contain digit")101if not re.search(r"[!@#$%^&*]", password): #?pw_specialissues ← ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)']
pass 1 of 2100 issues.append("Must contain digit")101if not re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.search(r"[!@#$%^&*]", passwordweak): #?pw_special102 issues→ ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)'].append("Must contain special character (!@#$%^&*)")return len(issues) == 0, issues #?return_password_result
104return len(issues['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)']) == 0, issues #?return_password_resultstrong ← False, issues ← ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)']
150for password in passwords: #?password_loop151 strong→ False, issues→ ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)'] = Validator<class '__main__.Validator'>.is_strong_password(passwordweak) #?validate_password152 if strong: #?check_strong#?print_strong else:
pass 1 of 2152if strong: #?check_strong153 print(f" ✓ '{password}': Strong password") #?print_strong154else:155 print(f" ✗ '{passwordweak}': {', '.join(issues['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)'])}") #?print_weakoutput ✗ 'weak': Must be at least 8 characters, Must contain uppercase letter, Must contain digit, Must contain special character (!@#$%^&*)issues ← ['Must contain special character (!@#$%^&*)']
pass 2 of 2100 issues.append("Must contain digit")101if not re<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>.search(r"[!@#$%^&*]", passwordBetter123): #?pw_special102 issues→ ['Must contain special character (!@#$%^&*)'].append("Must contain special character (!@#$%^&*)")return len(issues) == 0, issues #?return_password_result
104return len(issues['Must contain special character (!@#$%^&*)']) == 0, issues #?return_password_resultstrong ← False, issues ← ['Must contain special character (!@#$%^&*)']
150for password in passwords: #?password_loop151 strong→ False, issues→ ['Must contain special character (!@#$%^&*)'] = Validator<class '__main__.Validator'>.is_strong_password(passwordBetter123) #?validate_password152 if strong: #?check_strong#?print_strong else:
pass 2 of 2152if strong: #?check_strong153 print(f" ✓ '{password}': Strong password") #?print_strong154else:155 print(f" ✗ '{passwordBetter123}': {', '.join(issues['Must contain special character (!@#$%^&*)'])}") #?print_weakoutput ✗ 'Better123': Must contain special character (!@#$%^&*)strong ← True, issues ← []
150for password in passwords: #?password_loop151 strong→ True, issues→ [] = Validator<class '__main__.Validator'>.is_strong_password(passwordStrong@Pass1) #?validate_password152 if strong: #?check_strongif strong: #?check_strong
151strong, issues = Validator.is_strong_password(password) #?validate_password152if strongTrue: #?check_strong153 print(f" ✓ '{passwordStrong@Pass1}': Strong password") #?print_strong154else:output ✓ 'Strong@Pass1': Strong passwordprint(" === Key Points ===")
157print("\n=== Key Points ===")158print("""159@staticmethod is good for:160• Utility functions that don't need self/cls161• Functions logically related to the class162• Validation helpers163• Math/string operations164• Pure functions (no side effects)165166Why use static instead of module function?167• Logical grouping (StringUtils.is_palindrome)168• Namespace organization169• Can be overridden in subclasses170""")output === Key Points === @staticmethod is good for: • Utility functions that don't need self/cls • Functions logically related to the class • Validation helpers • Math/string operations • Pure functions (no side effects) Why use static instead of module function? • Logical grouping (StringUtils.is_palindrome) • Namespace organization • Can be overridden in subclassesmain()
173if __name__ == "__main__":174 main()
Related utilities grouped in class namespace. Called on class, not instance.
Inheritance behavior
How these methods behave in subclasses.
# How @classmethod and @staticmethod Behave with Inheritance
class Animal:
"""Base class demonstrating method types with inheritance."""
species_count = 0
def __init__(self, name: str):
self.name = name
Animal.species_count += 1
# Regular method - uses self, instance-specific
def speak(self) -> str:
return f"{self.name} makes a sound"
# Class method - uses cls, works with inheritance
@classmethod
def create(cls, name: str):
"""Factory that works with subclasses."""
print(f"Creating {cls.__name__}")
return cls(name)
@classmethod
def describe_class(cls) -> str:
"""Describe the class - works correctly for subclasses."""
return f"Class: {cls.__name__}"
# Static method - fixed behavior, no cls
@staticmethod
def validate_name(name: str) -> bool:
"""Validate name - same for all classes."""
return len(name) >= 2 and name[0].isupper()
class Dog(Animal):
"""Dog subclass - inherits all method types."""
def speak(self) -> str:
return f"{self.name} says Woof!"
# Override static method - optional
@staticmethod
def validate_name(name: str) -> bool:
"""Dogs can have lowercase names."""
return len(name) >= 2
class Cat(Animal):
"""Cat subclass - demonstrates cls behavior."""
def speak(self) -> str:
return f"{self.name} says Meow!"
# Add Cat-specific class method
@classmethod
def create_kitten(cls, name: str):
"""Cat-specific factory method."""
return cls(f"Little {name}")
class WorkingDog(Dog):
"""Third level inheritance."""
def __init__(self, name: str, job: str):
super().__init__(name)
self.job = job
def speak(self) -> str:
return f"{self.name} the {self.job} dog says Woof!"
# Override class method
@classmethod
def create(cls, name: str, job: str = "guard"):
"""Extended factory with job parameter."""
print(f"Creating {cls.__name__} with job: {job}")
return cls(name, job)
def main():
print("=== Inheritance Behavior ===\n")
# Class method with inheritance
print("--- @classmethod with Inheritance ---")
# cls is the actual class being called on
animal = Animal.create("Generic")
dog = Dog.create("Rex")
cat = Cat.create("Whiskers")
print(f"animal type: {type(animal).__name__}")
print(f"dog type: {type(dog).__name__}")
print(f"cat type: {type(cat).__name__}")
# describe_class shows actual class
print("\n--- describe_class (cls aware) ---")
print(Animal.describe_class())
print(Dog.describe_class())
print(Cat.describe_class())
# Static method inheritance
print("\n--- @staticmethod with Inheritance ---")
# Inherited unchanged (Animal's version)
print(f"Animal.validate_name('Rex'): {Animal.validate_name('Rex')}")
print(f"Cat.validate_name('Rex'): {Cat.validate_name('Rex')}")
# Overridden (Dog has its own version)
print(f"Animal.validate_name('rex'): {Animal.validate_name('rex')}")
print(f"Dog.validate_name('rex'): {Dog.validate_name('rex')}")
# Regular method - instance specific
print("\n--- Regular Method with Inheritance ---")
print(f"animal.speak(): {animal.speak()}")
print(f"dog.speak(): {dog.speak()}")
print(f"cat.speak(): {cat.speak()}")
# Multi-level inheritance
print("\n--- Multi-level Inheritance ---")
working_dog = WorkingDog.create("Max", "police")
print(f"working_dog type: {type(working_dog).__name__}")
print(f"working_dog.speak(): {working_dog.speak()}")
# Cat-specific method
print("\n--- Subclass-specific Methods ---")
kitten = Cat.create_kitten("Fluffy")
print(f"kitten.name: {kitten.name}")
print(f"kitten.speak(): {kitten.speak()}")
# Why cls matters
print("\n--- Why cls Matters ---")
print("""
@classmethod factory pattern:
# In Animal.create():
def create(cls, name):
return cls(name) # cls changes based on call
Animal.create("X") # cls = Animal, returns Animal
Dog.create("X") # cls = Dog, returns Dog
Cat.create("X") # cls = Cat, returns Cat
If we used Animal(name) instead of cls(name),
Dog.create() would return Animal, not Dog!
""")
print("=== Key Points ===")
print("""
@classmethod:
• cls changes based on which class calls it
• Subclasses automatically get correct behavior
• Use for factory methods, alternative constructors
@staticmethod:
• Inherited but can be overridden
• Same behavior regardless of class (unless overridden)
• Use for utility functions
Regular methods:
• Override in subclasses for polymorphism
• self is always the instance
""")
if __name__ == "__main__":
main()
species_count ← (empty)
3class Animal:4 """Base class demonstrating method types with inheritance."""56 species_count→ (empty) = 0 #?species_count78 def __init__(self, name: str): #?animal_init9 self.name = name10 Animal.species_count += 11112 # Regular method - uses self, instance-specific #?regular_comment13 def speak(self) -> str: #?speak_def14 return f"{self.name} makes a sound" #?speak_body1516 # Class method - uses cls, works with inheritance #?classmethod_comment17 @classmethod #?create_decorator18 def create(cls, name: str): #?create_def19 """Factory that works with subclasses."""20 print(f"Creating {cls.__name__}") #?print_cls_name21 return cls(name) #?return_cls_instance2223 @classmethod #?describe_class_decorator24 def describe_class(cls) -> str: #?describe_class_def25 """Describe the class - works correctly for subclasses."""26 return f"Class: {cls.__name__}" #?describe_class_body2728 # Static method - fixed behavior, no cls #?staticmethod_comment29 @staticmethod #?validate_name_decorator30 def validate_name(name: str) -> bool: #?validate_name_def31 """Validate name - same for all classes."""32 return len(name) >= 2 and name[0].isupper() #?validate_name_body333435class Dog(Animal):36 """Dog subclass - inherits all method types."""3738 def speak(self) -> str: #?dog_speak39 return f"{self.name} says Woof!" #?dog_speak_body4041 # Override static method - optional #?override_static_comment42 @staticmethod #?dog_validate_decorator43 def validate_name(name: str) -> bool: #?dog_validate_def44 """Dogs can have lowercase names."""45 return len(name) >= 2 #?dog_validate_body464748class Cat(Animal):49 """Cat subclass - demonstrates cls behavior."""5051 def speak(self) -> str: #?cat_speak52 return f"{self.name} says Meow!" #?cat_speak_body5354 # Add Cat-specific class method #?cat_classmethod_comment55 @classmethod #?create_kitten_decorator56 def create_kitten(cls, name: str): #?create_kitten_def57 """Cat-specific factory method."""58 return cls(f"Little {name}") #?create_kitten_body596061class WorkingDog(Dog):62 """Third level inheritance."""def main():
79def main():80 print("=== Inheritance Behavior ===\n")8182 # Class method with inheritance #?classmethod_inheritance83 print("--- @classmethod with Inheritance ---")8485 # cls is the actual class being called on #?cls_demo86 animal = Animal<class '__main__.Animal'>.create("Generic") #?create_animal87 dog = Dog.create("Rex") #?create_dogoutput=== Inheritance Behavior === --- @classmethod with Inheritance ---def create(cls, name: str): #?create_def
pass 1 of 317@classmethod #?create_decorator18def create(cls<class '__main__.Animal'>, nameGeneric: str): #?create_def19 """Factory that works with subclasses."""20 print(f"Creating {cls.__name__Animal}") #?print_cls_name21 return cls(nameGeneric) #?return_cls_instanceoutputCreating AnimalAll 3 passes — pass 1 is the card above pass clsnamecls.__name__1 <class '__main__.Animal'> Generic Animal 2 <class '__main__.Dog'> Rex Dog 3 <class '__main__.Cat'> Whiskers Cat self.name ← Generic, Animal.species_count ← 1
pass 1 of 58def __init__(self⟨Animal A⟩, nameGeneric: str): #?animal_init9 self.name→ Generic = nameGeneric10 Animal.species_count→ 1 += 1All 5 passes — pass 1 is the card above pass selfnameself.nameAnimal.species_count1 ⟨Animal A⟩ Generic Generic 0 → 1 2 ⟨Dog B⟩ Rex Rex 1 → 2 3 ⟨Cat C⟩ Whiskers Whiskers 2 → 3 4 ⟨WorkingDog D⟩ Max Max 3 → 4 5 ⟨Cat E⟩ Little Fluffy Little Fluffy 4 → 5 animal ← ⟨Animal A⟩
85# cls is the actual class being called on #?cls_demo86animal→ ⟨Animal A⟩ = Animal<class '__main__.Animal'>.create("Generic") #?create_animal87dog = Dog<class '__main__.Dog'>.create("Rex") #?create_dog88cat = Cat.create("Whiskers") #?create_catdog ← ⟨Dog B⟩
86animal = Animal.create("Generic") #?create_animal87dog→ ⟨Dog B⟩ = Dog<class '__main__.Dog'>.create("Rex") #?create_dog88cat = Cat<class '__main__.Cat'>.create("Whiskers") #?create_catcat ← ⟨Cat C⟩
87dog = Dog.create("Rex") #?create_dog88cat→ ⟨Cat C⟩ = Cat<class '__main__.Cat'>.create("Whiskers") #?create_cat8990print(f"animal type: {type(animal⟨Animal A⟩).__name__}") #?print_animal_type91print(f"dog type: {type(dog⟨Dog B⟩).__name__}") #?print_dog_type92print(f"cat type: {type(cat⟨Cat C⟩).__name__}") #?print_cat_type9394# describe_class shows actual class #?describe_demo95print("\n--- describe_class (cls aware) ---")96print(Animal<class '__main__.Animal'>.describe_class()) #?describe_animal97print(Dog.describe_class()) #?describe_dogoutputanimal type: Animal dog type: Dog cat type: Cat --- describe_class (cls aware) ---def describe_class(cls) -> str: #?describe_class_def
pass 1 of 323@classmethod #?describe_class_decorator24def describe_class(cls<class '__main__.Animal'>) -> str: #?describe_class_def25 """Describe the class - works correctly for subclasses."""26 return f"Class: {cls.__name__Animal}" #?describe_class_bodyAll 3 passes — pass 1 is the card above pass clscls.__name__1 <class '__main__.Animal'> Animal 2 <class '__main__.Dog'> Dog 3 <class '__main__.Cat'> Cat print(Animal.describe_class()) #?describe_animal
95print("\n--- describe_class (cls aware) ---")96print(Animal<class '__main__.Animal'>.describe_class()) #?describe_animal97print(Dog<class '__main__.Dog'>.describe_class()) #?describe_dog98print(Cat.describe_class()) #?describe_catoutputClass: Animalprint(Dog.describe_class()) #?describe_dog
96print(Animal.describe_class()) #?describe_animal97print(Dog<class '__main__.Dog'>.describe_class()) #?describe_dog98print(Cat<class '__main__.Cat'>.describe_class()) #?describe_catoutputClass: Dogprint(Cat.describe_class()) #?describe_cat
97print(Dog.describe_class()) #?describe_dog98print(Cat<class '__main__.Cat'>.describe_class()) #?describe_cat99100# Static method inheritance #?staticmethod_inheritance101print("\n--- @staticmethod with Inheritance ---")102103# Inherited unchanged (Animal's version) #?static_inherited104print(f"Animal.validate_name('Rex'): {Animal<class '__main__.Animal'>.validate_name('Rex')}") #?validate_animal105print(f"Cat.validate_name('Rex'): {Cat.validate_name('Rex')}") #?validate_cat_inheritedoutputClass: Cat --- @staticmethod with Inheritance ---def validate_name(name: str) -> bool: #?validate_name_def
pass 1 of 329@staticmethod #?validate_name_decorator30def validate_name(nameRex: str) -> bool: #?validate_name_def31 """Validate name - same for all classes."""32 return len(nameRex) >= 2 and name[0]R.isupper() #?validate_name_bodyAll 3 passes — pass 1 is the card above pass namename[0]1 Rex R 2 Rex R 3 rex r print(f"Animal.validate_name('Rex'): {Animal.validate_name('Rex')}") …
103# Inherited unchanged (Animal's version) #?static_inherited104print(f"Animal.validate_name('Rex'): {Animal<class '__main__.Animal'>.validate_name('Rex')}") #?validate_animal105print(f"Cat.validate_name('Rex'): {Cat<class '__main__.Cat'>.validate_name('Rex')}") #?validate_cat_inheritedoutputAnimal.validate_name('Rex'): Trueprint(f"Cat.validate_name('Rex'): {Cat.validate_name('Rex')}") #?vali…
104print(f"Animal.validate_name('Rex'): {Animal.validate_name('Rex')}") #?validate_animal105print(f"Cat.validate_name('Rex'): {Cat<class '__main__.Cat'>.validate_name('Rex')}") #?validate_cat_inherited106107# Overridden (Dog has its own version) #?static_overridden108print(f"Animal.validate_name('rex'): {Animal<class '__main__.Animal'>.validate_name('rex')}") #?validate_lowercase_animal109print(f"Dog.validate_name('rex'): {Dog.validate_name('rex')}") #?validate_lowercase_dogoutputCat.validate_name('Rex'): Trueprint(f"Animal.validate_name('rex'): {Animal.validate_name('rex')}") …
107# Overridden (Dog has its own version) #?static_overridden108print(f"Animal.validate_name('rex'): {Animal<class '__main__.Animal'>.validate_name('rex')}") #?validate_lowercase_animal109print(f"Dog.validate_name('rex'): {Dog<class '__main__.Dog'>.validate_name('rex')}") #?validate_lowercase_dogoutputAnimal.validate_name('rex'): Falsedef validate_name(name: str) -> bool: #?dog_validate_def
42@staticmethod #?dog_validate_decorator43def validate_name(namerex: str) -> bool: #?dog_validate_def44 """Dogs can have lowercase names."""45 return len(namerex) >= 2 #?dog_validate_bodyprint(f"Dog.validate_name('rex'): {Dog.validate_name('rex')}") #?vali…
108print(f"Animal.validate_name('rex'): {Animal.validate_name('rex')}") #?validate_lowercase_animal109print(f"Dog.validate_name('rex'): {Dog<class '__main__.Dog'>.validate_name('rex')}") #?validate_lowercase_dog110111# Regular method - instance specific #?regular_inheritance112print("\n--- Regular Method with Inheritance ---")113print(f"animal.speak(): {animal⟨Animal A⟩.speak()}") #?speak_animal114print(f"dog.speak(): {dog.speak()}") #?speak_dogoutputDog.validate_name('rex'): True --- Regular Method with Inheritance ---def speak(self) -> str: #?speak_def
12# Regular method - uses self, instance-specific #?regular_comment13def speak(self⟨Animal A⟩) -> str: #?speak_def14 return f"{self.nameGeneric} makes a sound" #?speak_bodyprint(f"animal.speak(): {animal.speak()}") #?speak_animal
112print("\n--- Regular Method with Inheritance ---")113print(f"animal.speak(): {animal⟨Animal A⟩.speak()}") #?speak_animal114print(f"dog.speak(): {dog⟨Dog B⟩.speak()}") #?speak_dog115print(f"cat.speak(): {cat.speak()}") #?speak_catoutputanimal.speak(): Generic makes a sounddef speak(self) -> str: #?dog_speak
38def speak(self⟨Dog B⟩) -> str: #?dog_speak39 return f"{self.nameRex} says Woof!" #?dog_speak_bodyprint(f"dog.speak(): {dog.speak()}") #?speak_dog
113print(f"animal.speak(): {animal.speak()}") #?speak_animal114print(f"dog.speak(): {dog⟨Dog B⟩.speak()}") #?speak_dog115print(f"cat.speak(): {cat⟨Cat C⟩.speak()}") #?speak_catoutputdog.speak(): Rex says Woof!def speak(self) -> str: #?cat_speak
pass 1 of 251def speak(self⟨Cat C⟩) -> str: #?cat_speak52 return f"{self.nameWhiskers} says Meow!" #?cat_speak_bodyprint(f"cat.speak(): {cat.speak()}") #?speak_cat
114print(f"dog.speak(): {dog.speak()}") #?speak_dog115print(f"cat.speak(): {cat⟨Cat C⟩.speak()}") #?speak_cat116117# Multi-level inheritance #?multilevel118print("\n--- Multi-level Inheritance ---")119working_dog = WorkingDog<class '__main__.WorkingDog'>.create("Max", "police") #?create_working120print(f"working_dog type: {type(working_dog).__name__}") #?print_working_typeoutputcat.speak(): Whiskers says Meow! --- Multi-level Inheritance ---def create(cls, name: str, job: str = "guard"): #?working_create_def
72@classmethod #?working_create_decorator73def create(cls<class '__main__.WorkingDog'>, nameMax: str, jobpolice: str = "guard"): #?working_create_def74 """Extended factory with job parameter."""75 print(f"Creating {cls.__name__WorkingDog} with job: {jobpolice}") #?working_print76 return cls(nameMax, jobpolice) #?working_returnoutputCreating WorkingDog with job: policedef __init__(self, name: str, job: str): #?working_dog_init
64def __init__(self⟨WorkingDog D⟩, nameMax: str, jobpolice: str): #?working_dog_init65 super().__init__(name)66 self.job = jobself.job ← police
65super().__init__(name)66self.job→ police = jobpoliceworking_dog ← ⟨WorkingDog D⟩
118print("\n--- Multi-level Inheritance ---")119working_dog→ ⟨WorkingDog D⟩ = WorkingDog<class '__main__.WorkingDog'>.create("Max", "police") #?create_working120print(f"working_dog type: {type(working_dog⟨WorkingDog D⟩).__name__}") #?print_working_type121print(f"working_dog.speak(): {working_dog⟨WorkingDog D⟩.speak()}") #?speak_workingoutputworking_dog type: WorkingDogdef speak(self) -> str: #?working_dog_speak
68def speak(self⟨WorkingDog D⟩) -> str: #?working_dog_speak69 return f"{self.nameMax} the {self.jobpolice} dog says Woof!" #?working_dog_speak_bodyprint(f"working_dog.speak(): {working_dog.speak()}") #?speak_working
120print(f"working_dog type: {type(working_dog).__name__}") #?print_working_type121print(f"working_dog.speak(): {working_dog⟨WorkingDog D⟩.speak()}") #?speak_working122123# Cat-specific method #?cat_specific124print("\n--- Subclass-specific Methods ---")125kitten = Cat<class '__main__.Cat'>.create_kitten("Fluffy") #?create_kitten126print(f"kitten.name: {kitten.name}") #?print_kitten_nameoutputworking_dog.speak(): Max the police dog says Woof! --- Subclass-specific Methods ---def create_kitten(cls, name: str): #?create_kitten_def
55@classmethod #?create_kitten_decorator56def create_kitten(cls<class '__main__.Cat'>, nameFluffy: str): #?create_kitten_def57 """Cat-specific factory method."""58 return cls(f"Little {nameFluffy}") #?create_kitten_bodykitten ← ⟨Cat E⟩
124print("\n--- Subclass-specific Methods ---")125kitten→ ⟨Cat E⟩ = Cat<class '__main__.Cat'>.create_kitten("Fluffy") #?create_kitten126print(f"kitten.name: {kitten.nameLittle Fluffy}") #?print_kitten_name127print(f"kitten.speak(): {kitten⟨Cat E⟩.speak()}") #?speak_kittenoutputkitten.name: Little Fluffydef speak(self) -> str: #?cat_speak
pass 2 of 251def speak(self⟨Cat E⟩) -> str: #?cat_speak52 return f"{self.nameLittle Fluffy} says Meow!" #?cat_speak_bodyprint(f"kitten.speak(): {kitten.speak()}") #?speak_kitten
126print(f"kitten.name: {kitten.name}") #?print_kitten_name127print(f"kitten.speak(): {kitten⟨Cat E⟩.speak()}") #?speak_kitten128129# Why cls matters #?why_cls130print("\n--- Why cls Matters ---")131print("""132@classmethod factory pattern:133134# In Animal.create():135def create(cls, name):136 return cls(name) # cls changes based on call137138Animal.create("X") # cls = Animal, returns Animal139Dog.create("X") # cls = Dog, returns Dog140Cat.create("X") # cls = Cat, returns Cat141142If we used Animal(name) instead of cls(name),143Dog.create() would return Animal, not Dog!144""")145146print("=== Key Points ===")147print("""148@classmethod:149• cls changes based on which class calls it150• Subclasses automatically get correct behavior151• Use for factory methods, alternative constructors152153@staticmethod:154• Inherited but can be overridden155• Same behavior regardless of class (unless overridden)156• Use for utility functions157158Regular methods:159• Override in subclasses for polymorphism160• self is always the instance161""")outputkitten.speak(): Little Fluffy says Meow! --- Why cls Matters --- @classmethod factory pattern: # In Animal.create(): def create(cls, name): return cls(name) # cls changes based on call Animal.create("X") # cls = Animal, returns Animal Dog.create("X") # cls = Dog, returns Dog Cat.create("X") # cls = Cat, returns Cat If we used Animal(name) instead of cls(name), Dog.create() would return Animal, not Dog! === Key Points === @classmethod: • cls changes based on which class calls it • Subclasses automatically get correct behavior • Use for factory methods, alternative constructors @staticmethod: • Inherited but can be overridden • Same behavior regardless of class (unless overridden) • Use for utility functions Regular methods: • Override in subclasses for polymorphism • self is always the instancemain()
164if __name__ == "__main__":165 main()
@classmethod: cls is the actual subclass. @staticmethod: same function.
Exercise: practical.py
Build a data model with factory methods and utilities