1+ # from abc import ABC, abstractmethod
2+ from collections import namedtuple
3+
4+ Customer = namedtuple ('Customer' , 'name fidelity' )
5+
6+
7+ class LineItem :
8+ def __init__ (self , product , quantity , price ):
9+ self .product = product
10+ self .quantity = quantity
11+ self .price = price
12+
13+ def total (self ):
14+ return self .price * self .quantity
15+
16+
17+ class Order :
18+
19+ def __init__ (self , customer , cart , promotion = None ):
20+ self .customer = customer
21+ self .cart = list (cart )
22+ self .promotion = promotion
23+
24+ def total (self ):
25+ if not hasattr (self , '__total' ):
26+ self .__total = sum (item .total () for item in self .cart )
27+ return self .__total
28+
29+ def due (self ):
30+ if self .promotion is None :
31+ discount = 0
32+ else :
33+ discount = self .promotion (self )
34+ return self .total () - discount
35+
36+ def __repr__ (self ):
37+ fmt = '<Order total: {:.2f} due: {:.2f}>'
38+ return fmt .format (self .total (), self .due ())
39+
40+
41+ promos = []
42+
43+
44+ def promotion (promo_func ):
45+ promos .append (promo_func )
46+ return promo_func
47+
48+
49+ @promotion
50+ def fidelity_promo (order ):
51+ '''为积分为1000或以上的顾客提供5%折扣'''
52+ return order .total () * .05 if order .customer .fidelity >= 1000 else 0
53+
54+
55+ @promotion
56+ def bulkItem_promo (order ):
57+ '''单个商品为20个或以上时提供10%折扣'''
58+ discount = 0
59+ for item in order .cart :
60+ if item .quantity >= 20 :
61+ discount += item .total () * .1
62+ return discount
63+
64+
65+ @promotion
66+ def large_order_promo (order ):
67+ '''订单中的不同商品达到10个或以上时提供7%折扣'''
68+ distinct_items = {item .product for item in order .cart }
69+ if len (distinct_items ) >= 10 :
70+ return order .total () * .07
71+ return 0
72+
73+
74+ def best_promo (order ):
75+ ''' 选择可用的最佳折扣 '''
76+ return max (promo (order ) for promo in promos )
0 commit comments