for Loops as Robot Scanning Loops

Pre-COSMOS Day 8, for Cluster 10: Robot Inventors, a 60-minute robotics upgrade. It teaches for loops as the known-repeat scanning loops a robot uses: processing each sensor reading, repeating exactly N times with range(), scanning every other position with range(start, stop, step), counting obstacles, and using nested loops to scan a 3x5 camera image row by row. The watch-outs around range() excluding its end value appear both as trap slides and as checks. Every snippet was executed under CPython 3.12.4.

Subject: Python · 91 slides · code lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. What you will be able to do

Objectives

Yesterday, while meant: keep going until a condition changes. Today, for means: repeat for each item, or repeat exactly N times.

1. Use for item in list to process robot sensor readings one at a time.

2. Use range(n) for exactly N repeats, and explain why range(5) stops before 5.

3. Use range(start, stop, step) to scan patterns like every other pixel.

4. Count and record results with counters, indexes, and enumerate().

5. Use nested loops to scan a 3x5 camera grid row by row, then decide when a robot behavior needs for instead of while.

2. What survived from Lists: Operations & Slicing?

Warm-up

Discussion prompt

Before we open for Loops as Robot Scanning Loops: without looking back, what was the main idea of Lists: Operations & Slicing, and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

An in-depth session of 41 slides. It covers indexing from 0, negative indexes, and slicing with the end excluded, along with the slice shortcuts, joining with + and repeating with *, changing items, and append. The three misses the diagnostic found each appear as a trap slide, and there are five checks, followed by a scaffolded build-it-yourself Dream Team Roster project. It was built for the Pre-COSMOS Day 3 hour.

3. Why this matters for robots

Concept

Robots repeat tiny actions constantly: take five readings, test each sensor value, scan a row of pixels, or try the same movement a fixed number of times.

robot taskloop idea
Check each distance readingfor reading in readings
Take 5 test stepsfor step in range(5)
Scan columns 1, 3, 5, 7, 9range(1, 10, 2)
Scan a camera imagenested loops: rows, then columns

By the end, the range traps that were almost solid on the diagnostic should feel boring in the best way.

4. Fill in: loop idea for Why this matters for robots

Comparison

Comparison matrix

From Why this matters for robots: refill the loop idea column from what you know. The rest of the table is as it appeared.

robot taskloop idea
Check each distance readingfor reading in readings
Take 5 test stepsfor step in range(5)
Scan columns 1, 3, 5, 7, 9range(1, 10, 2)
Scan a camera imagenested loops: rows, then columns

5. For vs while

Concept

while is for an unknown number of repeats: keep driving until the robot reaches the goal, or keep asking until a condition changes.

for is for a known set of repeats: one pass for each item in a list, or exactly N passes from range().

questionusually use
Do I already know the items or count?for
Am I waiting for the world to change?while
Do I need one pass per sensor reading?for
Do I need to stop when the goal is reached?while

6. Which is which, by usually use

Discrimination

Sort into buckets

Sort these by usually use, from memory, without looking back at For vs while. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

for
Do I already know the items or count?; Do I need one pass per sensor reading?
while
Am I waiting for the world to change?; Do I need to stop when the goal is reached?
g1
usually use is "for" for Do I already know the items or count?, Do I need one pass per sensor reading? — that is what the table on "For vs while" records, and it is the single property separating this group from the rest.
g2
usually use is "while" for Am I waiting for the world to change?, Do I need to stop when the goal is reached? — that is what the table on "For vs while" records, and it is the single property separating this group from the rest.

7. The shape of a for loop

Concept

A for loop has a loop variable, a sequence to walk through, a colon, and an indented body.

piecejob
forstarts the loop
distanceloop variable: the current item
in readingsthe sequence being scanned
:says the indented body starts next
indented linesthe work repeated once per item

Indentation decides what repeats. A line lined up under the for runs every pass; a line back at the left runs after the loop is done.

8. What each one costs: The shape of a for loop

Trade off

Comparison matrix

From The shape of a for loop: every row here is a choice with a cost. Fill the job column, then say which row you would actually pick and what you give up for it.

piecejob
forstarts the loop
distanceloop variable: the current item
in readingsthe sequence being scanned
:says the indented body starts next
indented linesthe work repeated once per item

9. What has to happen first: Warm-up: five robot readings

Ranking

Put in order

Put the moves of Warm-up: five robot readings into the order they have to happen.

  1. range(5) gives exactly five values
  2. The body runs once per value
  3. Trace the output

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. The values are 0, 1, 2, 3, and 4.

10. Warm-up: five robot readings

Worked example

First, make the robot print five scan numbers. Predict the last number before you reveal the trace.

for step in range(5):
    print(step)

range(5) gives exactly five values

Why: The values are 0, 1, 2, 3, and 4. The stop number is the first value left out.

The body runs once per value

Why: Line 2 runs five times because range(5) handed over five values.

Trace the output

Why: Verified by execution under CPython 3.12.4.

passstepprinted
100
211
322
433
544

11. Watch it run: Warm-up: five robot readings

Pattern

Step through it

Step through Warm-up: five robot readings one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: pass is 1
  2. Step 2: pass is 2
  3. Step 3: pass is 3
  4. Step 4: pass is 4
  5. Step 5: pass is 5

12. Something is wrong here: range(5) does not include 5

Anomaly

Predict first

A student writes this, and it looks reasonable:

Goal: label robot steps 1 through 5.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This feels natural, but range(5) means five values starting at 0.

Same goal: label robot steps 1 through 5.

Why: This feels natural, but range(5) means five values starting at 0.

13. Trap: range(5) does not include 5

Trap

The trap

Goal: label robot steps 1 through 5.

Use range(5) because the goal mentions 5

Why: This feels natural, but range(5) means five values starting at 0.

wrong output
Step 0
Step 1
Step 2
Step 3
Step 4

The fix

Same goal: label robot steps 1 through 5.

Use range(1, 6)

Why: Start at 1, and make the stop one past the last label you want.

right output
Step 1
Step 2
Step 3
Step 4
Step 5

14. The stop is a wall, not a tile

Intuition

Think of range(5) as five lockers numbered 0, 1, 2, 3, 4. The 5 is the wall after the last locker.

This is the same rule as slicing: the end is excluded. Python likes starts that are included and stops that are left out.

end excluded — The stop value in range() is not produced. range(5) has 5 values, but none of them is 5.

15. Break it if you can: The stop is a wall, not a tile

Counterexample

Discussion prompt

Think of range(5) as five lockers numbered 0, 1, 2, 3, 4. The 5 is the wall after the last locker.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

16. Looping through a list

Concept

When you already have readings, loop through the list itself. The loop variable becomes one reading at a time.

listloop variable values
[12, 8, 3, 15, 4]12, then 8, then 3, then 15, then 4
['r', 'g', 'b']'r', then 'g', then 'b'

The loop variable is not magic. Name it for what one item means: distance, color, pixel, row, or reading.

17. By analogy: Looping through a list

Analogy

Discussion prompt

Explain Looping through a list by analogy to something with no Python in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

When you already have readings, loop through the list itself. The loop variable becomes one reading at a time.

18. Plan first: Process sensor readings

Step zero

Discussion prompt

Process sensor readings — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Line 3 picks one reading at a time

Answer:

  1. Line 3 picks one reading at a time
  2. Lines 4-7 make one decision per reading
  3. Trace each reading

19. Process sensor readings

Worked example

The robot says a reading below 5 means an obstacle is close.

readings = [12, 8, 3, 15, 4]

for distance in readings:
    if distance < 5:
        print('Obstacle!')
    else:
        print('Clear')

Line 3 picks one reading at a time

Why: distance is 12 on the first pass, 8 on the second pass, and so on.

Lines 4-7 make one decision per reading

Why: The if runs inside the loop body, so every reading gets checked.

Trace each reading

Why: Verified by execution: two readings are close enough to report an obstacle.

passdistancedistance < 5?printed
112FalseClear
28FalseClear
33TrueObstacle!
415FalseClear
54TrueObstacle!

20. Inspect it line by line: Process sensor readings

Error analysis

Annotate

Walk the callouts on Process sensor readings. Each one is a place this is easy to get subtly wrong.

  • distance is 12 on the first pass, 8 on the second pass, and so on.
  • The if runs inside the loop body, so every reading gets checked.
  • Verified by execution: two readings are close enough to report an obstacle.

21. The loop variable is a clipboard

Intuition

Picture the robot handing you one sensor reading on a clipboard. You do the body of the loop with that reading.

On the next pass, the old value is replaced by the next one. You do not move the loop variable forward yourself; the for loop does that for you.

That is why for distance in readings reads almost like English: for each distance in readings, run this body.

22. Teach it back: The loop variable is a clipboard

Explain it

Discussion prompt

Explain The loop variable is a clipboard to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Picture the robot handing you one sensor reading on a clipboard. You do the body of the loop with that reading.

23. Something is wrong here: checking only the first reading

Anomaly

Predict first

A student writes this, and it looks reasonable:

Goal: check every reading for an obstacle.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This checks the first sensor value and then stops.

Same goal: check every reading for an obstacle.

Why: This checks the first sensor value and then stops. The close readings later in the list are never seen.

24. Trap: checking only the first reading

Trap

The trap

Goal: check every reading for an obstacle.

Only test readings[0]

Why: This checks the first sensor value and then stops. The close readings later in the list are never seen.

checked valueprinted
12Clear

The fix

Same goal: check every reading for an obstacle.

Loop with for distance in readings

Why: The body runs once for each item, so no reading gets skipped.

