Section · 01
The basic shape
whiletakes a condition. As long as it’s true, the indented body runs. After each pass, the condition is checked again:
countdown = 5
while countdown > 0:
print(countdown)
countdown = countdown - 1
print("Liftoff.")Prints 5, 4, 3, 2, 1, then Liftoff. Three things to notice:
1. The loop variable (countdown) is set BEFORE the loop.
2. Something inside the loop CHANGES the loop variable.
3. The condition eventually becomes false — otherwise we'd loop forever.Miss any one of those and you have a bug. The third is the famous one — the infinite loop.
Section · 02
When to use while vs for
Most loops should be forloops, which you’ll see next lesson. Reach for while only when:
1. You don't know how many times you'll loop in advance.
2. The exit condition depends on something computed inside the loop.
3. You're waiting on an external event.If you know the number of iterations up front — “do this 10 times,” “process every line in the file” — use for. while is for genuinely open-ended loops.
Section · 03
Pattern 1: input validation
A classic use: keep asking until the user gives you something usable.
age = None
while age is None:
raw = input("Your age: ")
try:
age = int(raw)
except ValueError:
print("Please enter a whole number.")
print(f"Got it — age {age}.")The loop variable here is age. It starts as None(a stand-in for “not set yet”). Each pass either keeps it None (try again) or assigns a number (exit). You could write this with a while True: and a break, which we’ll cover next lesson — both are common.
Section · 04
Pattern 2: retry with backoff
Calling an unreliable thing — an API, a flaky database, a remote file. You want to try a few times before giving up:
import time
attempt = 0
max_attempts = 5
wait_seconds = 1
while attempt < max_attempts:
success = try_to_send_request()
if success:
break
attempt = attempt + 1
print(f"Attempt {attempt} failed. Waiting {wait_seconds}s...")
time.sleep(wait_seconds)
wait_seconds = wait_seconds * 2 # exponential backoff
else:
raise RuntimeError("Gave up after 5 attempts.")Two Python-specific things in there. The break exits the loop early on success. The else: on a loop is unusual — it runs only if the loop exits naturally (i.e., the condition became false, no break). Handy for “we got through all the retries without success.” You don’t see it often; it’s worth knowing.
Section · 05
Pattern 3: polling for a condition
Wait for something to change — a job to finish, a file to appear, a connection to come up:
import time
job_status = "queued"
while job_status != "done":
job_status = check_job_status()
if job_status == "failed":
raise RuntimeError("Job failed.")
if job_status == "done":
break
time.sleep(5)
print("Job complete.")In real systems you’d add a timeout (don’t poll forever) and probably some jitter to the sleep. But the structure is the same: keep checking until the world changes the way you need it to.
Section · 06
The infinite loop trap
The #1 while loop bug:
# WRONG — n is never updated, loop runs forever
n = 10
while n > 0:
print(n)
# (you'll need to Ctrl-C to stop)The condition n > 0 is true forever because nothing inside the loop changes n. The fix:
n = 10
while n > 0:
print(n)
n = n - 1 # <-- the missing lineEvery while loop should have one of these in its body:
1. A statement that moves toward making the condition false.
2. A break statement triggered by something inside the loop.
3. A return / raise that exits the function entirely.When you write a while loop, find the line that ends it beforeyou finish typing the body. If you can’t point to it, you have a bug waiting to happen.