Why is compute_bill returning the wrong value?

Question

Why is compute_bill returning the wrong value?

Answer

A common issue here is indenting the return statement inside of the for loop, which causes the loop to only be able to possibly run one time before the function returns and exits.
If your code looks something like the code below, unindent your return statement to be on the same level as the for, not inside of it.

for item in my_list:
  my_var += 10
  return my_var
4 Likes

I have been struggling with this the last few exercises so I figured I’d post. How do you determine how you define “things” in lists/dictionaries when it comes to loop statements? For example, the solution for this problem says " for item in food". How did you come to the conclusion of using the term item? In previous examples, “for food in prices” was used. How was it determined “food” should be used? Thanks.

7 Likes

the for in loop (for variable in list) declares (names) a variable within the for loop, you are free to pick your own variable names, except for the reserved words in a programming language

however, its recommend to give variable logic/descriptive names. This is something that comes with time and experience.

Whoever wrote the course decided on the variable names used, because (s)he thought these names fitted best.

I also have a question on this exercise. My code (below) is coming back rejected.

def compute_bill(food):
  total = 0 
  for p in prices:
    total += prices[p]
  return total

The tip below the output says
compute_bill(['apple']) returned 10.5 instead of 2

Wasn’t the point of the exercise to compute all of the food items on the list (Which would give us $10.50). It doesn’t make sense that the computer is trying to pass ‘apple’ as an argument through this function since we already know its price is $2.

Please help. Thanks.

1 Like

no, the point of this exercise was to make a function which could calculate the total cost of a customer purchase.

that is why the function has a parameter, so we can test different “customers” (by passing various shopping lists as argument on function call)

1 Like

This is what I came up with and it passed:


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

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

def compute_bill(food):
  total = 0
  for item in food:
    total += prices[item]
  return total

print compute_bill(shopping_list)

From my understanding, we’re to assume the customer only wants 1 of each item on their list. 7.5 was printed to my console, which equals the combined cost of 1 apple, 1 orange and 1 banana as defined in the dictionaries.

Did you change the values of the keys in your dictionaries? These lessons don’t take kindly to mutations in the provided code, or the use of definitions aside from the ones provided in the lesson outline.

Your function looks essentially identical to mine, so I don’t imagine that’s the problem.

12 Likes

we could add multiply function calls to represent different customers:

print compute_bill(shopping_list)
print compute_bill(['pear', 'apple'])
print computer_bill(['pear', 'pear', 'pear', 'orange', 'orange'])

no, there is a one difference between your and kmonroe25 code. Study the for loop closely. He is looping over prices, and not using his food parameter. So if you run his code and add a bunch of function calls you will see the function always returns 8.5, regardless of what customer (function call) wants to buy

2 Likes

The source of the confusion is in the instructions. You are told to add the value of each item in “the food list” to your total variable. There are two dictionaries and a shopping list already included in the provided code. None of them are identifiable as a “food list”.

The problem with this is that we aren’t supposed to use a ‘list’ at all, despite the fact that this module is dealing with Python lists and dictionaries. The exercise intends for us to use an argument named “food” as input in our “compute_bill” function, and to pull only from the “prices” dictionary provided. No list is used in this function.

It seems a few people are being misled by this use of the term list in the instructions to total everything in the food list, instead of just being told to use a function with the argument “food” to total everything in the “prices” dictionary.

14 Likes

In fact there is a list, and you already mentioned it… shopping_list, which we are to pass to the compute_bill function.

print (compute_bill(shopping_list))

Inside the function, food is that list.

Not so. We are not totalling everything in the prices dictionary, but using the dictionary to look up prices of items in the food list.

The lessons up to this one are teaching how to create lists, perform basic manipulation of lists, and understand the differences between lists and dictionaries. A person without prior experience in programming who reaches this lesson is unprepared for what they will perceive as a shift in terminology.

The instruction offered up to this point teaches a student to see [1, 2, 3, 4] as a list. When the instructions say “food list”, they will look for a variable “food” followed by integers or strings in brackets. This is what they have been taught to do by the prior lessons.

I understand a food list is created in the function. The lessons in this module, however, do not make this clear.

Also, when I pulled the solution to this exercise it did not take the shopping list as an argument when it called the compute_bill function. The solution provided the sum of one item each of the four fruits in the prices dictionary, not the sum of the prices for the three items included in the solution’s shopping_list.

I agree you provided the correct answer to the presented instructions. Unfortunately, the module did not count that answer as correct. So either the key was incorrect, or the instructions were unclear.

7 Likes

The food list is given to us at the top of the code… shopping_list. Clearly we can see it is a list so I don’t quite get the confusion. However, I do see your point about how learners expect things to be literal, rather than implied or suggested. More than a few people have stumbled over this question but that is why we have this forum. We can help clarify the question, but are not in a position to argue whether the instructions are clear or not. It won’t change anything. Best we just clear things up, make the most of it and move on.

Self study implies that we will reach for other resources as we learn. It only makes sense that a simple course is going to miss out on a lot of the details. We can discover them by reading the documentation on each new concept and at the same time increase our knowledge base of the available methods on that class of object.

Lists and dictionaries have a lot of methods associated with them. We use only a handful here, but extra study and practice will help grow one’s toolkit to include other methods not taught here.

2 Likes

3 posts were split to a new topic: Compute_bill gives wrong output

