Advertisement
kidig

Задачка - Скидки на продукты

Feb 15th, 2013
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # -*- coding: utf8 -*-
  2.  
  3. from collections import defaultdict
  4.  
  5.  
  6. def discount_together(order_items, discounts, products=[], percent=0):
  7.     ''' Скидки для групп товаров, присутствующих в заказе '''
  8.    
  9.     # выходим, если хотя бы один товар не найден
  10.     if not set(products).issubset(order_items.keys()):
  11.         return discounts
  12.    
  13.     # определяем кол-во найденных групп
  14.     pairs = min([len(order_items[x]) for x in products])
  15.    
  16.     for p in products:
  17.         for idx in range(pairs):
  18.             key = order_items[p][idx]
  19.            
  20.             # пропускаем, если скидка для товара установлена
  21.             if key in discounts:
  22.                 continue
  23.  
  24.             discounts[key] = percent
  25.             print "discount_and: %s - %.2f" % (key, percent)
  26.  
  27.     return discounts
  28.  
  29.  
  30. def discount_oneof(order_items, discounts, products=[], percent=0, condition = []):
  31.     ''' Скидки для каждого товара из группы, [при наличии другого товара из условия] '''
  32.    
  33.     # если задано условия, проверяем его в первую очередь
  34.     if len(condition) and not set(condition).issubset(order_items.keys()):
  35.         return basket
  36.        
  37.     for p in products:
  38.         for key in order_items.get(p, []):
  39.            
  40.             # пропускаем, если скидка для товара уже задана
  41.             if key in discounts:
  42.                 continue
  43.            
  44.             discounts[key] = percent
  45.             print "discount_or: %s - %.2f" % (key, percent)
  46.            
  47.     return discounts
  48.  
  49.  
  50. def order_discount(order_items, ranges, exclude = []):
  51.     ''' Скидка на сумму заказа, в зависимости от кол-ва товаров, [исключая некоторые позиции] '''
  52.  
  53.     # количество товаров в заказе, исключая позиции exclude
  54.     total_len = sum([ len(items) for key, items in order_items.iteritems() if not key in exclude ])
  55.  
  56.     # выбираем скидку, соответствующую кол-ву товаров в заказе
  57.     discount = ranges.get(str(total_len), 0)
  58.  
  59.     if discount > 0:
  60.         print "total_discount: %.2f" % (discount)
  61.  
  62.     return discount
  63.  
  64.  
  65. def get_basket(order, products, discount_types=[], total_discount_options={}):
  66.     ''' Расчёт потребительской корзины '''
  67.  
  68.     basket = {'items': [], 'total': {}}
  69.    
  70.     order_items = defaultdict(list)
  71.    
  72.     # преобразуем список в словарь (по уникальным товарам) - в значениях индексы исходного списка
  73.     for i, item in enumerate(order):
  74.         order_items[item].append(i)
  75.  
  76.     discounts = {}
  77.    
  78.     # вычисляем скидки в порядке следования
  79.     for discount_item in discount_types:
  80.         d_type = discount_item.get('type')
  81.         d_options = discount_item.get('options')
  82.        
  83.         if d_type == 'together':
  84.             discount_together(order_items, discounts, **d_options)
  85.  
  86.         if d_type == 'oneof':
  87.             discount_oneof(order_items, discounts, **d_options)
  88.  
  89.  
  90.     subtotal = 0
  91.  
  92.     # формируем корзину, подсчитываем подитог
  93.     for i, item in enumerate(order):
  94.         price = products[item]
  95.         discount = discounts[i] if i in discounts else 0
  96.         basket['items'].append({
  97.             'product': item,
  98.             'price': price,
  99.             'discount': discount
  100.         })
  101.  
  102.         subtotal+=price*discount
  103.  
  104.     # вычисляем скидку на сумму заказа
  105.     total_discount = order_discount(order_items, **total_discount_options)
  106.  
  107.     basket['total'] = {'subtotal': subtotal, 'discount': total_discount, 'total': subtotal*td}
  108.      
  109.     return basket
  110.  
  111.  
  112.  
  113. def main():
  114.  
  115.     ''' Товары с ценами '''
  116.     products = {
  117.         'A': 100,
  118.         'B': 100,
  119.         'C': 100,
  120.         'D': 100,
  121.         'E': 100,
  122.         'F': 100,
  123.         'G': 100,
  124.         'H': 100,
  125.         'I': 100,
  126.         'K': 100,
  127.         'L': 100,
  128.         'M': 100
  129.     }
  130.  
  131.     ''' Список установленных скидок '''
  132.     discounts = [
  133.         {'type': 'together', 'options': {'products': ['A','B'], 'percent': 0.9 }},
  134.         {'type': 'together', 'options': {'products': ['D','E'], 'percent': 0.95 }},
  135.         {'type': 'together', 'options': {'products': ['E','F','G'], 'percent': 0.95 }},
  136.         {'type': 'oneof', 'options': {'products': ['K','L','M'], 'percent': 0.95 , 'condition': ['A']}},
  137.     ]
  138.  
  139.     ''' Скидки по сумме заказа '''
  140.     total_discount_options = {'ranges': {'3': 0.95, '4': 0.9, '5': 0.8}, 'exclude': ['A','C']}
  141.  
  142.  
  143.     ''' Исходный список товаров в заказе '''    
  144.     myorder = ['A', 'B', 'C', 'K', 'L', 'D', 'D', 'E']
  145.  
  146.     print get_basket(myorder, products, discounts, total_discount_options)
  147.  
  148.  
  149. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement