In this article, we will explain the features of while
loops in Python and address common issues that beginners often encounter.
Looping constructs in programming languages are used to repeat certain blocks of code until a specified condition is met. One such construct in Python is the while
loop.
Here's an example of a while
loop in Python:
number = 0
while number < 3:
print('The condition is true, the variable number is less than three and is now', number, ', so the loop continues to execute.')
number += 1
print('We have exited the loop because the value of number became', number, ', and the condition is no longer true.')
input('Press Enter to exit')
When we run this program, we get the following output:
The condition is true, the variable number is less than three and is now 0, so the loop continues to execute.
...
We have exited the loop because the value of number became 3, and the condition is no longer true.
Here's a snippet of a more realistic program:
while score1 < 5 and score2 < 5:
print('The game continues because no one has scored 5 points yet.')
If we translate this Python statement into plain English (which can be useful for beginners), it reads:
"As long as the number of points of the first player (score1
) or the number of points of the second player (score2
) is less than 5, display the message: ‘The game continues because no one has scored 5 points yet.’"
The Python interpreter evaluates the while
condition (score1 < 5 and score2 < 5
) as True
, meaning the loop continues until it becomes False
(i.e., when one of the players scores 5 points, ending the game).
Let's look at a simple dice game program and analyze how it works:
import random
score1 = 0
score2 = 0
die1 = 0
die2 = 0
input('Player 1 rolls the dice, press Enter!\n')
while score1 < 5 and score2 < 5:
die1 = random.randint(1, 6)
print(die1, '\n')
input('Now Player 2 rolls the dice, press Enter!\n')
die2 = random.randint(1, 6)
print(die2, '\n')
if die1 > die2:
score1 += 1
elif die1 < die2:
score2 += 1
else:
print('It’s a tie!\n')
print('Score', score1, ':', score2, '\n')
input('Press Enter!\n')
if score1 > score2:
input('Player 1 wins! Press Enter to exit')
else:
input('Player 2 wins! Press Enter to exit')
In this program:
random
module to generate random values for the dice rolls.while
loop ensures the game continues until one of the players reaches 5 points.and
operator ensures the loop stops when either score1
or score2
reaches 5.This program has one minor flaw: in theory, the random number generator might produce a large number of ties, requiring players to press Enter repeatedly. This could create a situation similar to an infinite loop, so we need to modify the program to limit the number of iterations.
One possible solution is to introduce an additional variable that tracks the number of rounds played. We will also discuss methods for dealing with actual infinite loops in the next section.
Infinite loops are one of the biggest challenges programmers face. When a program gets stuck in an infinite loop, it can cause memory overflow or excessive CPU usage, leading to application crashes or even system freezes.
To understand what an infinite loop is, let's look at this simple Python program:
number = 1
while number > 0:
print(number)
number += 1
Run this code in the Python interpreter and observe the result. The program will keep printing numbers indefinitely (or until your computer runs out of memory). Now, let's kill the program by closing the IDE and analyze what happened:
number = 1
We initialize a variable number
and set it to 1
.
while number > 0:
print(number)
number += 1
We create a loop that keeps running as long as number
is greater than 0. Since number
is always increasing, the condition will never become false, meaning the loop will never stop.
Another way to create an infinite loop is:
number = 1
while number == 1:
print(number)
While intentionally creating infinite loops is sometimes useful (e.g., in game loops or servers), they usually happen by accident because programmers overlook certain conditions.
Consider this program, where we try to visit as many cities as possible before running out of fuel:
import random
fuel = 30
cities = 0
consumption = random.randint(1, 10)
while fuel != 0:
cities += 1
fuel -= consumption
consumption = random.randint(1, 10)
print('You have traveled through', cities, 'cities')
input('Out of fuel! Press Enter to exit the car.')
At first glance, this seems correct. However, when we run the program, we notice something strange:
You have traveled through 298 cities
You have traveled through 299 cities
You have traveled through 300 cities
...
The program never stops, even though we expected it to end when the fuel reached zero.
To find the issue, let's modify the print statement to track the remaining fuel:
print('You have traveled through', cities, 'cities, and you have', fuel, 'liters of fuel left.')
Now we get:
You have traveled through 6 cities, and you have 5 liters of fuel left.
You have traveled through 7 cities, and you have -4 liters of fuel left.
You have traveled through 8 cities, and you have -8 liters of fuel left.
The problem is in the condition while fuel != 0
. The fuel never becomes exactly 0
; instead, it skips to a negative value. If, by pure chance, fuel
had become 0
, the loop would have ended, but that’s not guaranteed. Since fuel
was never exactly 0
, the condition remained true, and the program continued running forever.
We just need to change one symbol in the condition:
import random
fuel = 30
cities = 0
consumption = random.randint(1, 10)
while fuel > 0:
cities += 1
fuel -= consumption
consumption = random.randint(1, 10)
print('You have traveled through', cities, 'cities')
input('Out of fuel! Press Enter to exit the car.')
Now, the condition while fuel > 0
ensures the loop only runs while there is fuel left.
You have traveled through 5 cities
Out of fuel! Press Enter to exit the car.
The loop correctly stops when the fuel runs out, and the program moves to the next block of code.
Conditional branching in Python is implemented using if-elif-else
statements. When combined with loops, they allow for highly flexible and dynamic programs. Let’s write a simple sports simulator.
Imagine a hockey final between The Montreal Canadiens and The Maple Leafs. The main game time ended in a draw, so the match continues until the first goal is scored:
import random
goal1 = 0
goal2 = 0
time = 1
while goal1 == 0 and goal2 == 0:
attack = random.randint(1, 2)
if attack == 1:
shoot = random.randint(1, 2)
if shoot == 1:
keeper = random.randint(1, 2)
if keeper == 1:
print('The Maple Leafs’ goalkeeper saved the puck, the match continues')
time += 1
attack = random.randint(1, 2)
else:
print('Goal! The Montreal Canadiens wins 1:0!')
goal1 += 1
else:
print('The Montreal Canadiens forward missed the goal')
time += 1
attack = random.randint(1, 2)
else:
shoot = random.randint(1, 2)
if shoot == 1:
keeper = random.randint(1, 2)
if keeper == 1:
print('The Montreal Canadiens’ goalkeeper saved the puck, the match continues')
time += 1
attack = random.randint(1, 2)
else:
print('Goal! The Maple Leafs wins 0:1!')
goal2 += 1
else:
print('The Maple Leafs forward missed the goal')
time += 1
attack = random.randint(1, 2)
print('The match ended in the', time, 'minute of overtime.')
input()
The while
loop ensures that the game continues until one of the teams scores. Theoretically, this loop could run infinitely, but the probability of a random number generator never selecting a goal is quite low.
However, it's always a good idea to limit the number of iterations. Can you think of how to do that? (Hint: Add a condition to limit the variable time
to a maximum number of minutes.)
In our simulation, the first overtime was quite intense—both teams had four goal attempts before The Maple Leafs finally scored:
The Montreal Canadiens forward missed the goal
The Montreal Canadiens’ goalkeeper saved the puck, the match continues
The Maple Leafs’ goalkeeper saved the puck, the match continues
The Montreal Canadiens forward missed the goal
The Maple Leafs forward missed the goal
The Maple Leafs’ goalkeeper saved the puck, the match continues
The Montreal Canadiens’ goalkeeper saved the puck, the match continues
The Montreal Canadiens’ goalkeeper saved the puck, the match continues
Goal! The Maple Leafs wins 0:1!
The match ended in the 9th minute of overtime.
This is similar to how sports simulators and manager games work—except that real games take many more factors into account. However, the core logic of all complex programs follows the same principles: they are built using loops, conditions, and interactive elements like the input()
function.
The while
loop has two powerful assistants:
break
immediately exits the loop when a condition is met.continue
skips an iteration but allows the loop to continue.These statements greatly enhance a program’s structure. Here’s an elegant way to handle user input errors without crashing the program:
while True:
try:
number = int(input('Enter a number: '))
break
except ValueError:
print('Invalid input, please enter a valid number.')
continue
print('Thank you!')
If the user enters a valid number, break
stops the loop. If the user enters text or symbols, the except
block catches the error, prints a message, and continue
restarts the loop.
This way, the program does not crash but patiently waits for valid input.