Advanced Code Example — Classes and OOP#
This example demonstrates a class hierarchy with inheritance, class methods, and polymorphism — modeling a real retail analytics system with Customer and PremiumCustomer classes.
Business Scenario#
You are building a customer management system for a retail chain. The system needs to:
- Model standard customers with purchase tracking and tier classification
- Model premium customers who have additional benefits (extended tier benefits, dedicated support)
- Process a mixed portfolio of both customer types using a shared interface
Code#
# ══════════════════════════════════════════════════════════
# BASE CLASS — Standard Customer
# ══════════════════════════════════════════════════════════
class Customer:
"""Represents a standard retail customer."""
tier_thresholds = {
'Platinum': 1000,
'Gold': 500,
'Silver': 200
}
def __init__(self, name: str, customer_id: int, region: str):
self.name = name
self.customer_id = customer_id
self.region = region
self.purchases = []
self.account_type = 'Standard'
def add_purchase(self, amount: float) -> None:
if amount <= 0:
raise ValueError(f"Purchase amount must be positive, got {amount}")
self.purchases.append(round(amount, 2))
def total_spent(self) -> float:
return round(sum(self.purchases), 2)
def purchase_count(self) -> int:
return len(self.purchases)
def average_purchase(self) -> float:
if not self.purchases:
return 0.0
return round(self.total_spent() / self.purchase_count(), 2)
def classify_tier(self) -> str:
total = self.total_spent()
for tier_name, threshold in self.tier_thresholds.items():
if total >= threshold:
return tier_name
return 'Standard'
def shipping_discount(self) -> float:
tier_discounts = {'Platinum': 0.15, 'Gold': 0.10, 'Silver': 0.05, 'Standard': 0.00}
return tier_discounts.get(self.classify_tier(), 0.00)
def summary(self) -> str:
return (f"[{self.account_type}] {self.name} (ID: {self.customer_id}) | "
f"Region: {self.region} | Total: ${self.total_spent():,.2f} | "
f"Tier: {self.classify_tier()} | Discount: {self.shipping_discount()*100:.0f}%")
def __repr__(self) -> str:
return f"Customer(name='{self.name}', id={self.customer_id})"
# ══════════════════════════════════════════════════════════
# SUBCLASS — Premium Customer (inherits from Customer)
# ══════════════════════════════════════════════════════════
class PremiumCustomer(Customer):
"""Premium member with enhanced benefits and dedicated support."""
def __init__(self, name: str, customer_id: int, region: str, membership_years: int):
super().__init__(name, customer_id, region) # call parent __init__
self.membership_years = membership_years
self.account_type = 'Premium'
def loyalty_bonus(self) -> float:
"""Additional discount based on membership longevity."""
if self.membership_years >= 5:
return 0.05
elif self.membership_years >= 2:
return 0.03
return 0.01
def shipping_discount(self) -> float:
"""Override parent: premium gets base + loyalty bonus."""
base = super().shipping_discount()
return min(base + self.loyalty_bonus(), 0.30) # capped at 30%
def summary(self) -> str:
base = super().summary()
return f"{base} | Loyalty Bonus: {self.loyalty_bonus()*100:.0f}% | Member: {self.membership_years}yr"
# ══════════════════════════════════════════════════════════
# PORTFOLIO — Mixed customer types, shared interface
# ══════════════════════════════════════════════════════════
portfolio: list[Customer] = [
Customer('Bob Martinez', 1002, 'Southwest'),
Customer('David Kim', 1004, 'Southeast'),
PremiumCustomer('Alice Johnson', 1001, 'Northwest', membership_years=6),
PremiumCustomer('Carol Chen', 1003, 'Northwest', membership_years=3),
]
# Add purchases
purchases_data = {
'Alice Johnson': [250.50, 180.75, 420.25, 310.00, 420.00, 380.00],
'Bob Martinez': [95.80, 215.25, 110.00],
'Carol Chen': [300.00, 290.75, 300.00, 410.00],
'David Kim': [45.00, 60.00],
}
for customer in portfolio:
for amount in purchases_data.get(customer.name, []):
customer.add_purchase(amount)
# Print summaries — same .summary() call works for BOTH class types (polymorphism)
print("=" * 72)
print(" CUSTOMER PORTFOLIO")
print("=" * 72)
for customer in sorted(portfolio, key=lambda c: c.total_spent(), reverse=True):
print(f" {customer.summary()}")
print("\n" + "=" * 72)
print(f" Total Portfolio Revenue: ${sum(c.total_spent() for c in portfolio):,.2f}")
print(f" Premium Customers: {sum(1 for c in portfolio if isinstance(c, PremiumCustomer))}")
print(f" Standard Customers: {sum(1 for c in portfolio if type(c) == Customer)}")
print("=" * 72)Expected Output#
========================================================================
CUSTOMER PORTFOLIO
========================================================================
[Premium] Alice Johnson (ID: 1001) | Region: Northwest | Total: $1,961.50 | Tier: Platinum | Discount: 20% | Loyalty Bonus: 5% | Member: 6yr
[Premium] Carol Chen (ID: 1003) | Region: Northwest | Total: $1,300.75 | Tier: Platinum | Discount: 18% | Loyalty Bonus: 3% | Member: 3yr
[Standard] Bob Martinez (ID: 1002) | Region: Southwest | Total: $421.05 | Tier: Silver | Discount: 5%
[Standard] David Kim (ID: 1004) | Region: Southeast | Total: $105.00 | Tier: Standard | Discount: 0%
========================================================================
Total Portfolio Revenue: $3,788.30
Premium Customers: 2
Standard Customers: 2
========================================================================Key Concepts Demonstrated#
| Concept | Where in Code |
|---|---|
Class definition with __init__ |
Customer.__init__() |
Instance attributes (self.x) |
self.name, self.purchases, etc. |
| Class attribute (shared) | tier_thresholds dictionary |
| Inheritance | class PremiumCustomer(Customer) |
super() call |
super().__init__(...) in PremiumCustomer |
| Method override | PremiumCustomer.shipping_discount() |
| Polymorphism | customer.summary() called on both types |
isinstance() |
Checking customer type in portfolio summary |
Next: Jupyter Notebook →