2

I have two dictionaries which I need to multiply and get the total of, both with the same keys (I need the total of the stock and price of some items).

# Create a list "menu" with 4 items
menu = ["sandwich", "burger", "fish", "chips"]
# Create a dictionary "stock" with the stock value for each item in the menu
stock = {"sandwich" : 6, "burger" : 5, "fish" : 6, "chips" : 10}
# Create a dictionary "price" with the price for each item in the menu
price = {"sandwich" : 4.50, "burger" : 6.00, "fish" : 6.50, "chips" : 3.50}

# Get the values from stock and price for each menu item and multiply by eachother
for key in price:
    menu_stock = price[key] * stock[key]
    # Get the sum of these values
    total_stock_worth = sum(menu_stock)

# Print statement with the calculated total stock worth
print("The total stock worth is £" + str("{:.2f}".format(total_stock_worth)))

I get the error message (for line 12: total_stock_worth = sum(menu_stock)): TypeError: 'float' object is not iterable

The output I'm after is: The total stock worth is £131.00

mandykg
  • 33
  • 4

4 Answers4

1

menu_stock (in your loop) stores float value while sum function requires its argument to be an iterable.
So you need to accumulate all products of price*stocks before calculating their sum.

RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • Thanks, I am new to Python so still learning. How do I accumulate the products so they are iterable? – mandykg Jan 03 '23 at 15:01
  • @mandykg, simply with `total_stock_worth = sum(price[k] * stock[k] for k in price)` - generating accumulated iterable on the fly – RomanPerekhrest Jan 03 '23 at 15:06
0

To compute the total_stock_worth try:

# Create a list "menu" with 4 items
menu = ["sandwich", "burger", "fish", "chips"]
# Create a dictionary "stock" with the stock value for each item in the menu
stock = {"sandwich": 6, "burger": 5, "fish": 6, "chips": 10}
# Create a dictionary "price" with the price for each item in the menu
price = {"sandwich": 4.50, "burger": 6.00, "fish": 6.50, "chips": 3.50}

# Get the values from stock and price for each menu item and multiply by eachother
total_stock_worth = sum(price[m] * stock[m] for m in menu)

# Print statement with the calculated total stock worth
print("The total stock worth is £" + str("{:.2f}".format(total_stock_worth)))

Prints:

The total stock worth is £131.00
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
0

The sum function work with iterable ex: list, set etc.. In your code menu_stock is a float not an iterable. To solved your problem declare menu_stock as a list and append the product of each of the stock and price to it. After the loop, call the sum function to calculate the total_stock_worth.

Also you don't need to call the str() method format() does that automatically for you.

Solution

# Create a list "menu" with 4 items
menu = ["sandwich", "burger", "fish", "chips"]
# Create a dictionary "stock" with the stock value for each item in the menu
stock = {"sandwich" : 6, "burger" : 5, "fish" : 6, "chips" : 10}
# Create a dictionary "price" with the price for each item in the menu
price = {"sandwich" : 4.50, "burger" : 6.00, "fish" : 6.50, "chips" : 3.50}

# declare menu_stock as list
menu_stock = []

# Get the values from stock and price for each menu item and multiply by eachother
for key in price:
    menu_stock.append(price[key] * stock[key])
    # Get the sum of these values
total_stock_worth = sum(menu_stock)

# Print statement with the calculated total stock worth
print("The total stock worth is £{:.2f}".format(total_stock_worth))
Maxwell D. Dorliea
  • 1,086
  • 1
  • 8
  • 20
  • Amazing this has worked! Thank you so much! – mandykg Jan 03 '23 at 15:04
  • I dislike the recommendation from this answer. Either use `sum` directly with a generator-expression: `total_stock_worth = sum(price[key] * stock[key] for key in price)` or do not use `sum` at all and use a loop to add the values manually: `total_stock_worth=0; for key in price: menu_stock = price[key] * stock[key]; total_stock_worth += menu_stock`. But doing a mix of both and maintaining a list just to finally sum its item is very counterintuitive, and also less efficient, both in time and in space. – Stef Jan 03 '23 at 17:22
  • @Stef This code time complexity is ```O(n)```. Can we do better than this? – Maxwell D. Dorliea Jan 03 '23 at 18:53
  • @MaxwellD.Dorliea Your code builds a list of length `n`, when no list is needed. So in terms of space complexity, yes, we easily can do better than this. – Stef Jan 04 '23 at 10:26
  • @Stef I know for space complexity we can do better but I was only trying to correct the mistake make by the user that ask the question. I didn't wanted to change the whole code but fixed the error. I also wanted him to understand what I did. Moreover him didn't ask for reducing the space complexity. I'm sure him don't have much to do with that for now. Anyways thanks for the suggestion Sir. I really appreciate it. – Maxwell D. Dorliea Jan 04 '23 at 13:41
0

You have two options:

  • Use a for-loop, and increment total_stock_worth with +=; or
  • Use sum( ) with a generator-expression.

In your code you tried to mix both, and it fails for two reasons:

  • you call sum on a single value instead of a sequence of values;
  • every time you write total_stock_worth = ... you erase the previous value stored in total_stock_worth.

Below, the two options:

# Create a list "menu" with 4 items
menu = ["sandwich", "burger", "fish", "chips"]
# Create a dictionary "stock" with the stock value for each item in the menu
stock = {"sandwich" : 6, "burger" : 5, "fish" : 6, "chips" : 10}
# Create a dictionary "price" with the price for each item in the menu
price = {"sandwich" : 4.50, "burger" : 6.00, "fish" : 6.50, "chips" : 3.50}

# OPTION 1: USE A FOR-LOOP AND INCREMENT MANUALLY
total_stock_worth = 0
for key in price:
    menu_stock = price[key] * stock[key]
    total_stock_worth = total_stock_worth + menu_stock

print("The total stock worth is £{:.2f}".format(total_stock_worth))

# OPTION 2: USE SUM() WITH A GENERATOR-EXPRESSION
total_stock_worth = sum(price[key] * stock[key] for key in price)

print("The total stock worth is £{:.2f}".format(total_stock_worth))

With both options the output is the same:

The total stock worth is £131.00

As a matter of personal preference, you can replace:

total_stock_worth = total_stock_worth + menu_stock

with:

total_stock_worth += menu_stock

where += can be read as "increment by"; those two lines are really equivalent.

Stef
  • 13,242
  • 2
  • 17
  • 28