11. Making a purchase, code returns wrong total


#1



https://www.codecademy.com/en/courses/python-beginner-en-IZ9Ra/2/2?curriculum_id=4f89dab3d788890003000096

When I run the code I receive the following error message:
Oops, try again. compute_bill(['apple']) returned 10.5 instead of 2


I looked through the history of people having issues on this lesson and I think that CA may have changed the requirements slightly. The instructions say: " Ignore whether or not the item you're billing for is in stock." There were some previous posts where people tried to only calculate the total of items in stock (maybe this applies to a later exercise in the lesson.

So my question is why when we run compute_bill(['apple']) does the function add all of the prices in the prices dictionary instead of only the price for the apple? As I understand, that trial command would look for the key:value pair that is associated with apple in the dictionary 'prices', and add only that value to total.

Thank you!


shopping_list = ["banana", "orange", "apple"]

stock = {
    "banana": 6,
    "apple": 0,
    "orange": 32,
    "pear": 15
}
    
prices = {
    "banana": 4,
    "apple": 2,
    "orange": 1.5,
    "pear": 3
}

# Write your code below!
def compute_bill(food):
    total = 0
    for food in prices:
        total += prices[food]
    return total


#2

lets look at your function declaration:

def compute_bill(food):

food is the function argument, which means when you call the function the pass in the list with the items you want to buy, which means you want to iterate over food:

for item in food:

and then add that item to the total cost:

total += prices[item]

#3

Thank you!

It's funny how this seems so obvious once I've written it out correctly.

For any other beginners, I was trying to figure out why my old version didn't work. As stetim94 explains above, if our argument is (food), then we want to iterate over food. As you can see in my original (incorrect) code above, the for loop iterates over (prices).

I still felt that should have worked. If we run compute_bill('apple'), it seems like we are iterating over prices, but only for the value 'apple', so I expect the answer '2' not '10.5'.

The problem can be seen by rewriting the code another way. If I change the argument of the function to something else entirely, we will get the same wrong answer '10.5' like this:

shopping_list = ["banana", "orange", "apple"]

stock = {
    "banana": 6,
    "apple": 0,
    "orange": 32,
    "pear": 15
}
    
prices = {
    "banana": 4,
    "apple": 2,
    "orange": 1.5,
    "pear": 3
}

# Write your code below!
def compute_bill(x):
    total = 0
    for food in prices:
        total += prices[food]
    print total
    return total
compute_bill('apple')

So even if the argument isn't (food), the function still will iterate over each (food) in (prices). In fact, if you compute_bill('arbitrary_string'), you will STILL get 10.5.

If this is obvious to everyone else then forgive me, but I'm hoping that a beginner's explanation might help another beginner.

Thanks again for the help!


#4

You do understand my explanation?

no, if you loop over prices you will loop over the entire dictionary, no matter what you pass as parameter when you call the function, the result is always going to be 10.5:

def compute_bill(x):
    total = 0
    for food in prices:
        print prices, prices[food]
        total += prices[food]
    print total
    return total
compute_bill('apple')

i added a print statement, as you can see, it is clearly looping over the dictionary. Which means you will always get 10.5, that is not the purpose of the function.

if you plan on calling the function with a single item, it should still be a list:

compute_bill(['apple'])

a for in loop on a string with iterating over each letter. That is never going to work


#5

I did understand your explanation. My last post was pointing out the same thing that you said: That if you loop over prices, the result will be 10.5

Running compute_bill('apple') was another example to show that we could get 10.5 from another result because we are still looping over prices. I understand that this is not the right answer.