Programming Fundamentals

Control Flow

↩ Back
01

Branching

Reference
if, elif, else

A branch attaches a block of code to a condition. The block runs when the condition is True and is passed over when it is False, so the program takes one route out of several.

if temperature > 30: print("Hot") elif temperature > 15: print("Mild") else: print("Cold")
Three parts of the syntax
The keywordif opens the branch, elif adds another question, and else catches everything left over.
The colonEvery header line ends with :. Forgetting it is a SyntaxError, and Python points at the line where the colon should be.
The indentationThe lines that belong to the branch are pushed to the right by four spaces. That shift is what marks the block.
only one of the three blocks above can ever run

Reading a chain

Python tests the conditions from the top. The first one that answers True wins: its block runs and every remaining condition in the chain is never checked. If none of them holds, the else block runs, and when there is no else the whole chain quietly does nothing.

The order of the conditions is part of the meaning.
Interactive
Branch Tracer

Move the score and watch which line runs. The condition list on the right shows what Python asked, in the order it asked, and where it stopped asking.

score = 78if score >= 90: print("A")elif score >= 80: print("B")elif score >= 70: print("C")else: print("F")
score >= 90False
score >= 80False
score >= 70False
elsereached
Output
C

One branch printed, and the conditions below it were never evaluated.

Warning
elif or a Second if

Replacing elif with a fresh if looks harmless and changes the result. A chain stops at the first match, while separate branches are all tested, so several of them can run for the same value.

Chained
Separate
age = 25if age >= 18: print("adult")elif age >= 13: print("teen")
age = 25if age >= 18: print("adult")if age >= 13: print("teen")
Output
press run to execute
Output
press run to execute
use elif when the cases exclude each other
Detail
Indentation Is the Block

In most languages a block is wrapped in braces and the layout is decoration. In Python the layout is the syntax: the indented lines are the block, and the first line back at the old margin is outside it.

if logged_in: print("Welcome") print("Loading") print("Done") # always runs
four spaces mark a line as inside the block, and stepping back to the margin moves it outside

Mixing tabs and spaces in the same file raises a TabError even when the lines look aligned, and a block with nothing indented under it needs pass to hold its place.

02

The while Loop

Definition
Repeat While True

A while loop is a branch that comes back. Python tests the condition, runs the block when it holds, and then returns to the condition rather than moving on. The block repeats until the answer is False.

count = 3while count > 0: print(count) count = count - 1print("Liftoff")
watch the highlighted line move
Output
press run to execute this loop
Three parts that keep it honest
SetupA variable holds the state the condition asks about, and it exists before the loop starts.
ConditionA boolean expression checked before every pass, including the first one.
UpdateA line inside the block that moves the state closer to making the condition False.
a condition that is False at the start means zero passes
Warning
The Loop With No Exit

Drop the update and nothing about the condition ever changes, so Python keeps answering True and the block repeats without end. The program does not crash: it prints forever, or freezes with no output at all.

count = 3while count > 0: print(count)
this preview stops itself, a real run would not
Output
press run to watch it never reach False
Where the update usually goes wrong
AbsentThe variable in the condition is never touched inside the block.
MisplacedThe update sits outside the block, so it runs once the loop is over rather than on every pass.
BackwardsThe state moves away from the exit, as in count = count + 1 under count > 0.
Stopping a runaway loop

Press Ctrl and C in a terminal to interrupt the program. In Jupyter or Colab, use the interrupt button on the toolbar. Before running any while loop, read the block once and name the line that will eventually make the condition False.

Interactive
While Stepper

Press Step to advance one pass of the loop. The table records what the condition answered and the value of each variable after the block ran, which is the trace a programmer draws by hand when a loop misbehaves.

total = 0n = 1while n <= 5: total = total + n n = n + 1print(total)
one pass at a time
Output
the loop is still running
Passn <= 5totalnWhat happened

Before the first pass, total is 0 and n is 1.

Detail
break and continue

Two keywords interrupt the normal circuit from inside the block. They work in both kinds of loop, and each one skips a different amount of what is left.

WordEffectWhere the program lands
breakLeaves the loop at oncethe first line after the loop
continueAbandons the current passback at the condition
n = 0while True: n = n + 1 if n % 2 == 0: continue if n > 7: break print(n)
watch continue and break redirect the flow
Output
press run to execute

