Skip to content
This repository has been archived by the owner on Oct 27, 2022. It is now read-only.

Commit

Permalink
Merge pull request #4 from kejbaly2/good_luck
Browse files Browse the repository at this point in the history
A few improvements and suggestions - thanks :)
  • Loading branch information
cleder committed Sep 11, 2014
2 parents 5c5fbb9 + a2e6811 commit 2efd77e
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 26 deletions.
9 changes: 8 additions & 1 deletion .gitignore
@@ -1,6 +1,10 @@
# vim swap files
*.sw*

*.py[cod]

# C extensions
*.c
*.so

# Packages
Expand Down Expand Up @@ -33,4 +37,7 @@ nosetests.xml
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
.pydevproject

# Rope
.ropeproject/
44 changes: 21 additions & 23 deletions okfncart/cart.py
Expand Up @@ -3,41 +3,39 @@
#
from . import getproducts


class Cart(object):

def __init__(self, products, offers=None):
self._contents = {}
self._products = products
self._discounts = {}
if not offers:
self._offers=[]
else:
self._offers= offers
def __init__(self, products=None, offers=None):
# products can be added after instance init
# products must be available in _products before they can be
# added to the cart!
self.contents = {} # holds cart content quantities
self._products = products or {} # 'universe' of available products
self._discounts = {} # discounts that have been applied to the cart
self._offers = offers or [] # 'universe' offers that can be applied

def load_products(self, filename):
self._products = getproducts.loadproducts(filename)

@property
def contents(self):
return self._contents
self._products.update(getproducts.loadproducts(filename))

def add(self, product, quantity):
# initialize the product in the basket, this could also be done
# with a collection.defaultdict
if product not in self._contents:
self._contents[product] = 0
self._contents[product] += quantity
# product being added must be available in the available
# _products 'universe'
assert product in self._products
# initialize the product in the basket
self.contents.setdefault(product, 0)
self.contents[product] += quantity

def _add_discount(self, name, price):
self._discounts[name] = price

def get_price(self):
price = 0.0
for content in self.contents.items():
price += self._products[content[0]] * content[1]
self._discounts = {}
for product, qty in self.contents.items():
price += self._products[product] * qty
for offer in self._offers:
# pass in the this cart to the discount class
offer.add_discount(self)
for discount in self._discounts.items():
price += discount[1]
for discount in self._discounts.values():
price += discount
return price
62 changes: 60 additions & 2 deletions okfncart/test_main.py
Expand Up @@ -44,11 +44,24 @@ def test_cartobjject_loadproducts(self):
here = os.path.abspath(os.path.dirname(__file__))
file_name = os.path.join(here, 'tests', 'products.csv')
prods = getproducts.loadproducts(file_name)
my_cart = cart.Cart(None)
self.assertEqual(my_cart._products, None)
my_cart = cart.Cart()
self.assertEqual(my_cart._products, {})
my_cart.load_products(file_name)
self.assertEqual(my_cart._products,prods)

def test_cartobjject_bulk_contents_update(self):
# loadproducts should update, not override products
# passed in on init
here = os.path.abspath(os.path.dirname(__file__))
file_name = os.path.join(here, 'tests', 'products.csv')
prods1 = {'item': 0.1}
prods2 = getproducts.loadproducts(file_name)
prods_all = prods1.copy()
prods_all.update(prods2)
my_cart = cart.Cart(products=prods1)
self.assertEqual(my_cart._products, prods1)
my_cart.load_products(file_name)
self.assertEqual(my_cart._products, prods_all)


class BasicCartTestCase(unittest.TestCase):
Expand All @@ -73,6 +86,21 @@ def test_add_to_cart(self):
my_cart.add('apple', 5)
self.assertEqual(my_cart.contents['apple'], 8)

def test_add_invalid_to_cart(self):
"""
check that we can't add an invalid product to the cart
"""
products = {'snickers bar': 0.7, 'strawberries': 2.0,
'apple': 0.15, 'ice cream': 3.49}
my_cart = cart.Cart(products)

# this should work
my_cart.add('apple', 1)

# but this should raise AssertionError
with self.assertRaises(AssertionError):
my_cart.add('invalid_product', 1)

def test_compute_cart_value(self):
"""
calculate the total cost of the cart
Expand Down Expand Up @@ -175,6 +203,36 @@ def test_20pc_off_snickers_4_mars(self):
self.assertEqual(my_cart.contents['snickers'], 2)
self.assertEqual(my_cart.get_price(),2.6)

def test_multiple_discounts(self):
# changed the price of all products to 1.0 to simplify
products = {'snickers': 1.0, 'strawberries': 1.0, 'mars': 1.0}
my_cart_no_offers = cart.Cart(products)
my_cart_no_offers.add('mars', 1)
my_cart_no_offers.add('snickers', 1)
# should be 2.00 with no offers
self.assertEqual(my_cart_no_offers.get_price(), 2.0)

offer1 = offers.OfferP1p2XpcOff('mars', 'snickers', 0.2)
offer2 = offers.OfferB2g3rdf('strawberries')
my_cart_offers_1 = cart.Cart(products, [offer1])
my_cart_offers_2 = cart.Cart(products, [offer2])
my_cart_offers_both = cart.Cart(products, [offer1, offer2])

my_cart_offers_1.add('mars', 1)
my_cart_offers_1.add('snickers', 1)
# should get 0.20 off
self.assertEqual(my_cart_offers_1.get_price(), 1.8)

my_cart_offers_2.add('strawberries', 3)
# should get 1.00 off (3 strawberries @ 1.00 - 1 strawberry @ 1.00)
self.assertEqual(my_cart_offers_2.get_price(), 2.0)

my_cart_offers_both.add('mars', 1)
my_cart_offers_both.add('snickers', 1)
my_cart_offers_both.add('strawberries', 3)
# should get 0.20 off + 1.00 off (1.20)
self.assertEqual(my_cart_offers_both.get_price(), 3.8)


def test_suite():
suite = unittest.TestSuite()
Expand Down

0 comments on commit 2efd77e

Please sign in to comment.