Skip to main content

Section 5.3 Using while

Our first use of while in Section 5.2 was used to count from one to six. In addition to doing counting with while, we normally use a while loop when we don’t know in advance how many times a loop will execute. The last program on that page didn’t do any counting; it continued until the loop condition came back False. That program was a good example of an example, but not a particularly useful program.
One useful and common situation is when we want to validate input: we want to keep asking users for input as long as they don’t give us what we want. This sort of loop is called an indefinite loop because we don’t know in advance how many iterations we will need. The user might give us good input right away, or they may give us bad input twice, three times, or even fifty times. Here’s a program that calculates a person’s approximate age in days. We want to make sure that the user doesn’t give us a negative number or zero for their age:

Note 5.3.1.

We’ve done something new in line three. Instead of writing two lines of code:
years_str = input("Enter your age in years: ")
years = int(years_str)
we combine them into one statement by nesting the function calls.
Here is another example of an indefinite loop: when you are at the grocery store, the clerks keep adding the prices for your items until they see the little plastic bar that means “that is my last item”. The clerks don’t know in advance how many items you have; you could have one item, five items, or fifty items.
In the following exercise, write a program that keeps adding up prices until the user is finished, and then gives the number of items, the total price, and the average price. We can’t put a little plastic bar in our program, so we need some way to tell the program “that is my last item”. We will use a price of 0 to indicate that we are finished entering numbers. This is called our sentinel value. The value we choose is arbitrary, but it should be something that distinguishes it from an ordinary value.

Checkpoint 5.3.2.

Here’s the plan:
  • Set total to zero.
  • Set number_of_items to zero.
  • Set price to None to indicate that it has never been used yet.
  • As long as the price is not 0:
    • Input price and convert to float.
    • If the price is not 0:
      • Add one to number_of_items
      • Add price to total.
  • Calculate the average_price as total divided by number_of_items
  • Print number_of_items, total, and average_price, properly labeled.
Provide the Python code to implement the plan.
Solution.
total = 0.0
number_of_items = 0
price = None

while price != 0:
    price = float(input("Enter price, or 0 when finished: "))
    if price != 0:
        number_of_items = number_of_items + 1
        total = total + price

average_price = total / number_of_items
print("Number of items:", number_of_items)
print("Total cost: $", total)
print("Average price: $", average_price)
There are still a few problems with this program.
  • If you enter a negative number, it will be added to the total and count. Modify the code so that negative numbers give an error message instead (but don’t end the loop) Hint: elif is your friend.
  • If you enter zero the first time you are asked for a price, the loop will end, and the program will try to divide by zero. Use an if/else statement outside the loop to avoid the division by zero and tell the user that you can’t compute an average without data.
  • This program doesn’t display the amounts to two decimal places. We will see a solution to this problem in Section 7.10.