checked valuesobstacles reported
12, 8, 3, 15, 42

25. Break it on purpose: checking only the first reading

Break the constraint

Discussion prompt

The rule this trap just fixed:

The body runs once for each item, so no reading gets skipped.

Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?

Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.

Answer:

This checks the first sensor value and then stops. The close readings later in the list are never seen.

26. Guess the shape of the answer: A tiny color scan

Estimation

Predict first

A for loop works the same way for colors, names, readings, or pixels: one item per pass.

Commit before you compute: what does A tiny color scan come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: The list has three items

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. So the loop body runs exactly three times.

27. A tiny color scan

Worked example

A for loop works the same way for colors, names, readings, or pixels: one item per pass.

for c in ['r', 'g', 'b']:
    print(c)

The list has three items

Why: So the loop body runs exactly three times.

Trace the color variable

Why: Verified by execution.

passcprinted
1'r'r
2'g'g
3'b'b

28. Work backwards from the answer: A tiny color scan

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Trace the color variable

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

A for loop works the same way for colors, names, readings, or pixels: one item per pass.

29. range(start, stop, step)

Concept

range() can take three inputs: where to start, where to stop, and how big each jump should be.

formmeaning
range(5)start at 0, stop before 5, step by 1
range(1, 10)start at 1, stop before 10, step by 1
range(1, 10, 2)start at 1, stop before 10, step by 2

Robot meaning: use the step to scan every second column, every tenth sensor, or every other test position.

30. Plan first: Scan every other position

Step zero

Discussion prompt

Scan every other position — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Start at 1

Answer:

  1. Start at 1
  2. Jump by 2 until the next jump would reach or pass 10
  3. Trace the scan

31. Scan every other position

Worked example

This scan starts at column 1, jumps by 2, and stops before 10.

for col in range(1, 10, 2):
    print(col)

Start at 1

Why: The first value produced by the range is the start value.

Jump by 2 until the next jump would reach or pass 10

Why: The produced values are 1, 3, 5, 7, and 9. The stop value 10 is not included.

Trace the scan

Why: Verified by execution.

passcolprinted
111
233
355
477
599

32. What happens as it grows: Scan every other position

Scale up

Step through it

Step through Scan every other position and watch the numbers move. Now imagine the input ten times bigger: which column is the one that stops this being practical?

  1. Step 1: pass is 1
  2. Step 2: pass is 2
  3. Step 3: pass is 3
  4. Step 4: pass is 4
  5. Step 5: pass is 5

33. Something is wrong here: the stop is still excluded

Anomaly

Predict first

A student writes this, and it looks reasonable:

Goal: scan odd columns 1, 3, 5, 7, 9.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This looks like it should end at 9, but 9 is the stop value, so it is excluded.

Same goal: scan odd columns 1, 3, 5, 7, 9.

Why: This looks like it should end at 9, but 9 is the stop value, so it is excluded.

34. Trap: the stop is still excluded

Trap

The trap

Goal: scan odd columns 1, 3, 5, 7, 9.

Use range(1, 9, 2)

Why: This looks like it should end at 9, but 9 is the stop value, so it is excluded.

wrong output
1
3
5
7

The fix

Same goal: scan odd columns 1, 3, 5, 7, 9.

Use range(1, 10, 2)

Why: The stop has to be one past the last odd column you want.

right output
1
3
5
7
9

35. Exactly N repeats

Concept

Use range(n) when the count matters more than the values. range(5) means exactly five passes.

The variable can still be useful for labels, logs, and trace tables. If you truly do not need it, many Python programmers name it _.

goalloop shape
take 5 readingsfor reading_number in range(5)
blink 3 timesfor blink in range(3)
repeat a test 10 timesfor trial in range(10)

36. What has to be given first: Five fixed robot moves

Missing information

Discussion prompt

A movement test might need exactly five forward moves, whether or not anything interesting happens.

What do you need to know — or decide — before the first line can be written? List everything the problem has to hand you.

Hint: Anything you would have to invent to get started is a thing the problem must supply.

Answer:

The labels are 0 through 4, but the count of passes is 5.

37. Five fixed robot moves

Worked example

A movement test might need exactly five forward moves, whether or not anything interesting happens.

for step in range(5):
    print('move forward', step)

The loop repeats exactly five times

Why: The labels are 0 through 4, but the count of passes is 5.

Trace the movement labels

Why: Verified by execution.

passstepprinted
10move forward 0
21move forward 1
32move forward 2
43move forward 3
54move forward 4

38. Watch it run: Five fixed robot moves

Pattern

Step through it

Step through Five fixed robot moves one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: pass is 1
  2. Step 2: pass is 2
  3. Step 3: pass is 3
  4. Step 4: pass is 4
  5. Step 5: pass is 5

39. Counters remember across passes

Concept

A loop can do more than print. It can keep a counter that survives from one pass to the next.

