Exercise 1: Adding a FreeShipping Strategy and Swapping Through All Four — Possible Solution ==================================================================== THE NEW STRATEGY ------------------------------ class FreeShipping: def calculate(self, weight): return 0 Matches this chapter's own strategy shape exactly - a single calculate(weight) method, same signature as StandardShipping/ExpressShipping/OvernightShipping, just ignoring weight entirely and always returning 0. SWAPPING THROUGH ALL FOUR ON THE SAME ORDER OBJECT ------------------------------ Starting from order = Order(25, StandardShipping()): standard: 12.5 (manual: 25 * 0.5 = 12.5) express: 35.0 (manual: 25 * 1.2 + 5 = 35.0) overnight: 77.5 (manual: 25 * 2.5 + 15 = 77.5) free: 0 Each call to set_shipping_strategy() followed by calculate_shipping() on the SAME order object produces a different, correctly-computed result - matching this chapter's own three-swap demonstration, just extended to four strategies including one that deliberately ignores its own input entirely. WHY FreeShipping STILL FITS THE PATTERN CLEANLY ------------------------------ FreeShipping's calculate() method doesn't need to use its weight parameter at all, but it still has to ACCEPT it - Order.calculate_shipping() always calls self.shipping_strategy.calculate(self.weight) the same way, regardless of which strategy is plugged in. A strategy is free to ignore part of its own input, but it still has to honor the shared interface's signature, or Order's own unchanged code would break. WHY THIS WORKS AS AN ANSWER ------------------------------ The new strategy follows the existing calculate(weight) interface exactly even though it doesn't use its argument, all four results are verified on one unmodified Order object via repeated runtime swaps exactly as this chapter's own example did, and the three non-zero results are cross-checked against hand calculations.