while loops

Published

2023-08-02

while loops

Sometimes, we wish to perform some task or calculation repetitively, but we only want to do this under certain conditions. For this we have the while loop. A while loop continues to execute, as long as some condition is true or has a truthy value.

Imagine you’re simulating a game of blackjack, and it’s the dealer’s turn. The dealer turns over their down card, and if their total is less than 17 they must continue to draw until they reach 17 or they go over 21.1 We don’t know how many cards they’ll draw, but they must continue to draw until the condition is met. A while loop will repeat as long as some condition is true, so it’s perfect for a case like this.

Here’s a little snippet of Python code, showing how we might use a while loop.

# Let's say the dealer has a five showing, and 
# then turns over a four. That gives the dealer 
# nine points. They *must* draw.
dealer = 9

prompt = "What's the value of the next card drawn? "

while dealer < 17:
    next_card = int(input(prompt))
    dealer = dealer + next_card

if dealer <= 21:
    print(f"Dealer has {dealer} points!")
else:
    print(f"Oh, dear. "
          f"Dealer has gone over with {dealer} points!")

Here the dealer starts with a total of nine. Then, in the while loop, we keep prompting for the number of points to be added to the dealer’s hand. Points are added to the value of dealer. This loop will continue to execute as long as the dealer’s score is less than 17. We see this in the while condition:

while dealer < 17:
   ...

Naturally, this construction raises some questions.

  • What can be used as a while condition?

  • When is the while condition checked?

  • When does the while loop terminate?

  • What happens after the loop terminates?

A while condition can be any expression which evaluates to a Boolean or truthy value

In the example above, we have a simple Boolean expression as our while condition. However, a while condition can be any Boolean expression, simple or compound, or any value or expression that’s truthy or falsey—and in Python, that’s just about anything! Examples:

lst = ['a', 'b', 'c']

while lst:
    print(lst.pop(0))

Non-empty sequences are truthy. Empty sequences are falsey. So as long as the list lst contains any elements, this while loop will continue. This will print

a
b
c

and then terminate (because after popping the last element, the list is empty, and thus falsey).

while x < 100 and x % 2 == 0:
    ...

This loop will execute as long as x is less than 100 and x is even.

The condition of a while loop is checked before each iteration

The condition of a while loop is checked before each iteration of the loop. In this case, the condition is dealer < 17. At the start, the dealer has nine points, so dealer < 17 evaluates to True. Since this condition is true, the body of the loop is executed. (The body consists of the indented lines under while dealer < 17.)

Once the body of the while loop has executed, the condition is checked again. If the condition remains true, then the body of the loop will be executed again. That’s why we call it a loop!

It’s important to understand that the condition is not checked while the body of the loop is executing.

The condition is always checked before executing the body of the loop. This might sound paradoxical. Didn’t we just say that after executing the body the condition is checked again? Yes. That’s true, and it’s in the nature of a loop to be a little… circular. However, what we’re checking in the case of a while loop is whether or not we should execute the body. If the condition is true, then we execute the body, then we loop back to the beginning and check the condition again.

Termination of a while loop

At some point (if we’ve designed our program correctly), the while condition becomes false. For example, if the dealer were to draw an eight, then adding eight points would bring the dealer’s score to 17. At that point, the condition dealer < 17 would evaluate to False (because 17 is not less than 17), and the loop terminates.

After the loop

Once a while terminates, code execution continues with the code which follows the loop.

It’s important to understand that the while condition is not evaluated again after the loop has terminated.

Review of our blackjack loop

Figure 1
Figure 2
Figure 3
Figure 4
Figure 5
Figure 6

Another example: coffee shop queue with limited coffee

Here’s another example of using a while loop.

Let’s say we have a queue of customers at a coffee shop. They all want coffee (of course). The coffee shop offers small (8 oz), medium (12 oz) and large (20 oz) coffees. However, the coffee shop has run out of beans and all they have is what’s left in the urn. The baristas have to serve the customers in order, and can only take orders as long as there’s at least 20 oz in the urn.

We can write a function which calculates how many people are served in the queue and reports the result. To do this we’ll use a while loop. Our function will take three arguments: the number of ounces of coffee in the urn, a list representing the queue of orders, and the minimum amount of coffee that must remain in the urn before the baristas must stop taking orders. The queue will be a list of values—8, 12, or 20—depending on which size each customer requests. For example,

queue = [8, 12, 20, 20, 12, 12, 20, 8, 12, ...]

Let’s call the amount of coffee in the urn reserve, the minimum minimum, and our queue of customers customers. Our while condition is reserve >= minimum.

def serve_coffee(reserve, customers, minimum):

    customers_served = 0
    
    while reserve >= minimum:
        reserve = reserve - customers[customers_served]
        customers_served += 1

    print(f"We have served {customers_served} customers, "
          f"and we have only {reserve} ounces remaining.")

