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.

basics.py
Replay: real traced execution (multi-file project)
# 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()



































  1. count ← (empty)

    3class Counter:4    """Demonstrates all three method types."""56    count→ (empty) = 0  # Class attribute - shared by all instances
  2. def 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 class
    output=== Three Method Types ===
    --- Static Method (no instance needed) ---
  3. def describe(): #?describe_def

    pass 1 of 2
    24@staticmethod  #?staticmethod_decorator25def describe():  #?describe_def26    print("Counter tracks how many instances exist")  #?describe_body
    outputCounter tracks how many instances exist
  4. Counter.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 instances
    output
    --- Class Method (before any instances) ---
  5. def get_count(cls): #?get_count_def

    pass 1 of 3
    17@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_count
    outputClass: Counter
    Total instances: 0
    All 3 passes — pass 1 is the card above
    passcls.count
    10
    23
    33
  6. 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_c2
    output
    --- Creating Instances ---
  7. self.name ← first, Counter.count ← 1

    pass 1 of 3
    8def __init__(self⟨Counter A⟩, namefirst: str):  #?init9    self.name→ first = namefirst  # Instance attribute10    Counter.count→ 1 += 1  #?increment
    All 3 passes — pass 1 is the card above
    passselfnameself.nameCounter.count
    1⟨Counter A⟩firstfirst0 1
    2⟨Counter B⟩secondsecond1 2
    3⟨Counter C⟩thirdthird2 3
  8. c1 ← ⟨Counter A⟩

    41print("\n--- Creating Instances ---")42c1→ ⟨Counter A⟩ = Counter("first")  #?create_c143c2 = Counter("second")  #?create_c244c3 = Counter("third")  #?create_c3
  9. c2 ← ⟨Counter B⟩

    42c1 = Counter("first")  #?create_c143c2→ ⟨Counter B⟩ = Counter("second")  #?create_c244c3 = Counter("third")  #?create_c3
  10. c3 ← ⟨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_c2
    output
    --- Regular Method (needs instance) ---
  11. def display(self): #?display_def

    pass 1 of 2
    12# Regular method - receives self (instance) #?regular_method13def display(self⟨Counter A⟩):  #?display_def14    print(f"Instance '{self.namefirst}' (total count: {Counter.count3})")  #?display_body
    outputInstance 'first' (total count: 3)
  12. c1.display() # Instance method

    47print("\n--- Regular Method (needs instance) ---")48c1⟨Counter A⟩.display()  # Instance method49c2⟨Counter B⟩.display()  #?call_display_c2
  13. def display(self): #?display_def

    pass 2 of 2
    12# Regular method - receives self (instance) #?regular_method13def display(self⟨Counter B⟩):  #?display_def14    print(f"Instance '{self.namesecond}' (total count: {Counter.count3})")  #?display_body
    outputInstance 'second' (total count: 3)
  14. 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 instances
    output
    --- Class Method (after instances) ---
  15. 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 class
    output
    --- Class Method Called on Instance ---
  16. 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 common
    output
    --- Static Method Called on Instance ---
  17. def describe(): #?describe_def

    pass 2 of 2
    24@staticmethod  #?staticmethod_decorator25def describe():  #?describe_def26    print("Counter tracks how many instances exist")  #?describe_body
    outputCounter tracks how many instances exist
  18. c1.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()
        
  19. main()

    82if __name__ == "__main__":83    main()

Regular: self. Classmethod: cls. Staticmethod: neither.

classmethod Receives class as first argument: `@classmethod def method(cls):`.
staticmethod No self or cls: `@staticmethod def method():`. Just a function in the class.

Factory methods with @classmethod

Alternative constructors that return instances.