counter — A variable that starts before the loop and changes inside the loop, often by adding 1 when something is found.

wherewhy
before the loopcreate the counter once
inside the loopupdate it for each item
after the loopuse the final answer

40. Plan first: Count close readings

Step zero

Discussion prompt

Count close readings — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Initialize before the loop

Answer:

  1. Initialize before the loop
  2. Add 1 only for close readings
  3. Trace every pass
  4. Print after the loop

41. Count close readings

Worked example

Now count how many readings report a close obstacle.

readings = [12, 8, 3, 15, 4]
obstacles = 0

for distance in readings:
    if distance < 5:
        obstacles = obstacles + 1

print(obstacles)

Initialize before the loop

Why: obstacles = 0 runs once. The robot has not found anything yet.

Add 1 only for close readings

Why: The counter changes on passes where distance < 5 is True.

Trace every pass

Why: Verified by execution: readings 3 and 4 are the two close readings.

passdistanceobstacles beforeobstacles after
start--0
11200
2800
3301
41511
5412

Print after the loop

Why: The final output is 2, because the loop has finished scanning all five readings.

42. Draw the shape of it: Count close readings

Blank canvas

Draw it

Draw what Count close readings just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

43. Something is wrong here: resetting the counter inside

Anomaly

Predict first

A student writes this, and it looks reasonable:

Goal: count all close readings in [12, 8, 3, 15, 4].

It is wrong. Say what breaks — and say it before you turn the page.

Correct: This erases the count at the start of every pass.

Same goal: count all close readings in [12, 8, 3, 15, 4].

Why: This erases the count at the start of every pass. The robot forgets what it found earlier.

44. Trap: resetting the counter inside

Trap

The trap

Goal: count all close readings in [12, 8, 3, 15, 4].

Put obstacles = 0 inside the loop

Why: This erases the count at the start of every pass. The robot forgets what it found earlier.

passdistancecounter after pass
1120
280
331
4150
541
printed-1

The fix

Same goal: count all close readings in [12, 8, 3, 15, 4].

Put obstacles = 0 before the loop

Why: The counter is created once, then it can remember across all passes.

passdistancecounter after pass
1120
280
331
4151
542
printed-2

45. Which of these survive contact with for Loops as Robot Scanning Loops?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
Robots repeat tiny actions constantly: take five readings, test each sensor value, scan a row of pixels, or try the same movement a fixed number of times.; while is for an unknown number of repeats: keep driving until the robot reaches the goal, or keep asking until a condition changes.; A for loop has a loop variable, a sequence to walk through, a colon, and an indented body.
Breaks
Goal: label robot steps 1 through 5.; Goal: check every reading for an obstacle.
sound
These are stated as this lesson states them — each one survives the edge cases for Loops as Robot Scanning Loops puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

46. When you need positions

Concept

Sometimes the item is enough: for distance in readings. Sometimes the position matters too: which sensor number saw the obstacle?

needgood loop
just the valuefor distance in readings
index onlyfor i in range(len(readings))
index and valuefor i, distance in enumerate(readings)

Use indexes when you must look up by position, label coordinates, or compare neighboring items.

47. What has to happen first: Index scan with range(len())

Ranking

Put in order

Put the moves of Index scan with range(len()) into the order they have to happen.

  1. Line 3 loops through indexes
  2. Line 4 uses the index to fetch the reading
  3. Trace the positions

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. The loop variable i is 0, 1, 2, 3, and 4.

48. Index scan with range(len())

Worked example

len(readings) is 5, so range(len(readings)) gives the indexes 0 through 4.

readings = [12, 8, 3, 15, 4]

for i in range(len(readings)):
    print(i, readings[i])

Line 3 loops through indexes

Why: The loop variable i is 0, 1, 2, 3, and 4.

Line 4 uses the index to fetch the reading

Why: readings[i] means the item at that position.

Trace the positions

Why: Verified by execution.

passireadings[i]printed
10120 12
2181 8
3232 3
43153 15
5444 4

49. Fill in: readings[i] for Index scan with range(len())

Comparison

Comparison matrix

From Index scan with range(len()): refill the readings[i] column from what you know. The rest of the table is as it appeared.

passireadings[i]printed
10120 12
2181 8
3232 3
43153 15
5444 4

50. Predict the next row: Index and value with enumerate

Pattern

Predict first

The table runs: 1 | 0 | 12 | 0 12 · 2 | 1 | 8 | 1 8 · 3 | 2 | 3 | 2 3 · 4 | 3 | 15 | 3 15

In Index and value with enumerate, given the rows so far: what is the next one — the row where pass is 5?

Correct: 5 | 4 | 4 | 4 4

passidistanceprinted
10120 12
2181 8
3232 3
43153 15
5444 4

Why: The relationship between the columns, not the individual numbers, is what generates the next row. i gets the position, and distance gets the reading at that position.

