Modernize code to Python 3.6+ and some cleanup
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5), # <2>
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, FidelityPromo()) # <3>
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, FidelityPromo()) # <4>
|
||||
@@ -72,8 +72,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
class Promotion(ABC): # the Strategy: an abstract base class
|
||||
|
||||
@@ -21,7 +21,7 @@ def cart_plain() -> List[LineItem]:
|
||||
return [
|
||||
LineItem('banana', 4, 0.5),
|
||||
LineItem('apple', 10, 1.5),
|
||||
LineItem('watermellon', 5, 5.0),
|
||||
LineItem('watermelon', 5, 5.0),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5), # <2>
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, FidelityPromo()) # <3>
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, FidelityPromo()) # <4>
|
||||
@@ -29,7 +29,6 @@
|
||||
# tag::CLASSIC_STRATEGY[]
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from collections import namedtuple
|
||||
import typing
|
||||
|
||||
|
||||
@@ -69,8 +68,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
class Promotion(ABC): # the Strategy: an abstract base class
|
||||
|
||||
@@ -20,7 +20,7 @@ def customer_fidelity_1100() -> Customer:
|
||||
def cart_plain() -> List[LineItem]:
|
||||
return [LineItem('banana', 4, .5),
|
||||
LineItem('apple', 10, 1.5),
|
||||
LineItem('watermellon', 5, 5.0)]
|
||||
LineItem('watermelon', 5, 5.0)]
|
||||
|
||||
|
||||
def test_fidelity_promo_no_discount(customer_fidelity_0, cart_plain) -> None:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5), # <2>
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, FidelityPromo()) # <3>
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, FidelityPromo()) # <4>
|
||||
@@ -29,7 +29,6 @@
|
||||
# tag::CLASSIC_STRATEGY[]
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from collections import namedtuple
|
||||
import typing
|
||||
|
||||
from pytypes import typelogged
|
||||
@@ -71,8 +70,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
@typelogged
|
||||
|
||||
@@ -20,7 +20,7 @@ def customer_fidelity_1100() -> Customer:
|
||||
def cart_plain() -> List[LineItem]:
|
||||
return [LineItem('banana', 4, .5),
|
||||
LineItem('apple', 10, 1.5),
|
||||
LineItem('watermellon', 5, 5.0)]
|
||||
LineItem('watermelon', 5, 5.0)]
|
||||
|
||||
|
||||
def test_fidelity_promo_no_discount(customer_fidelity_0, cart_plain) -> None:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo) # <2>
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -71,8 +71,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
# <2>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> banana_cart = [LineItem('banana', 30, .5),
|
||||
... LineItem('apple', 10, 1.5)]
|
||||
>>> big_cart = [LineItem(str(item_code), 1, 1.0)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -69,8 +69,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
def fidelity_promo(order):
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -73,8 +73,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
# tag::STRATEGY_BEST3[]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity)
|
||||
@@ -71,8 +71,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
# tag::STRATEGY_BEST4[]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo(10))
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo(10))
|
||||
@@ -73,8 +73,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
# tag::STRATEGY_PARAM[]
|
||||
@@ -85,7 +84,7 @@ Promotion = Callable[[Order], float] # <2>
|
||||
def fidelity_promo(percent: float) -> Promotion:
|
||||
"""discount for customers with 1000 or more fidelity points"""
|
||||
return lambda order: (
|
||||
order.total() * percent / 100.0 if order.customer.fidelity >= 1000 else 0
|
||||
order.total() * percent / 100 if order.customer.fidelity >= 1000 else 0
|
||||
)
|
||||
|
||||
|
||||
@@ -96,7 +95,7 @@ def bulk_item_promo(percent: float) -> Promotion:
|
||||
discount = 0
|
||||
for item in order.cart:
|
||||
if item.quantity >= 20:
|
||||
discount += item.total() * percent / 100.0
|
||||
discount += item.total() * percent / 100
|
||||
return discount
|
||||
|
||||
return discounter
|
||||
@@ -111,13 +110,13 @@ class LargeOrderPromo:
|
||||
def __call__(self, order: Order) -> float:
|
||||
distinct_items = {item.product for item in order.cart}
|
||||
if len(distinct_items) >= 10:
|
||||
return order.total() * self.percent / 100.0
|
||||
return order.total() * self.percent / 100
|
||||
return 0
|
||||
|
||||
|
||||
def general_discount(percent: float, order: Order) -> float:
|
||||
"""unrestricted discount; usage: ``partial(general_discount, 5)``"""
|
||||
return order.total() * percent / 100.0
|
||||
return order.total() * percent / 100
|
||||
|
||||
|
||||
# end::STRATEGY[]
|
||||
|
||||
@@ -23,7 +23,7 @@ def cart_plain() -> List[LineItem]:
|
||||
return [
|
||||
LineItem('banana', 4, 0.5),
|
||||
LineItem('apple', 10, 1.5),
|
||||
LineItem('watermellon', 5, 5.0),
|
||||
LineItem('watermelon', 5, 5.0),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ def cart_plain() -> List[LineItem]:
|
||||
return [
|
||||
LineItem('banana', 4, 0.5),
|
||||
LineItem('apple', 10, 1.5),
|
||||
LineItem('watermellon', 5, 5.0),
|
||||
LineItem('watermelon', 5, 5.0),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5), # <2>
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, FidelityPromo()) # <3>
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, FidelityPromo()) # <4>
|
||||
@@ -65,8 +65,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
class Promotion(ABC): # the Strategy: an abstract base class
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
def fidelity_promo(order):
|
||||
"""5% discount for customers with 1000 or more fidelity points"""
|
||||
return order.total() * .05 if order.customer.fidelity >= 1000 else 0
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo) # <2>
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -64,8 +64,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
# <2>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -71,8 +71,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
def fidelity_promo(order):
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -71,8 +71,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
def fidelity_promo(order):
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo)
|
||||
@@ -75,8 +75,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
# tag::STRATEGY_BEST3[]
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity)
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity)
|
||||
@@ -72,8 +72,7 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
# tag::STRATEGY_BEST4[]
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, fidelity_promo(10))
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, fidelity_promo(10))
|
||||
@@ -60,13 +60,12 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
def fidelity_promo(percent):
|
||||
"""discount for customers with 1000 or more fidelity points"""
|
||||
return lambda order: (order.total() * percent/100.0
|
||||
return lambda order: (order.total() * percent / 100
|
||||
if order.customer.fidelity >= 1000 else 0)
|
||||
|
||||
|
||||
@@ -76,7 +75,7 @@ def bulk_item_promo(percent):
|
||||
discount = 0
|
||||
for item in order.cart:
|
||||
if item.quantity >= 20:
|
||||
discount += item.total() * percent/100.0
|
||||
discount += item.total() * percent / 100
|
||||
return discount
|
||||
return discounter
|
||||
|
||||
@@ -86,6 +85,6 @@ def large_order_promo(percent):
|
||||
def discounter(order):
|
||||
distinct_items = {item.product for item in order.cart}
|
||||
if len(distinct_items) >= 10:
|
||||
return order.total() * percent / 100.0
|
||||
return order.total() * percent / 100
|
||||
return 0
|
||||
return discounter
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
>>> ann = Customer('Ann Smith', 1100)
|
||||
>>> cart = [LineItem('banana', 4, .5),
|
||||
... LineItem('apple', 10, 1.5),
|
||||
... LineItem('watermellon', 5, 5.0)]
|
||||
... LineItem('watermelon', 5, 5.0)]
|
||||
>>> Order(joe, cart, FidelityPromo(10))
|
||||
<Order total: 42.00 due: 42.00>
|
||||
>>> Order(ann, cart, FidelityPromo(10))
|
||||
@@ -60,11 +60,10 @@ class Order: # the Context
|
||||
return self.total() - discount
|
||||
|
||||
def __repr__(self):
|
||||
fmt = '<Order total: {:.2f} due: {:.2f}>'
|
||||
return fmt.format(self.total(), self.due())
|
||||
return f'<Order total: {self.total():.2f} due: {self.due():.2f}>'
|
||||
|
||||
|
||||
class Promotion():
|
||||
class Promotion:
|
||||
"""compute discount for order"""
|
||||
|
||||
def __init__(self, percent):
|
||||
@@ -79,7 +78,7 @@ class FidelityPromo(Promotion):
|
||||
|
||||
def __call__(self, order):
|
||||
if order.customer.fidelity >= 1000:
|
||||
return order.total() * self.percent/100.0
|
||||
return order.total() * self.percent / 100
|
||||
return 0
|
||||
|
||||
|
||||
@@ -90,7 +89,7 @@ class BulkItemPromo(Promotion):
|
||||
discount = 0
|
||||
for item in order.cart:
|
||||
if item.quantity >= 20:
|
||||
discount += item.total() * self.percent/100.0
|
||||
discount += item.total() * self.percent / 100
|
||||
return discount
|
||||
|
||||
|
||||
@@ -100,5 +99,5 @@ class LargeOrderPromo(Promotion):
|
||||
def __call__(self, order):
|
||||
distinct_items = {item.product for item in order.cart}
|
||||
if len(distinct_items) >= 10:
|
||||
return order.total() * self.percent / 100.0
|
||||
return order.total() * self.percent / 100
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user