A game club needs a 5-by-5 multiplication board. Each row must be assembled as one string and printed on its own line:
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25How can a program visit every row and every column without a separate instruction for each product?
We will build that payoff in three lessons. First,
forvisits a known sequence of integers. Then familiar total-and-count patterns use that sequence. Finally, one loop inside another builds tables and triangles.-
Use
forandrange()to visit a known sequence of numbers. -
Choose a start, stop, and step, then use each number in a calculation.
-
Put one loop inside another to build rows and columns.
-
Lesson 1: Visit a Range
Reproduce the 5050 sum
Unit 02 showed this total as a boxed peek. Unit 04 rebuilt it with
while. Here is the same running total withforandrange.total = 0 for n in range(1, 101): total = total + n print(f"Sum: {total}")Scroll the code for more ↓
Output
Sum: 5050This reproduces
Sum: 5050.range(1, 101)supplies the integers 1 through 100, andnreceives one value per pass. Do not modify theforvariable inside its loop body.Two forms of
rangerange(n)starts at 0. It supplies 0 throughn - 1.for number in range(5): print(number)Scroll the code for more ↓
Output
0 1 2 3 4The output is 0, 1, 2, 3, 4. The stop value 5 is not included.
range(a, b)starts ataand stops beforeb.for number in range(3, 8): print(number)Scroll the code for more ↓
Output
3 4 5 6 7range(3, 8)includes 3 but not 8, so the final printed value is 7. Set the stop one beyond the last value you want.One twist: a third
rangeargument chooses the step size.for number in range(0, 20, 5): print(number)Scroll the code for more ↓
Output
0 5 10 15This prints 0, 5, 10, 15. The stop value 20 is excluded even when the step is 5.
One twist: a negative step counts down, so the stop must be below the start.
for number in range(10, 0, -1): print(number)Scroll the code for more ↓
Output
10 9 8 7 6 5 4 3 2 1The countdown prints 10 through 1; it stops before 0.
Real input: choose the upper bound for a count from 1.
Try it n = int(input("How high? ")) for number in range(1, n + 1): print(number)Scroll the code for more ↓
int()converts the typed number; the range includes it by stopping atn + 1.Comment the job, not every pass
A short comment can explain why a loop exists.
# Print the five badge numbers. for badge_number in range(1, 6): print(f"Badge: {badge_number}")Scroll the code for more ↓
Output
Badge: 1 Badge: 2 Badge: 3 Badge: 4 Badge: 5The name
badge_numberexplains the changing value, and the comment explains the loop's purpose.Lesson 2: Calculate across a Range
Running totals and conditional counts
The accumulator patterns from Unit 04 work unchanged. Only the source of each number changes.
square_total = 0 for number in range(1, 6): square_total = square_total + number * number print(f"Sum of squares: {square_total}")Scroll the code for more ↓
Output
Sum of squares: 55The range supplies 1 through 5, and the accumulator produces
Sum of squares: 55.count = 0 for number in range(1, 31): if number % 4 == 0: count = count + 1 print(f"Count: {count}")Scroll the code for more ↓
Output
Count: 7Every integer from 1 through 30 is checked, but only seven values pass the divisibility test.
FizzBuzz with an
elifladderFizzBuzz classifies each integer. Multiples of both 3 and 5 must be checked first because they also match the separate tests.
for number in range(1, 16): if number % 15 == 0: line = "FizzBuzz" elif number % 3 == 0: line = "Fizz" elif number % 5 == 0: line = "Buzz" else: line = f"{number}" print(line)Scroll the code for more ↓
Output
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzzEach pass assigns exactly one string to
line. Use aprint(line)at the loop-body level (same indent as theif), after the ladder. The order lets 15 becomeFizzBuzz.One twist:
continueskips the rest of oneforpass and moves to the next value.for n in range(1, 11): if n % 3 == 0: continue print(n)Scroll the code for more ↓
Output
1 2 4 5 7 8 103, 6, and 9 are skipped; every other number from 1 through 10 prints.
Real input: choose the last FizzBuzz number. The familiar decision ladder now runs over the typed range.
Try it n = int(input("How high? ")) for number in range(1, n + 1): if number % 15 == 0: line = "FizzBuzz" elif number % 3 == 0: line = "Fizz" elif number % 5 == 0: line = "Buzz" else: line = f"{number}" print(line)Scroll the code for more ↓
The input changes only the range endpoint; each number still gets one label.
Find a divisor, then test for prime
A divisor divides a number with no remainder. First, stop as soon as one divisor of 91 is found.
Minimal: print the first divisor of 91, then leave the search loop.
for d in range(2, 91): if 91 % d == 0: print(d) breakScroll the code for more ↓
Output
77 is the first divisor found;
breakends thisforloop immediately.One twist: keep a boolean flag so the search also reports whether a number is prime.
n = 29 is_prime = True for divisor in range(2, n): if n % divisor == 0: is_prime = False break print(f"{n} is prime: {is_prime}")Scroll the code for more ↓
Output
29 is prime: Truebreakstops this loop when a divisor proves the flag false. Forn == 2,range(2, 2)is empty, sois_primestaysTrue.Lesson 3: Put One Loop inside Another
Build rows in stages
First, build one row string by adding one star per pass.
row_text = "" for col in range(1, 5): row_text = row_text + "*" print(row_text)Scroll the code for more ↓
Output
****One loop builds
****as a single string; printing happens after the row is complete.One twist: repeat that row-building loop inside an outer loop to make a rectangle.
for row in range(1, 4): row_text = "" for col in range(1, 5): row_text = row_text + "*" print(row_text)Scroll the code for more ↓
Output
**** **** ****The inner body has 8 spaces and adds four stars.
print(row_text)has 4 spaces, so it runs once per completed row. Abreakin the inner loop would leave only that loop.A growing triangle
The row number can control how many columns the inner loop visits.
height = 5 for row in range(1, height + 1): row_text = "" for col in range(1, row + 1): row_text = row_text + "*" print(row_text)Scroll the code for more ↓
Output
* ** *** **** *****Row 1 gets one inner pass, while row 5 gets five. The first accumulated row is
*; the last is*****.One twist: string repetition can make each triangle row without an inner loop.
height = 5 for r in range(1, height + 1): print("*" * r)Scroll the code for more ↓
Output
* ** *** **** *****"*" * rmakes exactly as many stars as the row number. The earlier loop shows how to build the same row one star at a time.One twist:
print(piece, end="")keeps the next piece on the same line; a plainprint()finishes it.for col in range(1, 5): print("*", end="") print()Scroll the code for more ↓
Output
****The four pieces print as
****on one line. The finalprint()moves to the next line.One number row
Before building a full table, make a single row with numbers separated by one space.
row_text = "" for col in range(1, 6): if col == 1: row_text = f"{col}" else: row_text = row_text + f" {col}" print(row_text)Scroll the code for more ↓
Output
1 2 3 4 5The result is
1 2 3 4 5with no trailing space; the first number needs no separator.A multiplication table
Build each table row as a string. A small condition inserts spaces between products without leaving a hidden trailing space.
table_size = 3 for row in range(1, table_size + 1): row_text = "" for col in range(1, table_size + 1): product = row * col if col == 1: row_text = f"{product}" else: row_text = row_text + f" {product}" print(row_text)Scroll the code for more ↓
Output
1 2 3 2 4 6 3 6 9The first row is
1 2 3and the last is3 6 9. The inner loop builds one completerow_text; the outer loop prints three rows. No special print options are needed.One twist: a width inside an f-string,
f"{number:3}", pads the number with spaces in front until it is 3 characters wide.row_text = "" for col in range(1, 6): row_text = row_text + f"{col * 4:3}" print(row_text)Scroll the code for more ↓
Output
4 8 12 16 20The row prints as
4 8 12 16 20. Every product fills exactly 3 characters — one-digit numbers get two spaces in front, two-digit numbers get one — so the columns of a table line up. The padding is on the left, so no row ends with a trailing space.ASCII pattern ladder
Start with the triangle you built above. These next shapes change one row rule at a time.
One twist: visit row lengths in reverse to make an inverted triangle.
height = 4 for r in range(height, 0, -1): print("*" * r)Scroll the code for more ↓
Output
**** *** ** *The negative step makes rows of 4, 3, 2, then 1 star.
One twist: add leading spaces so the triangle lines up on the right.
height = 4 for r in range(1, height + 1): print(" " * (height - r) + "*" * r)Scroll the code for more ↓
Output
* ** *** ****The spaces shrink as the stars grow. No row ends with trailing spaces.
One twist: widen each star row to odd widths to center a pyramid.
height = 4 for r in range(1, height + 1): print(" " * (height - r) + "*" * (2 * r - 1))Scroll the code for more ↓
Output
* *** ***** *******The star widths are 1, 3, 5, and 7, so the rows form a centered pyramid.
Real input: choose the height of the pyramid.
Try it height = int(input("Height: ")) for r in range(1, height + 1): print(" " * (height - r) + "*" * (2 * r - 1))Scroll the code for more ↓
The typed height controls both the leading spaces and each row's star width.
Final build
Return to the 5-by-5 multiplication board. The outer loop selects rows 1 through 5, the inner loop selects columns 1 through 5, and string accumulation makes one assertable row at a time.
table_size = 5 for row in range(1, table_size + 1): row_text = "" for col in range(1, table_size + 1): product = row * col if col == 1: row_text = f"{product}" else: row_text = row_text + f" {product}" print(row_text)Scroll the code for more ↓
Output
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25The finished board matches the opening exactly. Known ranges choose the positions, nested loops visit every row-column pair, and each row is printed only after its string is complete.
-
fortakes each number fromrange()in turn. -
range(n)begins at 0 and stops beforen; a start and step change the visit. -
Running totals and conditional counts work inside a
forloop too. -
In nested loops, the inner loop finishes for each outer-loop pass.
You can now build a multiplication board one row at a time.
-