Nick_M
Nick_M

Reputation: 17

why doesn't loop break at 0 count when I set while var != 0

I'm writing a program for my class, the program is to enter the item you want to buy online, then the price. I created a while loop that should break once the total items the user is buying gets to zero, that way I can take in all the items they want. For some reason though when the variable totalItems hits zero (and i know it is because I'm printing it out every line) the loop does not break, in fact it keeps going into the negatives.

def main():
    totalItems = int(input('How many items are you buying? '))
    while totalItems != 0:
        item1 = input('What is the first item? ')
        cost1 = input('What is the price of the first item? ')
        totalItems = totalItems - 1
        print(totalItems)
        item2 = input('What is the second item? ')
        cost2 = input('What is the price of the second item? ')
        totalItems = totalItems - 1
        print(totalItems)
        item3 = input('What is the third item? ')
        cost3 = input('What is the price of the third item? ')
        totalItems = totalItems - 1
        print(totalItems)
        item4 = input('What is the fourth item? ')
        cost4 = input('What is the price of the first item? ')
        totalItems = totalItems - 1
        print(totalItems)
        item5 = input('What is the first item? ')
        cost5 = input('What is the price of the first item? ')
        totalItems = totalItems - 1
    print('done')


main()

Upvotes: 0

Views: 1032

Answers (5)

Trenton McKinney
Trenton McKinney

Reputation: 62403

In this case, I would use a for-loop:

  • A while-loop is better for continuous operation, until a given condition occurs.
  • A for-loop is better for looping through a range or list of values.
  • There is no need to hardcode for each item. What if there are 100 items?
  • The while-loop in your code doesn't work, because python is sequential and the sequence of your code proceeds from item1 through item5. while != 0: is not evaluated again until after cost5.
    • Additionally, if the initial value of totalItems is <= 3, totalItems will be < 0 before the while condition is reevaluated. In this case, the loop will go on forever.
  • Always reuse code, if possible
  • product & cost are now in a dict returned by the function
def main():
    totalItems = int(input('How many items are you buying? '))
    item_dict = dict()
    for item in range(1, totalItems + 1):
        product = input(f'What is item {item}? ')
        cost = input(f'What is the price of item {item}? ')
        item_dict[f'item_{item}'] = {'product': product, 'cost': cost}
    print('done')
    return item_dict

items = main()

Output:

How many items are you buying?  4
What is item 1?  Book
What is the price of item 1?  7.50
What is item 2?  Car
What is the price of item 2?  15000
What is item 3?  Milk
What is the price of item 3?  6.99
What is item 4?  Coffee
What is the price of item 4?  4.99
done

Stored items:

print(items)

Output:

{'item_1': {'product': 'Book', 'cost': '7.50'},
 'item_2': {'product': 'Car', 'cost': '15000'},
 'item_3': {'product': 'Milk', 'cost': '6.99'},
 'item_4': {'product': 'Coffee', 'cost': '4.99'}}

Upvotes: 0

David Fisher
David Fisher

Reputation: 299

Python's Truth table: "any non-zero number is truth". This means while totalItems: is good.

A for loop might be better suited for what exactly you need.

for item_counter in range(total_items): # do stuff

This will stop once the you have gone from 0 to total_items. This has the added bonus of not needing to track everything yourself.

You can format a string that you're printing to the user.

item = input('Item {}: '.format(item_counter))  # Item 1:
cost = input('How much did {} cost? '.format(item))  # How much did The Internet cost?

If you're hoping to have something clever for the "first", "second", "third", etc. items you'll need to map them, but since the that would require infinite amount of typing, giving the numerical representation is typically easier. 101,102,103,104,105,106,107,108,109,110,111,112,113,220,330,440,550,660,770,880,990 And you've only made it to one hundred one novemdecillionth (ish) item.


To expand on dictionaries dict You could also assign the item to be in the dictionary.

products = dict{}
for loop:
  item = ...
  if item not in products:
    cost = ...
    product[item] = cost

And what this will do is save items which have the gmo free certified organic no added sugar no trans-fat diet water's price so if the user need multiple copies of the item, they would only have to add the cost once. Expanding on this, you can count the number of times the item has been added.

...
      product[item] = [cost, 1]
    else:
      product[item][1] += 1

product[item] refers to the value which is the list [cost, count]. We need to modify the second index so we specify [1] because we start counting at 0. The end result looks a tad confusing but ultimately we keep track of how many duplicate items are added as well.

Upvotes: 0

RemcoGerlich
RemcoGerlich

Reputation: 31260

The loop condition is only checked after all the code inside it has run. And since it is decreased five times in there, there's a good chance it goes from say 2 to -3, and those are both unequal to 0, so it continues.

Also, you have five times more or less the same code there. Why? Just make sure it's there once.

And the guard should be while totalItems > 0:, just a bit of defensive programming to make sure the loop ends even if a bug causes the variable to go below 0.

Lastly, don't have variables 'cost1', 'cost2', 'cost3' et cetera, especially not if you don't know in advance how many you are going to need. That is what lists are for.

Upvotes: 1

ForceBru
ForceBru

Reputation: 44838

The loop will iterate over its whole body, and the condition will be checked for the second time after the whole body has been executed:

while thing:
    do_stuff()
    thing = 0
    hello()  # this is still executed, even though `thing == 0`
    what()  # and this too

It looks like you want to automagically exit the loop as soon as totalItems becomes zero anywhere in the loop, but loops don't do that, you'll have to do it manually:

while totalItems != 0:
    item1 = input("What's the first item?")  # mind the quotes here
    cost1 = input('What is the price of the first item? ')
    totalItems = totalItems - 1
    if totalItems == 0:
        break  # get out of the loop
    print(totalItems)

    item2 = input("What's the second item?")  # mind the quotes here
    cost2 = input("What is the price of the second item?")  # mind the quotes here
    totalItems = totalItems - 1
    if totalItems == 0:
        break  # get out of the loop
    print(totalItems)

    # and so on

Upvotes: 0

sudoer123
sudoer123

Reputation: 89

You are decrementing your variable several times in your loop.

Upvotes: 0

Related Questions