It would be nice if in the instructions, it would actually say what we’re trying to make here, because the example with a given list at the end was completely misleading, and having the instructions be listed step-by-step when in reality, half of the instructions is implied, is just bad lesson planning. “The point of this exercise was to make a function which could calculate the total cost of a customer purchase.” That’s all that needed to be said.

2 Likes

The lesson does mention this:

Great work! Now we’re going to take a step back from the management side and take a look through the eyes of the shopper.

In order for customers to order online, we are going to have to make a consumer interface. Don’t worry: it’s easier than it sounds!

Taking the time to read information about an exercise, processing and understand what this means is vital part of the learning process.

link to exercise

1 Like
  1. Define a function compute_bill that takes one argument food as input.

In the function, create a variable total with an initial value of zero.

For each item in the food list, add the price of that item to total .

Finally, return the total .

Ignore whether or not the item you’re billing for is in stock.Note that your function should work for any food list.

These are the instructions that list everything you need to do, except why you’re doing it. Anyone following the instructions have no idea what to tweak to make it work if we’re not clear what we’re trying to do. On top of that, how are we, up to this point, supposed to know Python is capable of understanding imaginary scenarios? jturneraudit is right because I WAS looking for ‘food’ and wondering where the program was pulling a for loop from. Even after seeing the solution, I did not understand what ‘food’ meant or what it was an argument for, until realizing it is the supposed shopping list of a customer.

The instructions try too hard to be concise that it lacks a lot of vital information, and are so literal anyone following will just try to follow the instructions word-for-word and not understand why their program is missing something, meanwhile not getting the bigger picture. You can’t take the time to read the exercise if there isn’t any information. Even the example just says the ‘n’ list runs through the function without explaining why ‘n’ exists and why anyone is trying to run it through the function.

1 Like

because this was mentioned in the previous lesson, and this lesson was a continuation of the previous lesson

you are not, but understanding parameters and arguments is quite vital. Which has been taught. Its okay to revisit earlier lessons or documentation if you do not precisely remember.

taking time to understanding what you are building, where all the different pieces come in is vital for skill for programmer.

It seems a great many people do not recognize the shopping_list as being the list item to pass to the function for this exercise. It is the food list the instructions refer to.

2 Likes

Yes that was an issue. How does Python recognize ‘food’ argument as ‘shopping_list’ if they are two completely different names, and how were we not supposed to assume otherwise? Would inserting ‘shopping_list’ as argument instead of ‘food’ yield the same solution? Does Python just recognize them? Because the ambiguity only makes Python even more hard to grasp from these lessons. I’ve moved on but these are some things I haven’t understood yet.

1 Like

The food parameter is given the shopping_list argument when we call the function.

print (compute_bill(shopping_list))
                      <argument>

def compute_bill(food):
              <parameter>

The variable food is a local name given to whatever list is passed in. The instructions say it should accept any list so we have to use a different name than the one given to the global object.

Try it and see.

def compute_bill(shopping_list):

Now pass in a list,

print (compute_bill(['apple', 'pear', 'orange']))

Make the list slightly different from the original shopping_list and see if the total is different. If it is, then that means the local variable is not the same object as the global one.

The original list returns 5.5, and the substituted list returns 4.5 so that would indicate there is no conflict between the local variable and global variable. Still, it is more meaningful to the reader if the local variable has a unique name.

2 Likes

def compute_bill(food):
total = 0
for item in food:
total += prices[item]
return total

print compute_bill(shopping_list)

this was accepted, I guess my problem was how to compare the list in the dictionary. I tried to
if prices[key] == item
total += prices[key]
trying to check to see if it was there to prevent an error, which seemed Seemed inevitable because we were asked to make this available’s list. So I was trying to figure out how to check against the dictionary not coming up with an error. I was trying to call me each item in price checking against what would be in the list. For some reason I wasn’t able to don’t know howTo make sure that item on a customer’s list was in the prices dictionary. The other issue I had was that if I call the prices dictionary and put item with in it
prices[item]
Mentally this seems wrong because the word item isnt in the dictionary of prices. I would more expect to all these themselves and check against what’s on the list. For some reason I must’ve missed that if you iterate through a list and use that value term [and dictionary brackets that your comparing or querying or looking for the item in the dictionary. Some reason I didn’t see that possibility. But since this worked and I found it somewheres else on the web trying to find the answer to this. I know I don’t really understand it could just appreciate someone explaining why and a list work when calling dictionary. Actually as I’m writing I’m starting to understand that the parameter is being given and we know that it’s actually prices which is why it will work. So so somebody correct me if I’m wrong the iteration is being placed into the parameter of the dictionary so that it can call the price of that item. I I guess the problem with that in my mind was that we didn’t know what was on the list and I’m assuming that everyone was this would be different and might not contain items dictionary. In my effort to prevent an error from occurring from a possible list that might contain items not on the dictionary confuse myself wondering about how to check against the key values in the dictionary against the list and thought that I should be pulling keys instead of assuming every list would have items that would have been been in the dictionary. This is my first language that I’m learning so maybe this is a common thing along other languages. Guessing if we’re going to assume that every list is only going to contain items in the dictionary it’s limited contain that only contain items in the dictionary. I guess the words that it can be used for “any list” threw me off me off and made me want to prevent errors or lists that don’t contain items in the dictionary.

1 Like