Exercise 1: Adding a Third Port, DiscountPort — Possible Solution ==================================================================== THE NEW PORT AND ITS TWO ADAPTERS ------------------------------ class DiscountPort: def get_promo_discount(self, promo_code): raise NotImplementedError class FakeDiscountAdapter(DiscountPort): def __init__(self, promos): self.promos = promos def get_promo_discount(self, promo_code): return self.promos.get(promo_code, 0) class RealDiscountAdapter(DiscountPort): def __init__(self, promos): self.promos = promos def get_promo_discount(self, promo_code): time.sleep(0.01) return self.promos.get(promo_code, 0) Follows this chapter's own two-adapters-per-port shape exactly - same method signature on both, the "real" one adding the identical time.sleep(0.01) this chapter's own RealInventoryAdapter used. WIRING IT INTO PricingEngine ------------------------------ def __init__(self, inventory_port, notification_port, discount_port): self.inventory = inventory_port self.notifications = notification_port self.discounts = discount_port def calculate_price(self, product_id, base_price, promo_code=None): stock = self.inventory.get_stock_level(product_id) price = base_price if stock < 10: self.notifications.notify_low_stock(product_id) price = price * 1.15 if promo_code: discount_pct = self.discounts.get_promo_discount(promo_code) price = price * (1 - discount_pct) return price VERIFYING IDENTICAL RESULTS FROM FAKE AND REAL ADAPTERS ------------------------------ Pricing PROD-1 (stock 5, low-stock rule triggers) with promo code SAVE5 (5% off): price via fake adapters (with promo): 109.24999999999999 price via real adapters (with promo): 109.24999999999999 manual check: 100*1.15*(1-0.05) = 109.24999999999999 identical: True Both adapters, and a manual calculation, all agree exactly. VERIFYING THE CORE STILL REFERENCES NO CONCRETE ADAPTER ------------------------------ PricingEngine references FakeDiscountAdapter: False PricingEngine references RealDiscountAdapter: False Confirmed via the same inspect.getsource() technique this chapter already used for the first two ports - adding a third port didn't require PricingEngine to know about either of its adapters either. WHY THIS WORKS AS AN ANSWER ------------------------------ The new port and its two adapters mirror this chapter's own established shape exactly, the business result is verified identical between fake and real adapters and cross-checked by hand, and the dependency-inversion property is re-verified rather than assumed to still hold once a third port was added.