51. Index and value with enumerate

Worked example

enumerate(readings) hands you both pieces at once: the index and the value.

readings = [12, 8, 3, 15, 4]

for i, distance in enumerate(readings):
    print(i, distance)

The loop receives a pair each pass

Why: i gets the position, and distance gets the reading at that position.

Trace the same output

Why: This prints the same pairs as the range(len()) version, but the code says the intent more directly.

passidistanceprinted
10120 12
2181 8
3232 3
43153 15
5444 4

52. For-loop tools you may see

Concept

These are not the main build today, but they should not surprise you when you see them in examples.

toolmeaning
breakstop the loop early
continueskip the rest of this pass and go to the next one
_loop variable name used when the value is ignored
looping through a stringone character per pass, like pixels in a row
changing the list while loopingavoid this as a beginner; it can skip or duplicate work

Today, your safest default is simple: pick the right sequence, trace one row per pass, and keep changes inside the body easy to see.

53. Camera images are grids

Concept

A tiny robot camera image can be stored as a list of rows. Each row is a list of pixels.

row01234
0..#..
1.###.
2..#..

# means obstacle pixel. . means clear pixel. A 3-row, 5-column image has 15 total positions.

54. Teach it back: Camera images are grids

Explain it

Discussion prompt

Explain Camera images are grids to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

A tiny robot camera image can be stored as a list of rows. Each row is a list of pixels.

55. Nested loops scan row by row

Intuition

A nested loop is a loop inside another loop. The outside loop chooses the row; the inside loop scans across the columns in that row.

outside rowinside col values
00, 1, 2, 3, 4
10, 1, 2, 3, 4
20, 1, 2, 3, 4

That is how a camera scan becomes 15 visits: 3 rows times 5 columns.

56. What stays fixed: Nested loops scan row by row

Invariant

Step through it

Step through Nested loops scan row by row one row at a time. One of these columns never changes — find it, and say why it cannot.

  1. Step 1: outside row is 0
  2. Step 2: outside row is 1
  3. Step 3: outside row is 2

57. Plan first: Trace a full grid scan

Step zero

Discussion prompt

Trace a full grid scan — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: The outer loop chooses a row

Answer:

  1. The outer loop chooses a row
  2. The inner loop scans all five columns for that row
  3. Trace all 15 positions

58. Trace a full grid scan

Worked example

This is the stretch scan from the lesson: print the row, column, and pixel at every position.

image = [
    ['.', '.', '#', '.', '.'],
    ['.', '#', '#', '#', '.'],
    ['.', '.', '#', '.', '.'],
]

for row in range(3):
    for col in range(5):
        print(row, col, image[row][col])

The outer loop chooses a row

Why: row becomes 0, then 1, then 2.

The inner loop scans all five columns for that row

Why: For each row, col becomes 0, 1, 2, 3, and 4.

Trace all 15 positions

Why: Verified by execution. The scan goes left to right across row 0, then row 1, then row 2.

#rowcolpixel
100.
201.
302#
403.
504.
610.
711#
812#
913#
1014.
1120.
1221.
1322#
1423.
1524.

59. Build: robot camera scanner

Concept

Now you build the scanner yourself. Type each milestone before revealing the solution, run after every small change, and read errors before editing.

requirementtool you will use
print each row of the imagefor row in image
count obstacle pixelscounter before the loop, update inside
print obstacle coordinatesnested row and col loops
prove the scan covers 15 positionssecond counter plus 3x5 nested loops

Build rule: do not skip to the final program. The useful skill is making one small loop work, then adding the next one.

60. By analogy: Build: robot camera scanner

Analogy

Discussion prompt

Explain Build: robot camera scanner by analogy to something with no Python in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

Build rule: do not skip to the final program. The useful skill is making one small loop work, then adding the next one.

61. Guess the shape of the answer: Your turn 1: print each row

Estimation

Predict first

Your turn: create the image list and print each row. Before running, say out loud how many rows should print.

Commit before you compute: what does Your turn 1: print each row come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Expected output

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Three rows print, and each row has five pixels.

62. Your turn 1: print each row

Worked example

Your turn: create the image list and print each row. Before running, say out loud how many rows should print.

Hint

Why: The sequence is image, and each item in it is one row.

image = [
    ['.', '.', '#', '.', '.'],
    ['.', '#', '#', '#', '.'],
    ['.', '.', '#', '.', '.'],
]

for row in image:
    print(row)

Expected output

Why: Three rows print, and each row has five pixels.

lineoutput
1['.', '.', '#', '.', '.']
2['.', '#', '#', '#', '.']
3['.', '.', '#', '.', '.']

63. Draw the shape of it: Your turn 1: print each row

Blank canvas

Draw it

Draw what Your turn 1: print each row just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

64. Predict the next row: Your turn 2: count obstacle pixels

Pattern

Predict first

