Modernize code to Python 3.6+ and some cleanup

This commit is contained in:
Miroslav Šedivý
2021-01-31 22:48:38 +01:00
parent 93bb4407fa
commit b69e0c2023
86 changed files with 153 additions and 189 deletions

View File

@@ -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

View File

@@ -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),
]

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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:

View File

@@ -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>

View File

@@ -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)

View File

@@ -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):

View File

@@ -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[]

View File

@@ -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[]

View File

@@ -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[]

View File

@@ -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),
]

View File

@@ -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),
]

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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):

View File

@@ -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):

View File

@@ -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[]

View File

@@ -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[]

View File

@@ -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

View File

@@ -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