Back to the Checkout
A solution to Back to the Checkout kata described at CodeKata.
Solution
""" checkout.py """
# usage: python3 checkout.py
class Checkout():
""" simulate a checkout """
def __init__(self, pricing_rules):
self.pricing = pricing_rules
self.goods = {}
def scan(self, item):
""" add item to purchases """
self.goods[item] = self.goods.get(item, 0) + 1
def price(self, goods):
""" total price of goods """
self.goods = {}
for item in goods:
self.scan(item)
return self.total()
def total(self):
""" total price of self.goods """
total = 0
for item, purchased_qty in self.goods.items():
pricing = self.pricing[item]
remaining_qty = purchased_qty
for qty, price in sorted(pricing, reverse=True):
while remaining_qty > 0:
if remaining_qty >= qty:
remaining_qty -= qty
total += price
else:
break
return total
if __name__ == '__main__':
prices = {'A': [(1, 50), (3, 130)],
'B': [(1, 30), (2, 45)],
'C': [(1, 20)],
'D': [(1, 15)]}
co = Checkout(prices)
assert co.price('') == 0
assert co.price('A') == 50
assert co.price('AB') == 80
assert co.price('CDBA') == 115
assert co.price('AA') == 100
assert co.price('AAA') == 130
assert co.price('AAAA') == 180
assert co.price('AAAAA') == 230
assert co.price('AAAAAA') == 260
assert co.price('AAAB') == 160
assert co.price('AAABB') == 175
assert co.price('AAABBD') == 190
assert co.price('DABABA') == 190
co = Checkout(prices)
assert co.total() == 0
co.scan('A')
assert co.total() == 50
co.scan('B')
assert co.total() == 80
co.scan('A')
assert co.total() == 130
co.scan('A')
assert co.total() == 160
co.scan('B')
assert co.total() == 175
print('tests passed')