example
classmethod_factory.py
Replay: real traced execution (multi-file project)
# 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()




























































  1. """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."""
  2. 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_p1
    output=== Factory Methods with @classmethod ===
    --- Standard Constructor ---
  3. self.name ← Laptop, self.price ← 999.99, self.category ← electronics

    pass 1 of 6
    6def __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_category
    All 6 passes — pass 1 is the card above
    passnamepricecategoryself.nameself.priceself.category
    1Laptop999.99electronicsLaptop999.99electronics
    2Mouse29.99electronicsMouse29.99electronics
    3Keyboard79.99electronicsKeyboard79.99electronics
    4Sticker2.99generalSticker2.99general
    5E-book14.99digitalE-book14.99digital
    6T-shirt24.99physicalT-shirt24.99physical
  4. 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_p2
    outputStandard: Product('Laptop', $999.99, electronics)
    
    --- Factory: from_dict ---
  5. 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    )
  6. 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 ---
  7. parts ← ['Keyboard', '79.99', 'electronics'], name ← Keyboard

    pass 1 of 2
    25@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_return
  8. 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")  #?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_p4
    outputFrom string: Product('Keyboard', $79.99, electronics)
  9. parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general

    pass 2 of 2
    25@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_return
  10. p4 ← 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_physical
    outputFrom string (default category): Product('Sticker', $2.99, general)
    
    --- Factory: Preset Categories ---
  11. 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_return
  12. p5 ← 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_p5
  13. def 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_return
  14. p6 ← 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_guest
    outputDigital: Product('E-book', $14.99, digital)
    Physical: Product('T-shirt', $24.99, physical)
    
    --- User Factory Methods ---
  15. 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_return
  16. self.username ← admin, self.email ← admin@example.com, self.role ← admin

    pass 1 of 3
    49def __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_activeTrue
    All 3 passes — pass 1 is the card above
    passusernameemailroleis_activeself.usernameself.emailself.roleself.is_active
    1adminadmin@example.comadminTrueadminadmin@example.comadminTrue
    2guestguest@example.comguestFalseguestguest@example.comguestFalse
    3johnjohn@example.comuserTruejohnjohn@example.comuserTrue
  17. 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_guest
  18. def 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_return
  19. guest ← 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_dict
  20. def 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 args
  21. regular ← 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/validation
        
  22. main()

    129if __name__ == "__main__":130    main()
  1. """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."""
  2. 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 ---
  3. self.name ← Laptop, self.price ← 999.99, self.category ← electronics

    pass 1 of 6
    6def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str):7    self.name→ Laptop = nameLaptop8    self.price→ 999.99 = price999.999    self.category→ electronics = categoryelectronics
    All 6 passes — pass 1 is the card above
    passnamepricecategoryself.nameself.priceself.category
    1Laptop999.99electronicsLaptop999.99electronics
    2Mouse29.99electronicsMouse29.99electronics
    3Cable9.99accessoriesCable9.99accessories
    4Sticker2.99generalSticker2.99general
    5E-book14.99digitalE-book14.99digital
    6T-shirt24.99physicalT-shirt24.99physical
  4. 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 ---
  5. 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    )
  6. 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 ---
  7. parts ← ['Cable', '9.99', 'accessories'], name ← Cable, price ← 9.99

    pass 1 of 2
    25@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)
  8. 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)
  9. parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general

    pass 2 of 2
    25@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)
  10. 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 ---
  11. 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")
  12. 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}")
  13. 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")
  14. 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 ---
  15. 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")
  16. self.username ← admin, self.email ← admin@example.com, self.role ← admin

    pass 1 of 3
    49def __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_activeTrue
    All 3 passes — pass 1 is the card above
    passusernameemailroleis_activeself.usernameself.emailself.roleself.is_active
    1adminadmin@example.comadminTrueadminadmin@example.comadminTrue
    2guestguest@example.comguestFalseguestguest@example.comguestFalse
    3johnjohn@example.comuserTruejohnjohn@example.comuserTrue
  17. 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()
  18. 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)
  19. 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'})
  20. 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 args
  21. regular ← 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/validation
        
  22. main()

    127if __name__ == "__main__":128    main()
  1. """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."""
  2. 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 ---
  3. self.name ← Laptop, self.price ← 999.99, self.category ← electronics

    pass 1 of 6
    6def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str):7    self.name→ Laptop = nameLaptop8    self.price→ 999.99 = price999.999    self.category→ electronics = categoryelectronics
    All 6 passes — pass 1 is the card above
    passnamepricecategoryself.nameself.priceself.category
    1Laptop999.99electronicsLaptop999.99electronics
    2Mouse29.99electronicsMouse29.99electronics
    3Sticker2.99generalSticker2.99general
    4Sticker2.99generalSticker2.99general
    5E-book14.99digitalE-book14.99digital
    6T-shirt24.99physicalT-shirt24.99physical
  4. 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 ---
  5. 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    )
  6. 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 ---
  7. parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general

    pass 1 of 2
    25@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)
  8. 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)
  9. parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general

    pass 2 of 2
    25@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)
  10. 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 ---
  11. 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")
  12. 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}")
  13. 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")
  14. 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 ---
  15. 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")
  16. self.username ← admin, self.email ← admin@example.com, self.role ← admin

    pass 1 of 3
    49def __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_activeTrue
    All 3 passes — pass 1 is the card above
    passusernameemailroleis_activeself.usernameself.emailself.roleself.is_active
    1adminadmin@example.comadminTrueadminadmin@example.comadminTrue
    2guestguest@example.comguestFalseguestguest@example.comguestFalse
    3johnjohn@example.comuserTruejohnjohn@example.comuserTrue
  17. 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()
  18. 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)
  19. 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'})
  20. 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 args
  21. regular ← 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/validation
        
  22. main()

    127if __name__ == "__main__":128    main()
  1. """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."""
  2. 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 ---
  3. self.name ← Laptop, self.price ← 999.99, self.category ← electronics

    pass 1 of 6
    6def __init__(self(empty), nameLaptop: str, price999.99: float, categoryelectronics: str):7    self.name→ Laptop = nameLaptop8    self.price→ 999.99 = price999.999    self.category→ electronics = categoryelectronics
    All 6 passes — pass 1 is the card above
    passnamepricecategoryself.nameself.priceself.category
    1Laptop999.99electronicsLaptop999.99electronics
    2Mouse29.99electronicsMouse29.99electronics
    3Keyboard79.99electronicsKeyboard79.99electronics
    4Sticker2.99generalSticker2.99general
    5E-book14.99digitalE-book14.99digital
    6T-shirt24.99physicalT-shirt24.99physical
  4. 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 ---
  5. 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    )
  6. 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 ---
  7. parts ← ['Keyboard', '79.99', 'electronics'], name ← Keyboard

    pass 1 of 2
    25@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)
  8. 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)
  9. parts ← ['Sticker', '2.99'], name ← Sticker, price ← 2.99, category ← general

    pass 2 of 2
    25@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)
  10. 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 ---
  11. 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")
  12. 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}")
  13. 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")
  14. 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 ---
  15. 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")
  16. self.username ← admin, self.email ← admin@example.com, self.role ← admin

    pass 1 of 3
    49def __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_activeTrue
    All 3 passes — pass 1 is the card above
    passusernameemailroleis_activeself.usernameself.emailself.roleself.is_active
    1adminadmin@example.comadminTrueadminadmin@example.comadminTrue
    2guestguest@example.comguestFalseguestguest@example.comguestFalse
    3mayamaya@example.comeditorTruemayamaya@example.comeditorTrue
  17. 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()
  18. 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)
  19. 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'})
  20. 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 args
  21. regular ← 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/validation
        
  22. main()

    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.py