The table runs: 0 | 1 | 1 · 1 | 3 | 4 · 2 | 1 | 5

In Your turn 2: count obstacle pixels, given the rows so far: what is the next one — the row where row is printed?

Correct: printed | - | 5

rowobstacles in rowrunning total
011
134
215
printed-5

Why: The relationship between the columns, not the individual numbers, is what generates the next row. Use obstacles = 0 before the loops.

65. Your turn 2: count obstacle pixels

Worked example

Your turn: count how many # pixels are in the image. Before revealing, predict the total by looking at the grid.

Hint

Why: Use obstacles = 0 before the loops. Add 1 inside the inner loop only when the pixel equals #.

image = [
    ['.', '.', '#', '.', '.'],
    ['.', '#', '#', '#', '.'],
    ['.', '.', '#', '.', '.'],
]

obstacles = 0

for row in image:
    for pixel in row:
        if pixel == '#':
            obstacles = obstacles + 1

print(obstacles)

Expected output

Why: One obstacle in row 0, three in row 1, and one in row 2: total 5.

rowobstacles in rowrunning total
011
134
215
printed-5

66. Work backwards from the answer: Your turn 2: count obstacle pixels

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Expected output

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

Your turn: count how many # pixels are in the image. Before revealing, predict the total by looking at the grid.

67. What has to be given first: Your turn 3: print obstacle coordinates

Missing information

Discussion prompt

Your turn: print the row and column of every obstacle. Before revealing, point to the five # positions in the grid.

What do you need to know — or decide — before the first line can be written? List everything the problem has to hand you.

Hint: Anything you would have to invent to get started is a thing the problem must supply.

Answer:

Coordinates need indexes, so use range(3) for rows and range(5) for columns.

68. Your turn 3: print obstacle coordinates

Worked example

Your turn: print the row and column of every obstacle. Before revealing, point to the five # positions in the grid.

Hint

Why: Coordinates need indexes, so use range(3) for rows and range(5) for columns.

image = [
    ['.', '.', '#', '.', '.'],
    ['.', '#', '#', '#', '.'],
    ['.', '.', '#', '.', '.'],
]

for row in range(3):
    for col in range(5):
        if image[row][col] == '#':
            print(row, col)

Expected output

Why: The output lists each obstacle coordinate as row col.

lineoutput
10 2
21 1
31 2
41 3
52 2

69. What happens as it grows: Your turn 3: print obstacle coordinates

Scale up

Step through it

Step through Your turn 3: print obstacle coordinates and watch the numbers move. Now imagine the input ten times bigger: which column is the one that stops this being practical?

  1. Step 1: line is 1
  2. Step 2: line is 2
  3. Step 3: line is 3
  4. Step 4: line is 4
  5. Step 5: line is 5

70. Guess the shape of the answer: Your turn 4: prove 15 positions

Estimation

Predict first

Your turn: count every scanned position, not just obstacles. Before revealing, predict the final value.

Commit before you compute: what does Your turn 4: prove 15 positions come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Expected output

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Three rows times five columns means 15 total positions.

71. Your turn 4: prove 15 positions

Worked example

Your turn: count every scanned position, not just obstacles. Before revealing, predict the final value.

Hint

Why: Create positions = 0 before the loops, then add 1 inside the inner loop for every pixel.

image = [
    ['.', '.', '#', '.', '.'],
    ['.', '#', '#', '#', '.'],
    ['.', '.', '#', '.', '.'],
]

positions = 0

for row in range(3):
    for col in range(5):
        positions = positions + 1

print(positions)

Expected output

Why: Three rows times five columns means 15 total positions.

rowcolumns scannedrunning positions
055
1510
2515
printed-15

72. Inspect it line by line: Your turn 4: prove 15 positions

Error analysis

Annotate

Walk the callouts on Your turn 4: prove 15 positions. Each one is a place this is easy to get subtly wrong.

  • Create positions = 0 before the loops, then add 1 inside the inner loop for every pixel.
  • Three rows times five columns means 15 total positions.

73. What has to happen first: Full program: camera scanner

Ranking

Put in order

Put the moves of Full program: camera scanner into the order they have to happen.

  1. Read the outer loop
  2. Read the inner loop
  3. Expected output

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. The outer loop prints one row at a time, then starts an inner scan for that row.

74. Full program: camera scanner

Worked example

Here is the whole scanner after the milestones are working. Yours can use the same shape with your own image.

image = [
    ['.', '.', '#', '.', '.'],
    ['.', '#', '#', '#', '.'],
    ['.', '.', '#', '.', '.'],
]

obstacles = 0
positions = 0

for row in range(3):
    print('row', row, image[row])
    for col in range(5):
        positions = positions + 1
        pixel = image[row][col]
        if pixel == '#':
            obstacles = obstacles + 1
            print('obstacle at', row, col)

print('obstacles:', obstacles)
print('positions:', positions)

