HeKe
HeKe

Reputation: 41

OOP in python programming

Hello guys am kind of new to programming in python language and was hoping if I get assistance from you. The question is this:

  1. Create a class called ShoppingCart.

  2. Create a constructor that takes no arguments and sets the total attribute to zero, and initializes an empty dict attribute named items.

  3. Create a method add_item that requires item_name, quantity and price arguments. This method should add the cost of the added items to the current value of total. It should also add an entry to the items dict such that the key is the item_name and the value is the quantity of the item.

  4. Create a method remove_item that requires similar arguments as add_item. It should remove items that have been added to the shopping cart and are not required. This method should deduct the cost of the removed items from the current total and also update the items dict accordingly.

  5. If the quantity of an item to be removed exceeds the current quantity of that item in the cart, assume that all entries of that item are to be removed.

  6. Create a method checkout that takes in cash_paid and returns the value of balance from the payment. If cash_paid is not enough to cover the total, return "Cash paid not enough".

  7. Create a class called Shop that has a constructor which takes no arguments and initializes an attribute called quantity at 100. Make sure Shop inherits from ShoppingCart.

  8. In the Shop class, override the remove_item method, such that calling Shop's remove_item with no arguments decrements quantity by one

And here is my code

class ShoppingCart(object):

    def __init__(self):
        self.total = 0
        self.items = dict()

    def add_item(self, item_name, quantity, price):
        if item_name != None and quantity >= 1:
            self.items.update({item_name: quantity})
        if quantity and price >= 1:
            self.total += (quantity * price)

    def remove_item(self, item_name, quantity, price):
        self.total -= (quantity * price)
        try:
            if quantity >= self.items[item_name]:
                self.items.pop(item_name, None)
            self.items[item_name] -= quantity
        except(KeyError, RuntimeError):
            pass

    def checkout(self, cash_paid):
        balance = 0
        if cash_paid < self.total:
            return "Cash paid not enough"
        balance = cash_paid - self.total
        return balance


class Shop(ShoppingCart):

    def __init__(self):
        self.quantity = 100

    def remove_item(self):
        self.quantity -= 1

And the unittest

import unittest;

class Test(unittest.TestCase):
    def setUp(self):
        self.cart = ShoppingCart()
        self.shop = Shop()

    def test_cart_property_initialization(self):
        self.assertEqual(self.cart.total, 0, msg='Initial value of total not correct')
        self.assertIsInstance(self.cart.items, dict, msg='Items is not a dictionary')

    def test_add_item(self):
        self.cart.add_item('Mango', 3, 10)
        self.assertEqual(self.cart.total, 30, msg='Cart total not correct after adding items')
        self.assertEqual(self.cart.items['Mango'], 3, msg='Quantity of items not correct after adding item')

    def test_add_item_hidden(self):
        self.cart.add_item('Mango', 3, 10)
        self.cart.add_item('Orange', 16, 10)
        self.assertEqual(self.cart.total, 190, msg='Cart total not correct after adding items')
        self.assertEqual(self.cart.items['Orange'], 16, msg='Quantity of items not correct after adding item')

    def test_remove_item(self):
        self.cart.add_item('Mango', 3, 10)
        self.cart.remove_item('Mango', 2, 10)
        self.assertEqual(self.cart.total, 10, msg='Cart total not correct after removing item')
        self.assertEqual(self.cart.items['Mango'], 1, msg='Quantity of items not correct after removing item')

    def test_remove_item_hidden(self):
        self.cart.add_item('Mango', 3, 10)
        self.cart.add_item('Orange', 16, 10)
        self.cart.remove_item('Mango', 2, 10)
        self.assertEqual(self.cart.total, 170, msg='Cart total not correct after removing item')
        self.assertEqual(self.cart.items['Mango'], 1, msg='Quantity of items not correct after removing item')
        self.cart.remove_item('Mango', 2, 10)
        self.assertEqual(self.cart.total, 160, msg='Cart total not correct after removing item')
        with self.assertRaises(KeyError):
            self.cart.items['Mango']

    def test_checkout_returns_correct_value(self):
        self.cart.add_item('Mango', 3, 10)
        self.cart.add_item('Orange', 16, 10)
        self.assertEqual(self.cart.checkout(265), 75, msg='Balance of checkout not correct')
        self.assertEqual(self.cart.checkout(25), 'Cash paid not enough', msg='Balance of checkout not correct')


    def test_shop_is_instance_of_shopping_cart(self):
        self.assertTrue(isinstance(self.shop, ShoppingCart), msg='Shop is not a subclass of ShoppingCart')

    def test_shop_initializaton(self):
        self.assertEqual(self.shop.quantity, 100, msg='Shop quantity not initialized correctly')

    def test_shop_remove_item_method(self):
        for i in range(15):
            self.shop.remove_item()

        self.assertEqual(self.shop.quantity, 85)

Now after running the unitest am getting this error message:

"150 != 160 : Cart total not correct after removing item"

Anyone willing to help please will appreciate any guidelines.

Upvotes: 0

Views: 1323

Answers (4)

Joshua
Joshua

Reputation: 1

This should work fine

class ShoppingCart(object):

    def __init__(self):
        self.total = 0
        self.items = dict()

    def add_item(self, item_name, quantity, price):
        if item_name != None and quantity >= 1:
            self.items.update({item_name: quantity})
        if quantity and price >= 1:
            self.total += (quantity * price)

    def remove_item(self, item_name, quantity, price):
        try:
            if quantity >= self.items[item_name]:

                self.total -= (self.items[item_name] * price)
                self.items.pop(item_name, None)

            else:
              self.items[item_name] -= quantity
              self.total -= (quantity * price)
        except IOError:
            print
            "Error: can\'t find file or read data"

    def checkout(self, cash_paid):
        balance = 0
        if cash_paid < self.total:
            return "Cash paid not enough"
        balance = cash_paid - self.total
        return balance


class Shop(ShoppingCart):   
    def __init__(self):
        self.quantity = 100

    def remove_item(self):
        self.quantity -= 1

Upvotes: 0

omokehinde igbekoyi
omokehinde igbekoyi

Reputation: 1016

The problem is with your add_item method you are not updating the item so each time you add the same item it doesn't update it just resigns the item_name and quantity again and forgets about the previous values so this is what your add_item method should look like:

def add_item(self, item_name, quantity, price):
    self.total += price*quantity
    self.items.update({item_name: quantity})

Upvotes: 0

Shaun
Shaun

Reputation: 109

Looks like in the remove_item class attribute, you update the total value of the cart prior to determining if you are removing more items then you have.

If you modify it so you check the item quantity first and then subtract the total number available if less than the total number wanted to be removed... it should fix the problem

def remove_item(self, item_name, quantity, price):
    try:
        if quantity >= self.items[item_name]:

            self.total -= (self.items[item_name] * price)
            self.items.pop(item_name, None)
        else:
            self.items[item_name] -= quantity
            self.total -= (quantity * price)

Upvotes: 2

BoarGules
BoarGules

Reputation: 16942

Your test is wrong. Here your code checks that the cart total is 170 cash:

self.assertEqual(self.cart.total, 170, msg='Cart total not correct after removing item')

Then it removes 2 items at 10 cash each:

self.cart.remove_item('Mango', 2, 10)

Then it checks to see if there is 160 cash remaining:

self.assertEqual(self.cart.total, 160, msg='Cart total not correct after removing item')

but it hasn't, it has 150 cash, which is what anyone would expect (170 - 20 = 150).

Upvotes: 0

Related Questions