[DP]strategy
来源:互联网 发布:mac final cutpro x 编辑:程序博客网 时间:2024/06/05 15:28
# coding: utf-8# # Srategy Pattern# 策略模式定义一系列算法并封装它们,这些算法可以互换。# 策略模式还根据不同的对象使用不同的算法。# ## class implement# In[10]:import abcimport collectionsCustomer = collections.namedtuple('Customer', 'name fidelity')class LineItem(object): def __init__(self, product, quantity, price): self.product = product self.quantity = quantity self.price = price def total(self): return self.quantity * self.price class Order(object): def __init__(self, customer, cart, promotion=None): self.customer = customer self.cart = cart self.promotion = promotion def total(self): if not hasattr(self, '__total'): self.__total = sum(lineitem.total() for lineitem in self.cart) return self.__total def due(self): discount = 0 if self.promotion is None else self.promotion.discount(self) return self.total() - discount def __repr__(self): return "<Order total:{:.2f} due:{:.2f}>".format(self.total(), self.due())class Promotion(abc.ABC): """abstract class of Promotion""" @abc.abstractmethod def discount(self, Order): """return the discount vary different Order """ pass class FidelityPromo(Promotion): """if fidelity >= 1000 Give 5% discount""" def discount(self, order): """ return 0.05 of the total price of Order """ return 0.05*order.total() if order.customer.fidelity >= 100 else 0.0class BulkItemPromo(Promotion): """if the lineitem's quantity >= 20 give the lineitem'total price 10% discount""" def discount(self, order): discount = sum((0.1*lineitem.total() if lineitem.quantity >= 20 else 0.0 for lineitem in order.cart)) return discount class LargeOrderPromo(Promotion): """7% discount for the kind of lineitems in cart >10 """ def discount(self, order): kinds = {lineitem.product for lineitem in order.cart} return 0.07*order.total() if len(kinds)>=10 else 0.0 # In[3]:joe = Customer('John Doe', 0)# In[4]:ann = Customer('Ann Smith', 1100)# In[5]:cart = [LineItem('banana', 4, .5),LineItem('apple', 10, 1.5),LineItem('watermellon', 5, 5.0)]# In[11]:Order(joe, cart, FidelityPromo()) # joe's fidelity < 1000# Out[11]: <Order total:42.00 due:42.00># In[12]:Order(ann, cart, FidelityPromo()) # ann's fidelity > 1000# Out[12]: <Order total:42.00 due:39.90># In[13]:banana_cart = [LineItem('banana', 30, .5),LineItem('apple', 10, 1.5)]# In[14]:Order(joe, banana_cart, BulkItemPromo()) # number of 'banana' > 20# Out[14]: <Order total:30.00 due:28.50># In[15]:long_order = [LineItem(str(item_code), 1, 1.0) for item_code in range(10)]# In[16]:Order(joe, long_order, LargeOrderPromo()) # number of line items >=10# Out[16]: <Order total:10.00 due:9.30># In[17]:Order(joe, cart, LargeOrderPromo())# Out[17]: <Order total:42.00 due:42.00># ## function implement# function is the first class in python.# considering the subclasses of Promotion are very simple, i think implementation them as function is better.# the defination of Customer, LineItem and Oder is no need to change.# but change the due method in Oder is nesscery.# In[18]:import collectionsCustomer = collections.namedtuple('Customer', 'name fidelity')class LineItem(object): def __init__(self, product, quantity, price): self.product = product self.quantity = quantity self.price = price def total(self): return self.quantity * self.price class Order(object): def __init__(self, customer, cart, promotion=None): self.customer = customer self.cart = cart self.promotion = promotion def total(self): if not hasattr(self, '__total'): self.__total = sum(lineitem.total() for lineitem in self.cart) return self.__total def due(self): discount = 0 if self.promotion is None else self.promotion(self) return self.total() - discount def __repr__(self): return "<Order total:{:.2f} due:{:.2f}>".format(self.total(), self.due())def fidelity_promo(order): return 0.05*order.total() if order.customer.fidelity >= 100 else 0.0def bulk_promo(order): return sum((0.1*lineitem.total() if lineitem.quantity >= 20 else 0.0 for lineitem in order.cart))def large_order_promo(order): kinds = {lineitem.product for lineitem in order.cart} return 0.07*order.total() if len(kinds)>=10 else 0.0# In[19]:joe = Customer('John Doe', 0)ann = Customer('Ann Smith', 1100)cart = [LineItem('banana', 4, .5),LineItem('apple', 10, 1.5),LineItem('watermellon', 5, 5.0)]# In[20]:Order(joe, cart, fidelity_promo) # joe's fidelity < 1000# Out[20]: <Order total:42.00 due:42.00># In[21]:Order(ann, cart, fidelity_promo) # ann's fidelity > 1000# Out[21]:<Order total:42.00 due:39.90># In[22]:banana_cart = [LineItem('banana', 30, .5),LineItem('apple', 10, 1.5)]# In[24]:Order(joe, banana_cart, bulk_promo) # number of 'banana' > 20# Out[24]: <Order total:30.00 due:28.50># In[25]:long_order = [LineItem(str(item_code), 1, 1.0) for item_code in range(10)]# In[27]:Order(joe, long_order, large_order_promo) # number of line items >=10# Out[27]:<Order total:10.00 due:9.30># In[28]:Order(joe, cart, large_order_promo)# Out[28]: <Order total:42.00 due:42.00># ## what is the best promotion# In[31]:promos = [fidelity_promo, bulk_promo, large_order_promo]def best_promo(order): return max(promo(order) for promo in promos)# In[32]:Order(joe, long_order, best_promo)# Out[32]:<Order total:10.00 due:9.30># In[33]:Order(joe, banana_cart, best_promo)# Out[33]: <Order total:30.00 due:28.50># In[34]:Order(ann, cart, best_promo)# Out[34]:<Order total:42.00 due:39.90># there is another way to find the all promotions in a module.# use globals()# globals() return a dict of all parameters: variable, function , class in current module.# In[35]:promos = [globals()[name] for name in globals() if name.endswith('_promo') and name != 'best_promo']# also inspect module can inpect a module.# for example, there is a module named promotions:# In[ ]:promos = [func for name, func in inspect.getmembers(promotions, inspect.isfunction)]
0 0
- [DP]strategy
- uva 11341 Term Strategy (DP)
- Strategy
- Strategy
- Strategy
- Strategy
- Strategy
- Strategy
- Strategy
- strategy
- strategy
- Strategy
- Strategy
- Strategy
- Strategy
- Strategy
- Strategy Pattern
- strategy模式
- Direct3D基础
- 数组。。。。
- 火柴排队
- 文章标题
- 韩咏梅:幸福只需要七分饱(转自新加坡联合早报)
- [DP]strategy
- Android开发 工具
- hdu 2579 Dating with girls(2)【bfs】
- MyBatis入门(七)---逆向工程
- [sicily]1931. 卡片游戏
- 多元统计分析上机题之R语言实现(因子分析)
- 在开发板上移植是第三放程序————例lrzsz
- IOS中Socket的使用
- [Chromium官方博客文章转载]Jank Busters Part One(UI Jank指的是界面来不及刷新导致的卡塞空白现象?