At each iteration, we check to see if we still have enough coffee to continue taking orders. Then, within the body of the loop, we take the customers in order, and—one customer at a time—we deduct the amount of coffee they’ve ordered. Once the reserve drops below the minimum, we stop taking orders and report the results.

What happens if the while condition is never met?

Let’s say we called the serve_coffee() function (above), with the arguments, 6, lst, and 8, where lst is some arbitrary list of orders:

serve_coffee(6, lst, 8)

In this case, when we check the while condition the first time, the condition fails, because six is not greater than or equal to eight. Thus, the body of the loop would never execute, and the function would report:

We have served 0 customers, and we have only 6 ounces remaining.

So it’s possible that the body of any given while loop might never be executed. If, at the start, the while condition is false, Python will skip past the loop entirely!

Input validation with while loops

A common use for a while loop is input validation.

Let’s say we want the user to provide a number from 1 to 10, inclusive. We present the user with a prompt:

Pick a number from 1 to 10: 

So far, we’ve only seen how to complain to the user:

Pick a number from 1 to 10: 999
You have done a very bad thing. 
I will terminate now and speak to you no further!

That’s not very user-friendly! Usually what we do in cases like this is we continue to prompt the user until they supply a suitable value.

Pick a number from 1 to 10: 999
Invalid input.
Pick a number from 1 to 10: -1
Invalid input.
Pick a number from 1 to 10: 7
You have entered 7, which is a very lucky number!

But here’s the problem: We don’t know how many tries it will take for the user to provide a valid input! Will they do so on the first try? On the second try? On the fourth try? On the twelfth try? We just don’t know! Thus, a while loop is the perfect tool.

How would we implement such a loop in Python? What would serve as a condition?

Plot twist: In this case, we’d choose a condition that’s always true, and then only break out of the loop when we have a number in the desired range. This is a common idiom in Python (and many other programming languages).

while True:
    n = int(input("Pick a number from 1 to 10: "))
    if 1 <= n <= 10:
        break
    print("Invalid input.")
    
if n == 7:
    print("You have entered 7, "
          "which is a very lucky number!")
else:
    print(f"You have entered {n}. Good for you!")

Notice what we’ve done here: the while condition is the Boolean literal True. This can never be false! So we have to have a way of exiting the loop. That’s where break comes in. break is a Python keyword which means “break out of the nearest enclosing loop.” The if clause includes a condition which is only true if the user’s choice is in the desired range. Therefore, this loop will execute indefinitely, until the user enters a number between one and 10.

As far as user experience goes, this is much more friendly than just terminating the program immediately if the user doesn’t follow instructions. Rather than complaining and exiting, our program can ask again when it receives invalid input.

A note of caution

While the example above demonstrates a valid use of break, break should be used sparingly. If there’s a good way to write a while loop without using break then you should do so! This often involves careful consideration of while conditions—a worthwhile investment of your time.

It’s also considered bad form to include more than one break statement within a loop. Again, please use break sparingly.

Other applications of while loops

We’ll see many other uses for the while loop, including performing numeric calculations and reading data from a file.

Comprehension check

  1. What is printed?
    >>> c = 5
    >>> while c >= 0:
    ...     print(c)
    ...     c -= 1
    
  1. How many times is “Hello” printed?
    >>> while False:
    ...    print("Hello")
    ...
  1. What’s the problem with this while loop?
    >>> while True:
    ...     print("The age of the universe is...")
    ...
  1. How many times will this loop execute?
    >>> while True:
    ...     break
    ...
  1. How many times will this loop execute?
    >>> n = 10
    >>> while n > 0:
    ...     n = n // 2
    ...
  1. Here’s an example showing how to pop elements from a list within a loop.
    >>> while some_list:
    ...     element = some_list.pop()
    ...     # Now do something useful with that element
    ...

Ask yourself:

  • Why does this work?
  • When does the while loop terminate?
  • What does this have to do with truthiness or falsiness?
  • Is an empty list falsey?

Challenge!

How about this loop? Try this out with a hand-held calculator.

EPSILON = 0.01

x = 2.0

guess = x
while True:
    guess = sum((guess, x / guess)) / 2
    
    if abs(guess ** 2 - x) < EPSILON:
        break
        
print(guess)

(abs() is a built-in Python function which calculates the absolute value of a number.) What does this loop do?

Original author: Clayton Cafiero < [given name] DOT [surname] AT uvm DOT edu >

No generative AI was used in producing this material. This was written the old-fashioned way.

This material is for free use under either the GNU Free Documentation License or the Creative Commons Attribution-ShareAlike 3.0 United States License (take your pick).

Footnotes

  1. If you’re unfamiliar with the rules of blackjack, see https://en.wikipedia.org/wiki/Blackjack↩︎