Replay: real traced execution (multi-file project)
# 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()

















































































  1. """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."""
  2. 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_d1
    output=== Alternative Constructors ===
    --- Date Constructors ---
  3. self.year ← 2025, self.month ← 1, self.day ← 15

    pass 1 of 5
    9def __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_day
    All 5 passes — pass 1 is the card above
    passmonthdayself.yearself.monthself.day
    11152025115
    26202025620
    3122520251225
    411202511
    51152025115
  4. 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_d2
    outputStandard: 2025-01-15
  5. parts ← ['2025', '06', '20'], year ← 2025, month ← 6, day ← 20

    pass 1 of 2
    21@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_string
  6. d2 ← 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_d3
    outputFrom string: 2025-06-20
  7. parts ← ['2025', '12', '25'], year ← 2025, month ← 12, day ← 25

    pass 2 of 2
    21@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_string
  8. d3 ← 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_d4
    outputFrom string (custom sep): 2025-12-25
  9. dt ← 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_timestamp
  10. d4 ← 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_d5
    outputFrom timestamp: 2025-01-01
  11. t ← 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_today
  12. d5 ← 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_p1
    outputToday: 2025-01-15
    
    --- Person Constructors ---
  13. self.first_name ← John, self.last_name ← Doe, self.birth_year ← 1990

    pass 1 of 3
    46def __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_year1990
    All 3 passes — pass 1 is the card above
    passfirst_namelast_namebirth_yearself.first_nameself.last_nameself.birth_year
    1JohnDoe1990JohnDoe1990
    2JaneSmith1985JaneSmith1985
    3BobJohnson1995BobJohnson1995
  14. 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_p1
  15. def full_name(self) -> str: #?full_name_def

    pass 1 of 3
    51@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
    passselfself.first_nameself.last_name
    1Person('John Doe', age=35)JohnDoe
    2Person('Jane Smith', age=40)JaneSmith
    3Person('Bob Johnson', age=30)BobJohnson
  16. def age(self) -> int: #?age_def

    pass 1 of 3
    55@property  #?age_property56def age(selfPerson('John Doe', age=35)) -> int:  #?age_def57    return 2025 - self.birth_year1990  #?calc_age
    All 3 passes — pass 1 is the card above
    passselfself.birth_year
    1Person('John Doe', age=35)1990
    2Person('Jane Smith', age=40)1985
    3Person('Bob Johnson', age=30)1995
  17. 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_p2
    outputStandard: Person('John Doe', age=35)
  18. 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_name
  19. p2 ← 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_p2
  20. print(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_p3
    outputFrom full name: Person('Jane Smith', age=40)
  21. 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_date
  22. p3 ← 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_p3
  23. print(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_r1
    outputFrom birth date: Person('Bob Johnson', age=30)
    
    --- Rectangle Constructors ---
  24. self.width ← 10, self.height ← 5

    pass 1 of 4
    81def __init__(self(empty), width10: float, height5: float):  #?rect_init82    self.width→ 10 = width1083    self.height→ 5 = height5
    All 4 passes — pass 1 is the card above
    passwidthheightself.widthself.height
    1105105
    27777
    314.1421356237309517.071067811865475514.1421356237309517.0710678118654755
    410.010.010.010.0
  25. r1 ← Rectangle(10x5, area=50)

    143r1→ Rectangle(10x5, area=50) = Rectangle(10, 5)  #?create_r1144print(f"Standard: {r1Rectangle(10x5, area=50)}")  #?print_r1
  26. def area(self) -> float: #?area_def

    pass 1 of 4
    85@property  #?area_property86def area(selfRectangle(10x5, area=50)) -> float:  #?area_def87    return self.width10 * self.height5
    All 4 passes — pass 1 is the card above
    passselfself.widthself.height
    1Rectangle(10x5, area=50)105
    2Rectangle(7x7, area=49)77
    3Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001)14.1421356237309517.0710678118654755
    4Rectangle(10.0x10.0, area=100.0)10.010.0
  27. 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_r2
    outputStandard: Rectangle(10x5, area=50)
  28. 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_square
  29. r2 ← Rectangle(7x7, area=49)

    146r2→ Rectangle(7x7, area=49) = Rectangle<class '__main__.Rectangle'>.square(7)  #?create_r2147print(f"Square: {r2Rectangle(7x7, area=49)}")  #?print_r2
  30. print(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_r3
    outputSquare: Rectangle(7x7, area=49)
  31. height ← 7.0710678118654755, width ← 14.142135623730951

    pass 1 of 2
    99@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_area
  32. r3 ← 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_r3
  33. print(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_r4
    outputFrom area (2:1): Rectangle(14.142135623730951x7.0710678118654755, area=100.00000000000001)
  34. height ← 10.0, width ← 10.0

    pass 2 of 2
    99@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_area
  35. r4 ← 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_r4
  36. print(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.
        
  37. 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.

staticmethod_utility.py
Replay: real traced execution (multi-file project)
# 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()



















































































  1. """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."""
  2. 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_palindrome2
    output=== Static Methods for Utilities ===
    --- StringUtils ---
  3. cleaned ← radar

    pass 1 of 3
    10@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_palindrome
    All 3 passes — pass 1 is the card above
    passscleaned[::-1]cleaned
    1radarradarradar
    2helloollehhello
    3A man a plan a canal Panamaamanaplanacanalpanamaamanaplanacanalpanama
  4. 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_palindrome3
    output'radar' is palindrome: True
  5. print(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_palindrome3
    output'hello' is palindrome: False
  6. print(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_vowels
    output'A man a plan a canal Panama': True
  7. def 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_body
  8. print(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_email2
    output
    Vowels in 'hello world': 3
  9. pattern ← ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

    pass 1 of 2
    21@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_email
  10. print(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_email2
    output
    'user@example.com' valid: True
  11. pattern ← ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

    pass 2 of 2
    21@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_email
  12. print(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_slugify2
    output'invalid-email' valid: False
  13. s ← hello world!

    pass 1 of 2
    27@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_slug
  14. print(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_slugify2
    output
    Slugify 'Hello World!': hello-world
  15. s ← my blog post

    pass 2 of 2
    27@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_slug
  16. print(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_factorial
    outputSlugify '  My Blog Post  ': my-blog-post
    
    --- MathUtils ---
  17. 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_loop
  18. result ← 2

    pass 1 of 4
    44result = 1  #?init_result45for i2 in range(2, n5 + 1):  #?factorial_loop46    result→ 2 *= i247return result  #?return_factorial
    All 4 passes — pass 1 is the card above
    passiresult
    121 2
    232 6
    346 24
    4524 120
  19. return result #?return_factorial

    46    result *= i47return result120  #?return_factorial
  20. print(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_primes
    output5! = 120
  21. def is_prime(n: int) -> bool: #?is_prime_def

    pass 1 of 20
    49@staticmethod  #?is_prime_decorator50def is_prime(n0: int) -> bool:  #?is_prime_def51    """Check if n is prime."""52    if n < 2:  #?check_less_than_2
    20 passes — pass 1 is the card above
    passn
    10
    21
    32
    43
    54
    65
    76
    87
    98
    ⋯ 9 more passes ⋯
    1918
    2019
  22. if n < 2: #?check_less_than_2

    pass 1 of 2
    51"""Check if n is prime."""52if n0 < 2:  #?check_less_than_253    return False54for i in range(2, int(n ** 0.5) + 1):  #?prime_loop
  23. if n < 2: #?check_less_than_2

    pass 2 of 2
    51"""Check if n is prime."""52if n1 < 2:  #?check_less_than_253    return False54for i in range(2, int(n ** 0.5) + 1):  #?prime_loop
  24. for i in range(2, int(n ** 0.5) + 1): #?prime_loop

    pass 1 of 24
    53    return False54for i2 in range(2, int(n4 ** 0.5) + 1):  #?prime_loop55    if n % i == 0:  #?divisible_check56        return False
    24 passes — pass 1 is the card above
    passin
    124
    225
    326
    427
    528
    629
    739
    8210
    9211
    ⋯ 13 more passes ⋯
    23319
    24419
  25. if n % i == 0: #?divisible_check

    pass 1 of 10
    54for i in range(2, int(n ** 0.5) + 1):  #?prime_loop55    if n4 % i2 == 0:  #?divisible_check56        return False57return True  #?is_prime_return
    All 10 passes — pass 1 is the card above
    passni
    142
    262
    382
    493
    5102
    6122
    7142
    8153
    9162
    10182
  26. return True #?is_prime_return

    56        return False57return True  #?is_prime_return
  27. return True #?is_prime_return

    56        return False57return True  #?is_prime_return
  28. return True #?is_prime_return

    56        return False57return True  #?is_prime_return
  29. return True #?is_prime_return

    56        return False57return True  #?is_prime_return
  30. return True #?is_prime_return

    56        return False57return True  #?is_prime_return
  31. return True #?is_prime_return

    56        return False57return True  #?is_prime_return
  32. primes ← [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_gcd
    outputPrimes under 20: [2, 3, 5, 7, 11, 13, 17, 19]
  33. 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_loop
  34. a ← 18, b ← 12

    pass 1 of 3
    61"""Calculate greatest common divisor."""62while b18:  #?gcd_loop63    a→ 18, b→ 12 = b, a % b  #?gcd_swap64return abs(a)  #?return_gcd
    All 3 passes — pass 1 is the card above
    passab
    148 1818 12
    218 1212 6
    312 66 0
  35. return abs(a) #?return_gcd

    63    a, b = b, a % b  #?gcd_swap64return abs(a6)  #?return_gcd
  36. print(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_clamp2
    outputGCD(48, 18) = 6
  37. def clamp(value: float, min_val: float, max_val: float) -> float: #?c…

    pass 1 of 3
    66@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_return
    All 3 passes — pass 1 is the card above
    passvalue
    115
    2-5
    35
  38. 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_clamp3
    outputClamp 15 to [0, 10]: 10
  39. print(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_clamp3
    outputClamp -5 to [0, 10]: 0
  40. usernames ← ['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_loop
    outputClamp 5 to [0, 10]: 5
    
    --- Validator ---
  41. for username in usernames: #?username_loop

    pass 1 of 5
    142usernames = ["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_symbol
    All 5 passes — pass 1 is the card above
    passusernameusername[0]
    1alice
    2ab
    3user_123
    41invalid1
    5valid_user_name_here_now
  42. def is_valid_username(username: str) -> tuple[bool, str]: #?is_valid_…

    pass 1 of 5
    75@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_username
    All 5 passes — pass 1 is the card above
    passusernameusername[0]
    1alice
    2ab
    3user_123
    41invalid1
    5valid_user_name_here_now
  43. 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_result
    output  ✓ 'alice': Valid username
  44. if 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_length
  45. valid ← 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_result
    output  ✗ 'ab': Username must be at least 3 characters
  46. valid ← 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_result
    output  ✓ 'user_123': Valid username
  47. if 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_chars
  48. valid ← 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_result
    output  ✗ '1invalid': Username must start with a letter
  49. if 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_char
  50. valid ← 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_result
    output  ✗ 'valid_user_name_here_now': Username must be at most 20 characters
  51. passwords ← ['weak', 'Better123', 'Strong@Pass1']

    148print("\nPassword strength:")  #?password_header149passwords→ ['weak', 'Better123', 'Strong@Pass1'] = ["weak", "Better123", "Strong@Pass1"]  #?test_passwords150for password in passwords:  #?password_loop
    output
    Password strength:
  52. for password in passwords: #?password_loop

    pass 1 of 3
    149passwords = ["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_strong
    All 3 passes — pass 1 is the card above
    passpasswordreissues
    1weak<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>[] ['Must be at least 8 characters']
    2Better123<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>[] ['Must contain special character (!@#$%^&*)']
    3Strong@Pass1
  53. issues ← []

    pass 1 of 3
    88@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_issues
    All 3 passes — pass 1 is the card above
    passpasswordreissues
    1weak<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>[]
    2Better123<module 're' from '/usr/local/lib/python3.12/re/__init__.py'>[]
    3Strong@Pass1[]
  54. 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_uppercase
  55. issues ← ['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_lowercase
  56. issues ← ['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_special
  57. issues ← ['Must be at least 8 characters', 'Must contain uppercase letter', 'Must contain digit', 'Must contain special character (!@#$%^&*)']

    pass 1 of 2
    100    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 (!@#$%^&*)")
  58. 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_result
  59. strong ← 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
  60. #?print_strong else:

    pass 1 of 2
    152if 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_weak
    output  ✗ 'weak': Must be at least 8 characters, Must contain uppercase letter, Must contain digit, Must contain special character (!@#$%^&*)
  61. issues ← ['Must contain special character (!@#$%^&*)']

    pass 2 of 2
    100    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 (!@#$%^&*)")
  62. return len(issues) == 0, issues #?return_password_result

    104return len(issues['Must contain special character (!@#$%^&*)']) == 0, issues  #?return_password_result
  63. strong ← 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
  64. #?print_strong else:

    pass 2 of 2
    152if strong:  #?check_strong153    print(f"  ✓ '{password}': Strong password")  #?print_strong154else:155    print(f"  ✗ '{passwordBetter123}': {', '.join(issues['Must contain special character (!@#$%^&*)'])}")  #?print_weak
    output  ✗ 'Better123': Must contain special character (!@#$%^&*)
  65. 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_strong
  66. if 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 password
  67. print(" === 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 subclasses
        
  68. main()

    173if __name__ == "__main__":174    main()

Related utilities grouped in class namespace. Called on class, not instance.

Inheritance behavior

How these methods behave in subclasses.

inheritance_behavior.py
Replay: real traced execution (multi-file project)
# 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()





































































  1. 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."""
  2. 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_dog
    output=== Inheritance Behavior ===
    --- @classmethod with Inheritance ---
  3. def create(cls, name: str): #?create_def

    pass 1 of 3
    17@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_instance
    outputCreating Animal
    All 3 passes — pass 1 is the card above
    passclsnamecls.__name__
    1<class '__main__.Animal'>GenericAnimal
    2<class '__main__.Dog'>RexDog
    3<class '__main__.Cat'>WhiskersCat
  4. self.name ← Generic, Animal.species_count ← 1

    pass 1 of 5
    8def __init__(self⟨Animal A⟩, nameGeneric: str):  #?animal_init9    self.name→ Generic = nameGeneric10    Animal.species_count→ 1 += 1
    All 5 passes — pass 1 is the card above
    passselfnameself.nameAnimal.species_count
    1⟨Animal A⟩GenericGeneric0 1
    2⟨Dog B⟩RexRex1 2
    3⟨Cat C⟩WhiskersWhiskers2 3
    4⟨WorkingDog D⟩MaxMax3 4
    5⟨Cat E⟩Little FluffyLittle Fluffy4 5
  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_cat
  6. dog ← ⟨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_cat
  7. cat ← ⟨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_dog
    outputanimal type: Animal
    dog type: Dog
    cat type: Cat
    
    --- describe_class (cls aware) ---
  8. def describe_class(cls) -> str: #?describe_class_def

    pass 1 of 3
    23@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_body
    All 3 passes — pass 1 is the card above
    passclscls.__name__
    1<class '__main__.Animal'>Animal
    2<class '__main__.Dog'>Dog
    3<class '__main__.Cat'>Cat
  9. 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_cat
    outputClass: Animal
  10. print(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_cat
    outputClass: Dog
  11. print(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_inherited
    outputClass: Cat
    
    --- @staticmethod with Inheritance ---
  12. def validate_name(name: str) -> bool: #?validate_name_def

    pass 1 of 3
    29@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_body
    All 3 passes — pass 1 is the card above
    passnamename[0]
    1RexR
    2RexR
    3rexr
  13. 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_inherited
    outputAnimal.validate_name('Rex'): True
  14. print(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_dog
    outputCat.validate_name('Rex'): True
  15. print(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_dog
    outputAnimal.validate_name('rex'): False
  16. def 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_body
  17. print(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_dog
    outputDog.validate_name('rex'): True
    
    --- Regular Method with Inheritance ---
  18. 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_body
  19. print(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_cat
    outputanimal.speak(): Generic makes a sound
  20. def speak(self) -> str: #?dog_speak

    38def speak(self⟨Dog B⟩) -> str:  #?dog_speak39    return f"{self.nameRex} says Woof!"  #?dog_speak_body
  21. print(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_cat
    outputdog.speak(): Rex says Woof!
  22. def speak(self) -> str: #?cat_speak

    pass 1 of 2
    51def speak(self⟨Cat C⟩) -> str:  #?cat_speak52    return f"{self.nameWhiskers} says Meow!"  #?cat_speak_body
  23. print(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_type
    outputcat.speak(): Whiskers says Meow!
    
    --- Multi-level Inheritance ---
  24. 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_return
    outputCreating WorkingDog with job: police
  25. def __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 = job
  26. self.job ← police

    65super().__init__(name)66self.job→ police = jobpolice
  27. working_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_working
    outputworking_dog type: WorkingDog
  28. def 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_body
  29. print(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_name
    outputworking_dog.speak(): Max the police dog says Woof!
    
    --- Subclass-specific Methods ---
  30. 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_body
  31. kitten ← ⟨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_kitten
    outputkitten.name: Little Fluffy
  32. def speak(self) -> str: #?cat_speak

    pass 2 of 2
    51def speak(self⟨Cat E⟩) -> str:  #?cat_speak52    return f"{self.nameLittle Fluffy} says Meow!"  #?cat_speak_body
  33. print(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 instance
        
  34. main()

    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