Read the outer loop

Why: The outer loop prints one row at a time, then starts an inner scan for that row.

Read the inner loop

Why: Every pass adds one scanned position, then checks whether that pixel is an obstacle.

Expected output

Why: If yours prints your own rows, obstacle coordinates, 5 obstacles, and 15 positions in the same shape, you built it.

lineoutput
1row 0 ['.', '.', '#', '.', '.']
2obstacle at 0 2
3row 1 ['.', '#', '#', '#', '.']
4obstacle at 1 1
5obstacle at 1 2
6obstacle at 1 3
7row 2 ['.', '.', '#', '.', '.']
8obstacle at 2 2
9obstacles: 5
10positions: 15

75. Where the cost goes: Full program: camera scanner

Cost model

Annotate

In Full program: camera scanner, before reading the notes: mark where the time actually goes. Which line dominates?

  • The outer loop prints one row at a time, then starts an inner scan for that row.
  • Every pass adds one scanned position, then checks whether that pixel is an obstacle.
  • If yours prints your own rows, obstacle coordinates, 5 obstacles, and 15 positions in the same shape, you built it.

76. Show it off

Concept

Explain your scanner line by line: where the rows come from, where the columns come from, where the counters start, and where they change.

questionanswer you should be able to say
Why range(3)?There are 3 rows: 0, 1, 2.
Why range(5)?There are 5 columns: 0, 1, 2, 3, 4.
Why not include 5?The stop value is excluded.
Why nested loops?Each row needs a full column scan.

The robot-camera idea is the same as real image logic: scan positions, inspect pixels, count or react to what you find.

77. Break it if you can: Show it off

Counterexample

Discussion prompt

Explain your scanner line by line: where the rows come from, where the columns come from, where the counters start, and where they change.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

The robot-camera idea is the same as real image logic: scan positions, inspect pixels, count or react to what you find.

78. The for-loop recipe

Pattern

1. Decide whether the repeats are known

Why: Use for when you already have the items, rows, columns, or exact repeat count.

2. Choose the sequence

Why: Loop through a list for values, range(n) for exactly N repeats, or range(start, stop, step) for a scan pattern.

3. Name one item clearly

Why: Good loop variables sound like one thing: distance, pixel, row, col, or step.

4. Put repeated work inside the indented body

Why: Anything at the same indentation as the for line runs after the loop, not during every pass.

5. Trace one row per pass

Why: If you can fill a trace table, you can predict the loop before running it.

6. Use nested loops for grids

Why: Outer loop chooses the row; inner loop scans the columns.

79. Where this shows up: for Loops as Robot Scanning Loops

Real world

Discussion prompt

Outside this lesson: where does for Loops as Robot Scanning Loops actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of The for-loop recipe is doing the work in it.

Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.

Answer:

Pre-COSMOS Day 8 (Cluster 10: Robot Inventors), 60-minute robotics upgrade. for loops are taught as known-repeat robot scanning loops: process each sensor reading, repeat exactly N times with range(), scan every other position with range(start, stop, step), count obstacles, and use nested loops to scan a 3x5 camera image row by row.

80. Check: range(5)

Check

Trace it before clicking. How many values print, and what is the last one?

for i in range(5):
    print(i)
passiprinted
1??
2??
3??
4??
5??

Check your understanding

What does range(5) print?

  • A. 0, 1, 2, 3, 4 (correct)
  • B. 1, 2, 3, 4, 5
  • C. 0, 1, 2, 3, 4, 5
  • D. 5 only

Answer: A

Why: range(5) starts at 0 and stops before 5, so it produces five values: 0, 1, 2, 3, 4.

Why B tempts people
This treats 5 as the last label instead of the excluded stop value.
Why C tempts people
This includes both 0 and 5, giving six values instead of five.
Why D tempts people
This treats the argument as the value to print, not the number of passes.

81. What stays fixed: Check: range(5)

Invariant

Step through it

Step through Check: range(5) one row at a time. One of these columns never changes — find it, and say why it cannot.

  1. Step 1: pass is 1
  2. Step 2: pass is 2
  3. Step 3: pass is 3
  4. Step 4: pass is 4
  5. Step 5: pass is 5

82. Rule out three: Check: range(start, stop, step)

Elimination

Eliminate the wrong options

Which values does range(1, 10, 2) produce?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. 1, 3, 5, 7, 9
  • B. 1, 3, 5, 7, 9, 10
  • C. 1, 2, 3, 4, 5, 6, 7, 8, 9
  • D. 0, 2, 4, 6, 8

Survives elimination: A

Why: Start at 1, add 2 each time, and stop before 10. That gives 1, 3, 5, 7, 9.

83. Check: range(start, stop, step)

Check

This is the exact end-excluded rule with a step. Predict it first.

for col in range(1, 10, 2):
    print(col)
passcol
1?
2?
3?
4?
5?

