vkk07
vkk07

Reputation: 79

shopping cart total price in nested dict python

I want to calculate the total price in my shopping cart with the code below, but I am unable to iterate through the price in my items dict. Something is missing there. Also, if the for loop can be fixed, is there any way to iterate using comprehensions?

class ShoppingCart(object):
    def __init__(self):
        self.item = None
        self.quantity = None
        self.price = None
        self.items = {}
    def add(self, item, price, quantity):

        if item in self.items:
            previous_quantity = self.items[item]['quantity']
            previous_price = self.items[item]['price']

            self.items[item] = {'quantity': previous_quantity +   quantity,
                                'price': previous_price + price}
        else:
            self.items[item] = {'quantity':quantity,
                           'price':price}

    def total_items_in_cart(self):
         print(len(self.items))

    def total_items_price_in_cart(self):
         print(sum([price
                 for price in self.items.values()]))

sc = ShoppingCart()
sc.add('book', 30, 1)
# sc.add('book', 132, 1)

sc.add('toothbrush', 4, 10)
# sc.add('toothbrush', 5, 20)

# sc.total_items_in_cart()

cart_price_total = []
for item, value in sc.items.items():
    print("\n{}".format(item))
    for price,qty in value.items():
        print("{} :{}".format(price, qty))
        cart_price_total.append(qty)

print(cart_price_total) # this does not print what I want... 

Is there a way to use comprehensions to get the total value in my cart?

EDIT:

I added the data using a tuple, and it seems simple now. Cannot figure out why...

class ShoppingCart(object):
    def __init__(self):
        self.item = None
        self.quantity = None
        self.price = None
        self.items = {}
    def add(self, item, price, quantity):
        if item in self.items:
            previous_quantity = self.items[item]['quantity']
            previous_price = self.items[item]['price']
            self.items[item] = (previous_quantity+quantity, previous_price+price)
        else:
            self.items[item] = (price, quantity)

    def total_items_in_cart(self):
         return(len(self.items))

    def total_items_price_in_cart(self):
         return(sum([price
                 for price, quantity in self.items.values()]))

sc = ShoppingCart()
sc.add('book', 30, 1)
sc.add('toothbrush', 4, 10)
print(sc.total_items_in_cart())
print(sc.total_items_price_in_cart())

Upvotes: 0

Views: 2237

Answers (3)

Kevin DS.
Kevin DS.

Reputation: 131

Your ShoppingCart Class have price attribute, but you don't use it. You should only use your self.items = {}, you don't use self.item, self.quantity and self.price.

But, for your problem here the solution:

print(cart_price_total) # this does not print what I want...

Yeah but seems like your cart_price_total doesn't contened you're items values... But values AND items count.

Try this:

print(sum([sc.items[x]['price']*sc.items[x]['quantity'] for x in sc.items]))

Upvotes: 0

AGN Gazer
AGN Gazer

Reputation: 8378

I would just define a new instance variable such as _total_price and keep it updated as you add items:

class ShoppingCart(object):
    def __init__(self):
        self.item = None
        self.quantity = None
        self.price = None
        self.items = {}
        self._total_price = 0

    def add(self, item, price, quantity):
        if item in self.items:
            previous_quantity = self.items[item]['quantity']
            previous_price = self.items[item]['price']
            self.items[item] = {'quantity': previous_quantity + quantity,
                                'price': previous_price + price}
        else:
            self.items[item] = {'quantity':quantity, 'price':price}
        self._total_price += price * quantity

    @property
    def total_items_in_cart(self):
        return len(self.items) # better return a value instead of printing it

    @property
    def total_items_price_in_cart(self):
        return self._total_price

sc = ShoppingCart()
sc.add('book', 30, 1)
# sc.add('book', 132, 1)

sc.add('toothbrush', 4, 10)
# sc.add('toothbrush', 5, 20)

print(sc.total_items_in_cart)
print(sc.total_items_price_in_cart)

Of course you will need to deal with the case when user wants to remove an item from the cart.

Upvotes: 1

Ivan Vinogradov
Ivan Vinogradov

Reputation: 4483

Change your total_items_price_in_cart function to this:

def total_items_price_in_cart(self):
    items_prices = {k: v['price'] * v['quantity'] for (k, v) in self.items.items()}
    # items_prices == {'book': 30, 'toothbrush': 40}
    return sum(items_prices.values())

Output with input data in question:

70

Upvotes: 1

Related Questions