while True pairs with break on purpose: the exit moves from the header down into the block, which suits a loop that ends on an event rather than on a count.

03

for ... in range()

Definition
A Loop That Counts For You

A for loop walks through a series of values. On every pass it puts the next value into the loop variable and runs the block, and it ends when the series is exhausted. The setup, the condition and the update are all folded into the header.

for minute in range(3): print("Minute", minute)
Output
press run to execute

range builds the series of integer numbers, and minute is an ordinary variable that holds one of them at a time. The name is yours to choose: i is the habit for a plain counter, and a fuller name helps when the number means something.

Reference
Three Ways to Call range

The three forms differ only in how much you specify. What is left out takes its default value: counting starts at 0 and advances by 1.

CallReads asProduces
range(5)up to 50 1 2 3 4
range(2, 6)from 2 up to 62 3 4 5
range(0, 10, 3)from 0 up to 10 in steps of 30 3 6 9
range(5, 0, -1)from 5 down to 05 4 3 2 1
range(3, 3)from 3 up to 3an empty series
the start is included and the stop is not

An empty range is not an error. The loop body simply never runs, and the program carries on with the line below.

Interactive
Range Explorer

Set the three arguments and read the series that comes out. Try a step larger than the distance, a negative step, and a start that already sits past the stop.

for i in range(5): print(i)
Values produced

Output
passes 5
Detail
Beyond Counting

A for loop is not tied to numbers. It walks through anything Python can hand over one item at a time, and a string is the first such thing you already know how to write. Reaching for range here would make the same work harder: the counter would only serve to look each character up by its index.

By character
By index, with a detour
for letter in "loop": print(letter)
word = "loop"for i in range(len(word)): print(word[i])
Output
press run to execute
Output
press run to execute
use range when you need the number, not the item

Lists, tuples and dictionaries follow the same pattern, and they arrive in the next two guides.

Comparison
Which Loop To Reach For

Both loops repeat a block, so either one can be made to solve any repetition. The choice is about what the code says to a reader.

Questionforwhile
How many passesKnown before the loop startsDepends on what happens inside
The counterHandled by the headerYours to create and advance
Risk of no exitNone, the series is finiteReal, the update can go missing
Typical useRepeat n times, walk through dataWait for input, repeat until a result is good enough
Prefer for when the count is known, and while when the ending is a condition.
04

Putting Blocks Inside Blocks

Detail
A Branch Inside a Loop

Branches and loops combine by indenting one inside the other. Each level of nesting adds four more spaces, and the branch is evaluated afresh on every pass of the loop.

for n in range(1, 7): if n % 2 == 0: print(n, "even") else: print(n, "odd")
Output
press run to execute

Six passes, six decisions. Nothing about the branch is remembered from one pass to the next.

Detail
A Loop Inside a Loop

The inner loop runs its full series for every single pass of the outer one, so the block at the centre runs as many times as the two counts multiplied together.

for row in range(1, 4): for col in range(1, 4): print(row * col, end=" ") print()
a blank line ends the row
Output
press run to execute

Three outer passes and three inner passes give nine numbers. The print() at the end sits at the outer level, so it runs three times rather than nine.

05

Check Yourself

Question
What Does This Print?
The code
for i in range(3): print(i)
Pick one.
Challenge
Predict Four Outputs

Read each fragment and trace what it prints before pressing Check. The answer button is there for when your trace and the verdict disagree.

separate multiple values with spaces, like 7 2 5 (commas and line breaks work too)
1Squares
for i in range(1, 4): print(i * i)
2Overshooting the exit
n = 10 while n > 0: n = n - 3 print(n)
3The chain stops early
x = 5 if x > 10: print("big") elif x > 3: print("medium") elif x > 0: print("small")
4A step of four
for i in range(0, 10, 4): print(i)
06

Summary

Recap
What You Can Do Now
1
Write a branch with the colon and the indentation in place, and predict which of its blocks runs for a given value.
2
Explain why a chain of elif and a stack of separate if lines answer differently, and choose between them.
3
Build a while loop with its setup, condition and update, and name the line that will eventually stop it.
4
Trace a loop by hand, recording the condition and every variable after each pass.
5
Read any of the three forms of range and list the values it produces, including the empty case.
6
Nest a branch inside a loop, and count how many times the innermost block of two nested loops runs.