Check your understanding

Which values does range(1, 10, 2) produce?

  • A. 1, 3, 5, 7, 9 (correct)
  • B. 1, 3, 5, 7, 9, 10
  • C. 1, 2, 3, 4, 5, 6, 7, 8, 9
  • D. 0, 2, 4, 6, 8

Answer: A

Why: Start at 1, add 2 each time, and stop before 10. That gives 1, 3, 5, 7, 9.

Why B tempts people
This includes the stop value 10, but stops are excluded in range().
Why C tempts people
This ignores the step of 2 and counts by ones.
Why D tempts people
This uses the default start 0 instead of the given start 1.

84. What each one costs: Check: range(start, stop, step)

Trade off

Comparison matrix

From Check: range(start, stop, step): every row here is a choice with a cost. Fill the col column, then say which row you would actually pick and what you give up for it.

passcol
1?
2?
3?
4?
5?

85. Check: count close readings

Check

A reading below 5 is an obstacle. Trace the counter before choosing.

readings = [12, 8, 3, 15, 4]
obstacles = 0

for distance in readings:
    if distance < 5:
        obstacles = obstacles + 1

print(obstacles)
distancebelow 5?counter after
12False?
8False?
3True?
15False?
4True?

Check your understanding

What does this program print?

  • A. 2 (correct)
  • B. 1
  • C. 5
  • D. 3

Answer: A

Why: Only 3 and 4 are below 5, so the counter increases twice and prints 2.

Why B tempts people
This is what you get if you reset the counter inside the loop or only remember the last close reading.
Why C tempts people
This counts every reading instead of only readings below 5.
Why D tempts people
This counts 8 as close, but the test is strictly below 5.

86. Fill in: counter after for Check: count close readings

Comparison

Comparison matrix

From Check: count close readings: refill the counter after column from what you know. The rest of the table is as it appeared.

distancebelow 5?counter after
12False?
8False?
3True?
15False?
4True?

87. Check: grid scan size

Check

A 3-row, 5-column camera image is scanned with one visit per row-column pair.

row countcolumns per rowtotal positions
35?

Check your understanding

How many total positions does a 3x5 grid scan visit?

  • A. 15 (correct)
  • B. 8
  • C. 5
  • D. 12

Answer: A

Why: The outer loop runs 3 rows, and the inner loop runs 5 columns for each row. 3 times 5 is 15 positions.

Why B tempts people
This adds rows and columns instead of multiplying nested-loop visits.
Why C tempts people
This counts only one row of columns.
Why D tempts people
This is an off-by-one count that treats the rows or columns as if one value were skipped.

88. Rule out three: Check: for or while?

Elimination

Eliminate the wrong options

Which robot behavior is the best fit for a for loop?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. Take exactly 5 sensor readings, then stop.
  • B. Drive until the robot reaches the goal.
  • C. Keep asking until the user types the password.
  • D. Turn until the camera no longer sees a wall.

Survives elimination: A

Why: A for loop is best when the count or the items are known in advance. Exactly 5 readings is known before the loop starts.

89. Check: for or while?

Check

Choose the behavior that best matches a for loop.

Check your understanding

Which robot behavior is the best fit for a for loop?

  • A. Take exactly 5 sensor readings, then stop. (correct)
  • B. Drive until the robot reaches the goal.
  • C. Keep asking until the user types the password.
  • D. Turn until the camera no longer sees a wall.

Answer: A

Why: A for loop is best when the count or the items are known in advance. Exactly 5 readings is known before the loop starts.

Why B tempts people
That stop time depends on the world changing, so it fits while better.
Why C tempts people
That repeats an unknown number of times until a condition changes, so it fits while better.
Why D tempts people
That depends on a sensor condition changing, so it fits while better.

90. Connect it up: for Loops as Robot Scanning Loops

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — The for-loop recipe · Why this matters for robots · For vs while · The shape of a for loop · The stop is a wall, not a tile. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

91. You can now scan like a robot

Recap

You can use for item in list to process every sensor reading, and range(n) to repeat exactly N times.

You can explain the big trap: range(5) gives 0, 1, 2, 3, 4 because the stop value is excluded.

You can use range(start, stop, step) for scan patterns, like every other column.

You can use counters, indexes, enumerate(), and nested loops to scan a 3x5 camera grid and count what the robot sees.

robot problemloop choice
known readings, rows, columns, or repeat countfor
unknown repeats until a sensor or goal changeswhile

Sources

  1. Python 3 Tutorial - 4.2 for Statements
  2. Python 3 Library Reference - range
  3. Python 3 Library Reference - enumerate and len
  4. All snippets executed under CPython 3.12.4; outputs and trace tables copied from real runs. — Author verification run, 2026-06-18 (Pre-COSMOS Day 8 upgrade).

Want this taught 1-on-1? Alexander tutors Python — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108