Proposition for another solution to Stocking Out/Potential Bug


#1

The following code is not accepted as an answer to Stocking Out.

stock = {
    "banana": 6,
    "apple": 0,
    "orange": 32,
    "pear": 15
}
    
prices = {
    "banana": 4,
    "apple": 2,
    "orange": 1.5,
    "pear": 3
}
print ()
print (stock)
print ()
shopping_list = ["banana", "orange", "apple"]
def compute_bill(food):
    total = 0
    for item in food:
        if stock[item] > 0:
            total += prices[item]
            stock[item] = stock[item]-1
    return total
    
done = compute_bill(shopping_list)
print ("Total: %s" % done)
print ()
print (stock)

Despite the fact that python3 on a bash terminal results in the following output:

{'orange': 32, 'banana': 6, 'pear': 15, 'apple': 0}

Total: 5.5

{'orange': 31, 'banana': 5, 'pear': 15, 'apple': 0}

codeacademy does not accept this code as an answer.

I am aware print () is unnecessary for Python 2, but that is not too important for the sake of this exercise. print and print () should be accepted especially since print requires parenthesis now.

Another reason I have posted this is to call to attention a strange problem with this assignment. If the code is posted in this order:

stock = {
    "banana": 6,
    "apple": 0,
    "orange": 32,
    "pear": 15
}
    
prices = {
    "banana": 4,
    "apple": 2,
    "orange": 1.5,
    "pear": 3
}
shopping_list = ["banana", "orange", "apple"]
def compute_bill(food):
    total = 0
    for item in food:
        if stock[item] > 0:
            total += prices[item]
            stock[item] = stock[item]-1
            print stock[item]
    return total
    
done = compute_bill(shopping_list)
print done

It is deemed wrong. However simply changing the order of the code results in a correct answer.
(Like this):

shopping_list = ["banana", "orange", "apple"]
def compute_bill(food):
    total = 0
    for item in food:
        if stock[item] > 0:
            total += prices[item]
            stock[item] = stock[item]-1
            print stock[item]
    return total
    
done = compute_bill(shopping_list)
print done

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

In Python3, both my solution and the solution accepted by codeacedemy do not react the same way to this reordering.

I have posted this here because I think the developers who are in charge of bugs should look at this.
Link to question


#2

Ok, why does having this before your dictionary work but not after?:

shopping_list = ["banana", "orange", "apple"]
def compute_bill(food):
    total = 0
    for item in food:
        if stock[item] > 0:
            total += prices[item]
            stock[item] = stock[item]-1
            print stock[item]
    return total
    
done = compute_bill(shopping_list)
print done

Because of this: done = compute_bill(shopping_list)
When you do that, you change the level of the stock, so when the STC calls your function the stock levels are wrong.

You see, what the SCT does is not run your script and just look at the output, it imports your function from your script.
When you import a module in python, python will run that entire module before you can use anything, so before the SCT can even call compute_bill() python has run done=compute_bill(shopping_list) and changed the value in the stock dictionary.

So having stock afterward stops this from happening (it cannot run done = compute_bill(shopping_list) because stock and prices don't exist yet as they haven't been loaded), even if it did overwrite stock, you define stock to being back to what it should be afterward.

This is the same reason your first attempt doesn't work too. To avoid this, this is why you may have seen:

if __name__ == "__main__":
   # Do something that won't get run if the module is imported.

The reason for this is that when the module is loaded it will get given a property__name__. If you are running the module directly __name__ will equal "__main__". However, if you are importing it, __name__ will equal the modiules file name. Try using it on your code and seeing how it stops the compute_bill(shipping_list) running.

Just so you know, the () after print isn't unncessary in python 2, it actually changes how print handles what you input. It's the same as putting everything in a second set of () in python 3.x print function

>>> # Python 2.x
>>> print ("test")
test

>>> print ("test",1,"test")
('test', 1, 'test')

>>> print "test", 1, "test"
test 1 test

>>> type(print)
SyntaxError: invalid syntax

>>> # Python 3.x
# How to get the Python 3.x print functionality in Python 2.x
>>> from __future__ import print_function

>>> print ("test")
test

>>> print (("test"))
test

>>> print(("test",1, "test"))
('test', 1, 'test')

>>> print("test", 1,"test")
test 1 test

>>> type(print)
<type 'builtin_function_or_method'>

#3

Thanks for the detailed breakdown.

I mean I know the () isn't unnecessary, but I left it there because Python3 is more relevant outside of Codeacademy.


#4

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.