1 of 60

COMPUTER

PROGRAMMING

Deck 4

How Can a Program Repeat Work

Without Repeating Code?

Loops, state, stopping rules — and evidence that the process is correct

Guan-Ju Peng @ AM, NCHU

Deck 4 | 1

2 of 60

Our tool can judge one trip. What about the next?

Preserve Deck 3: the validation rules and the four-line report already work.

Bridge from Deck 3

Deck 4 | 2

Version 0.3

Read one trip.

Validate it.

Print one report or one error.

Version 0.4

Read another trip.

Keep useful totals.

Stop when the user is finished.

New problem: repeat the same policy without copying the whole script.

3 of 60

The request is “keep going, then summarize”

Driving problem: enter several trips, skip invalid records, and finish with a useful summary.

Driving problem

Deck 4 | 3

Input session

Campus / 12.5 km / 45 min

Bad / −1 km / 30 min

Station / 3.5 km / 30 min

DONE

Expected summary

Accepted trips: 2

Total distance: 16.00 km

Total duration: 75 min

Overall speed: 12.80 km/h

The rejected record and the stop command must not enter the totals.

4 of 60

Today’s inquiry ladder

Driving question: How can a program repeat work without repeating code?

Roadmap

Deck 4 | 4

01

What is the unit of work we need to repeat?

02

How can we visit each item with a for loop?

03

What must the program remember across iterations?

04

How do we repeat until a condition or command says stop?

05

How do we stop, skip, and keep making progress?

06

How can we verify a loop with AI as an assistant?

Build: Trip Log v0.4 | AI skill: trace and debug | Foundations: loops + memory locality

5 of 60

What is the unit of work we need to repeat?

Q1 · A new requirement creates a need for a new idea.

Q1 · Driving sub-question

Deck 4 | 5

Q1

“Let me enter another trip.”

​

Which steps should run again —

and which should run only once?

Separate per-record work from setup and the final summary.

6 of 60

Copying the script is not a repetition strategy

A fixed number of copies hard-codes the number of trips.

Q1 · Motivation

Deck 4 | 6

Copy and paste

Read → validate → report

Read → validate → report

Read → validate → report

​

What if there is a fourth trip?

Describe the rule once

While there is more input:

read one record

validate it

report and update if valid

A loop repeats a block; its control rule decides whether there is another iteration.

7 of 60

Draw the process before choosing syntax

One iteration handles one candidate record, not the whole session.

Q1 · Decomposition

Deck 4 | 7

Initialize

state

Read

next record

Validate

Report +

update

Repeat

Once before

Create the count and totals.

Once after

Summarize only accepted records.

Predict the process first. Then select a loop that expresses it.

8 of 60

Agree on the repeated-input contract

Version 0.4 adds an input protocol; it does not silently change the earlier data rules.

Q1 · Specification

Deck 4 | 8

Situation

Required behavior

Route is exactly DONE

Stop before distance/time prompts; do not count it.

A complete record is invalid

Print the first error; leave totals unchanged; read a new route.

A complete record is valid

Preserve the Deck 3 report and update totals once.

No accepted trips at the end

Print a clear message; do not divide by zero.

Other scope limits

Numeric conversion succeeds; values/totals are classroom-sized.

Zero distance is valid. DONE is a command, not an empty or numeric record.

9 of 60

How can we visit each item with a for loop?

Q2 · A new requirement creates a need for a new idea.

Q2 · Driving sub-question

Deck 4 | 9

Q2

One letter at a time.

One numbered attempt at a time.

​

How can one block work for every item?

A for loop requests items from an iterable and runs its body for each one.

10 of 60

One item is assigned on each iteration

An iterable can supply successive items; repeated values remain separate items.

Q2 · for as repeated binding

Deck 4 | 10

[P1] [P2]

PYTHON

for character in "loop":

print(character)

EQUIVALENT TRACE FOR THIS EXAMPLE

character = "l"

print(character)

character = "o"

print(character)

character = "o"

print(character)

character = "p"

print(character)

Output order:

l → o → o → p

for visits the items supplied by the iterable; it does not remove duplicates.

11 of 60

Indentation tells us what repeats

The statement after the loop belongs to the surrounding block.

Q2 · Block boundaries

Deck 4 | 11

[P2]

PYTHON

for attempt in range(1, 4):

print("Trip", attempt)

print("Finished")

Predict first

How many trips?

How many “Finished” lines?

​

Move the last line inward.

What changes?

The loop body is the indented block — not everything written below for.

12 of 60

range describes an integer sequence

start is included; stop is excluded; step determines the direction.

Q2 · range(start, stop, step)

Deck 4 | 12

[P1] [P3]

Expression

Values produced

Reason

range(4)

0, 1, 2, 3

Default start 0, step 1

range(1, 4)

1, 2, 3

Stop 4 is excluded

range(6, 0, -2)

6, 4, 2

A negative step moves down

range(8, 3)

No values

Positive step cannot reach the stop

range(0, 5, 0)

ValueError

The step cannot be zero

A range stores a compact description; it does not build a list of all its integers.

13 of 60

Quick check: predict the values and body count

Three minutes: write the sequences first, then test your predictions.

Q2 · Prediction challenge

Deck 4 | 13

[P3]

Expression

Your sequence

Body executions

range(1, 4)

?

?

range(4)

?

?

range(5, 1, -2)

?

?

range(2, 2)

?

?

Zero iterations is normal behavior, not necessarily a bug.

14 of 60

A known number of attempts fits range

For now: three inputs, with parsing assumed to succeed.

Q2 · Fixed-count input

Deck 4 | 14

[P1] [P2]

PYTHON

for attempt in range(1, 4):

duration_min = int(input("Minutes: "))

if duration_min > 0:

print("Accepted", duration_min)

else:

print("Rejected")

Three iterations means three attempts — not necessarily three accepted records.

15 of 60

What must the program remember across iterations?

Q3 · A new requirement creates a need for a new idea.

Q3 · Driving sub-question

Deck 4 | 15

Q3

The next trip arrives.

​

How do we remember how many were accepted

and how far they traveled altogether?

Loop state carries information from earlier iterations into the next one.

16 of 60

Give every state variable a job

Initialize the state once; update it only when the corresponding event occurs.

Q3 · Counters and accumulators

Deck 4 | 16

[P4]

Name

Before input

After an accepted trip

accepted_count

0

accepted_count += 1

total_km

0.0

total_km += distance_km

total_min

0

total_min += duration_min

Counter: how many?

Accumulator: how much altogether?

A skipped record must leave all three variables unchanged.

17 of 60

A small sum makes the state visible

Contract: n is a non-negative integer; compute 1 + 2 + ... + n.

Q3 · Trace before trusting

Deck 4 | 17

[P1]

PYTHON

n = 4

total = 0

for i in range(1, n + 1):

total += i

print(total)

i

Before

After

1

0

1

2

1

3

3

3

6

4

6

10

Invariant: after each iteration, total is the sum of the items processed so far.

18 of 60

Where does initialization belong?

Prepared faulty teaching example — not a recorded AI response.

Q3 · State-reset bug

Deck 4 | 18

[P2]

FAULTY · RESETS EVERY TIME

for i in range(1, 5):

total = 0

total += i

print(total)

REPAIRED · INITIALIZES ONCE

total = 0

for i in range(1, 5):

total += i

print(total)

Predict both results before pressing Run.

Totals live across the session. Per-record fields are refreshed each iteration.

19 of 60

Trace the accepted prefix, not every attempt

A loop invariant is a statement that remains true as the loop progresses.

Q3 · Accepted-only invariant

Deck 4 | 19

Record

Action

Count

Total km

Total min

Initial

—

0

0.0

0

Campus / 12.5 / 45

Accept

1

12.5

45

Bad / −1 / 30

Skip

1

12.5

45

Station / 3.5 / 30

Accept

2

16.0

75

DONE

Stop

2

16.0

75

After each record, the count and sums describe exactly the accepted records so far.

20 of 60

Which average actually answers the question?

A session summary must preserve the meaning of distance and elapsed time.

Q3 · Aggregation model

Deck 4 | 20

Mean trip duration

75 min / 2 accepted trips

​

37.50 min per trip

Overall average speed

16 km / (75 min / 60)

​

12.80 km/h over the session

Do not average the two speed numbers: (16.67 + 7.00) / 2 answers a different question.

21 of 60

Lab A: read three durations and report their mean

Seven minutes · first assume all three inputs are positive whole minutes.

Q3 · Hands-on · 7 minutes

Deck 4 | 21

01

Initialize a total once.

02

Read and add three values with one for loop.

03

Print the mean after the loop.

04

Predict 10, 20, 30; then run your program.

Extension question: if one attempt is rejected, is dividing by 3 still justified?

22 of 60

How do we repeat until the user is finished?

Q4 · A new requirement creates a need for a new idea.

Q4 · Driving sub-question

Deck 4 | 22

Q4

We do not know the number of trips in advance.

​

What should decide whether

the next iteration happens?

A while loop repeats while its condition remains true.

23 of 60

while checks its condition before every iteration

The condition can be false before the body has run even once.

Q4 · Condition-controlled repetition

Deck 4 | 23

[P2]

PYTHON

remaining = 3

while remaining > 0:

print(remaining)

remaining -= 1

print("Go")

remaining > 0?

Print; subtract 1

True

False

Print “Go”

Ask: what can change before the next condition check?

24 of 60

Two loops can express the same finite process

Choose the form that makes the source of repetition easiest to see.

Q4 · for versus while

Deck 4 | 24

[P1] [P2]

ITEM-DRIVEN

for remaining in range(3, 0, -1):

print(remaining)

print("Go")

CONDITION-DRIVEN

remaining = 3

while remaining > 0:

print(remaining)

remaining -= 1

print("Go")

“Known count → for” is a useful example, not a complete definition of for.

25 of 60

Make the stop command unambiguous

Read the route label first. A stop command must not be parsed as a trip.

Q4 · Sentinel protocol

Deck 4 | 25

[P2] [P4]

PYTHON

while True:

route_name = input("Route label (DONE to finish): ")

if route_name == "DONE":

break

​

distance_km = float(input("Distance in km: "))

duration_min = int(input("Duration in minutes: "))

# Validate, report, and update one record here.

DONE is checked before numeric input. A valid zero-distance trip is still data.

26 of 60

Choose a loop from the problem, not from habit

Identify where the next item or stopping condition comes from.

Q4 · Design choice

Deck 4 | 26

[P1] [P2]

Task

Natural expression

Control source

Visit each character in a word

for character in text

Next item from the iterable

Make exactly n attempts

for attempt in range(n)

A finite integer sequence

Read until DONE

while True + break

An explicit user command

Collect n accepted records

while accepted_count < n

A state condition

The best loop makes “what comes next?” and “when do we stop?” explicit.

27 of 60

Three attempts is not three accepted values

Only successful records should advance an accepted-count target.

Q4 · Progress means the right thing

Deck 4 | 27

[P2]

PYTHON

accepted_count = 0

while accepted_count < 3:

duration_min = int(input("Minutes: "))

if duration_min > 0:

accepted_count += 1

print("Accepted:", accepted_count)

Trace this input

0

20

30

40

​

How many attempts?

A condition-controlled loop stops only if the required progress actually occurs.

28 of 60

How do we stop, skip, and keep making progress?

Q5 · A new requirement creates a need for a new idea.

Q5 · Driving sub-question

Deck 4 | 28

Q5

An invalid record should not end the session.

DONE should.

​

How do we express those different actions?

break leaves the loop; continue skips the rest of the current iteration.

29 of 60

Stop the session or skip this record?

Both change the control flow, but they lead to different destinations.

Q5 · break and continue

Deck 4 | 29

[P4]

break

Stop this loop.

​

Continue with the first statement

after the loop.

continue

Skip the rest of this body.

​

Start the next cycle

of the same loop.

For our tool: DONE → break. Invalid complete trip → continue.

30 of 60

Reuse the first-error policy; then skip the record

One per-record error message. The full validation order is unchanged.

Q5 · Validation before accumulation

Deck 4 | 30

[P5] [P4]

INSIDE while · AFTER INPUT CONVERSION

error = ""

if route_name == "":

error = "Error: route label must not be empty."

elif not math.isfinite(distance_km):

error = "Error: distance must be finite."

elif distance_km < 0:

error = "Error: distance must be non-negative."

elif duration_min <= 0:

error = "Error: duration must be positive."

​

if error != "":

print(error)

continue

Reset error for each record. Keep accepted totals outside this reset.

31 of 60

Only accepted records reach the update point

The guard separates rejection from the meaningful state change.

Q5 · Update exactly once

Deck 4 | 31

[P4]

INSIDE while · ACCEPTED-RECORD PATH

# The rejection paths have already continued.

miles = distance_km * MILES_PER_KM

speed_kmh = distance_km / (duration_min / 60)

​

# Keep the existing band calculation and report.

​

accepted_count += 1

total_km += distance_km

total_min += duration_min

Invariant check: did this accepted record enter each total exactly once?

32 of 60

The final summary belongs after the loop

Zero accepted records is a normal outcome of the input protocol.

Q5 · Empty-data guard

Deck 4 | 32

[P2]

OUTSIDE while · ONE FINAL SUMMARY

print(f"Accepted trips: {accepted_count}")

if accepted_count == 0:

print("No valid trips to summarize.")

else:

mean_duration = total_min / accepted_count

overall_speed = total_km / (total_min / 60)

# Print totals and these averages with units.

No data is not the same as a measured zero. Do not divide before checking the count.

33 of 60

continue can skip the update that makes progress

Prepared faulty teaching example — trace it; do not launch an unbounded run.

Q5 · Nontermination bug

Deck 4 | 33

[P4]

FAULTY · READ-ONLY EXERCISE

i = 1

while i <= 3:

if i == 2:

continue

print(i)

i += 1

Bounded trace

i = 1 → print → i = 2

i = 2 → continue

i = 2 → continue

i = 2 → ...

A continue path is still a path. Check what it does to the next condition check.

34 of 60

Explain progress on every path

Passing a few tests does not prove that every possible interaction will terminate.

Q5 · Termination reasoning

Deck 4 | 34

[P2] [P4]

Loop

What progresses?

What must be true?

for over a finite range

The iterator advances

The body completes each time

Countdown while

remaining decreases

The update is not skipped

Trip Log until DONE

Each record returns to a new prompt

The user eventually enters DONE

Waiting for input ≠ spinning through unchanged state.

Describe the stop assumption; do not promise unconditional termination for interactive input.

35 of 60

Nested loops restart the inner work

A break belongs to the innermost enclosing loop, not to every loop.

Q5 · Nested execution

Deck 4 | 35

[P4]

PYTHON

for i in range(1, 3):

for j in range(1, 4):

print(i, j)

REPLACE THE INNER BODY WITH THIS

if j == 2:

break

print(i, j)

Predict both versions

First: how many pairs?

​

Then add the inner break.

Does i = 2 still run?

The inner break does not cancel the next outer iteration.

36 of 60

Lab B: choose the correct stop and skip

Six minutes · a miniature duration-only exercise; not the final route interface.

Q5 · Hands-on · 6 minutes

Deck 4 | 36

[P4]

INCOMPLETE EXERCISE · FILL BEFORE RUNNING

accepted_count = 0

while True:

raw_minutes = input("Minutes (DONE to finish): ")

if raw_minutes == "DONE":

# BLANK 1

duration_min = int(raw_minutes)

if duration_min <= 0:

print("Skip")

# BLANK 2

accepted_count += 1

print(accepted_count)

Predict 0, 20, −5, 30, DONE. Then also check DONE as the very first input.

37 of 60

A loop is a branch back to earlier work

Computer foundations · toy assembly, not actual Python compilation.

Foundations · Backward branch

Deck 4 | 37

TEACHING ISA · NOT PYTHON

LOAD R0, 0

loop: CMP R0, 3

JGE done

OUT R0

ADD R0, 1

JMP loop

done: HALT

What the new pieces mean

JGE: jump if greater or equal.

ADD: increase the register.

JMP loop: go back to the check.

​

The body need not be copied.

The backward branch repeats instructions; the state update changes the next decision.

38 of 60

Trace the machine-level loop to its stopping state

The same instruction sequence runs again with a different register value.

Foundations · Loop trace

Deck 4 | 38

R0 at CMP

Jump to done?

Output

Next R0

0

No

0

1

1

No

1

2

2

No

2

3

3

Yes

No more output

Halt

Quick check: remove ADD. Which state repeats, and why does the loop no longer stop?

39 of 60

Repeated work also means repeated memory access

CPU caches help service some accesses without going all the way to RAM.

Foundations · Cache, RAM, storage

Deck 4 | 39

[H1] [H2]

CPU

execution

CPU caches

small, nearby

RAM

larger working memory

Cache / RAM

Keep working data available

while the program runs.

SSD / other storage

Keeps saved files persistently.

Accessed through the storage system.

Saving a file to an SSD and fetching a cache line are different operations.

40 of 60

Why reuse and nearby addresses can help

Locality is about memory access patterns — not just how many lines of Python we write.

Foundations · Temporal and spatial locality

Deck 4 | 40

[H1] [H2]

Temporal locality

Access addresses:

100 → 100 → 100

​

Use the same location again soon.

Spatial locality

Access addresses:

100 → 104 → 108

​

Use nearby locations close in time.

These are abstract memory addresses, not a claim about Python object layout.

41 of 60

Cache quick check: follow the addresses

Toy read cache: initially empty; one line holds addresses 0–3; no eviction.

Foundations · Check understanding

Deck 4 | 41

[H1]

Read address

Hit or miss?

Why?

0

?

?

1

?

?

2

?

?

0 again

?

?

Explain the memory behavior. Do not use a tiny Python timing test as proof of cache effects.

42 of 60

How can we verify a loop with AI as an assistant?

Q6 · A new requirement creates a need for a new idea.

Q6 · Driving sub-question

Deck 4 | 42

Q6

One valid trip works.

​

What evidence tells us that empty input,

rejected records, and stopping also work?

Test ordered sessions, inspect state, and challenge every exit and skip path.

43 of 60

A loop needs sequence tests, not only isolated inputs

Each session has a meaningful order and an explicit ending.

Q6 · Test design

Deck 4 | 43

01

No records: DONE immediately.

02

One valid record; then DONE.

03

Valid → invalid → valid; then DONE.

04

All rejected, or a rejected final record.

05

Zero distance, duplicates, and the old 30/60 boundaries.

Also check what must NOT happen: extra prompts, rejected-record reports, or corrupted totals.

44 of 60

Work out the reference answer independently

Use the specification and ordinary arithmetic, not the program’s own output.

Q6 · Session oracle

Deck 4 | 44

Quantity

Independent derivation

Expected display

Accepted trips

Campus + Station only

2

Total distance

12.5 + 3.5

16.00 km

Total duration

45 + 30

75 min

Mean duration

75 / 2

37.50 min

Overall speed

16 / (75 / 60)

12.80 km/h

Write the expected answer before running either the original or the repaired program.

45 of 60

Ask AI for a bounded trace before asking for a rewrite

A reusable instructor demonstration prompt. Live responses vary.

Q6 · AI workflow

Deck 4 | 45

PROMPT TEMPLATE · TRACE → DIAGNOSE → PATCH

Use this contract and code. Do not rewrite it yet.

Trace at most six iterations or complete records.

Show the branch and state before/after each step.

Which path reads new input, skips, or stops?

If a state repeats, explain why progress may fail.

Do not execute a potentially unbounded loop.

Then suggest one minimal patch and tests to rerun.

AI can propose a trace. You must check that it follows the code and the agreed contract.

46 of 60

Find two violations in a loop that still finishes

Prepared faulty teaching example — not an actual AI response.

Q6 · Adversarial review

Deck 4 | 46

ISOLATED TASK · THREE FINITE DISTANCE ATTEMPTS

count = 0

total_km = 0.0

for attempt in range(3):

distance_km = float(input("km: "))

count += 1

total_km = 0.0

if distance_km < 0:

continue

total_km += distance_km

print(count, total_km)

For 12.5, −1, 3.5: expected count = 2, total = 16.0. What does this code actually print?

47 of 60

Repair the invariant with the smallest useful change

Move the counter behind validation; remove the repeated initialization.

Q6 · Minimal patch

Deck 4 | 47

REPAIRED ISOLATED EXAMPLE

count = 0

total_km = 0.0

for attempt in range(3):

distance_km = float(input("km: "))

if distance_km < 0:

continue

count += 1

total_km += distance_km

print(count, total_km)

A good repair restores the stated invariant and survives the relevant regression tests.

48 of 60

Assemble one loop with three visible paths

Continue the same project. Do not hide control flow inside unexplained new abstractions.

Q6 · Integration · trip_log.py

Deck 4 | 48

Path

Action inside the loop

STOP: route is DONE

break before numeric prompts → final summary

SKIP: invalid complete record

print the first error; continue → next route

ACCEPT: valid complete record

report and update once → next route

Before the loop

accepted_count = 0

total_km = 0.0

total_min = 0

After the loop

One summary.

No averages when count is zero.

Totals contain accepted records only.

Keep Deck 3’s report and validation. Add repetition, state, and a final summary.

49 of 60

Lab C: finish the repeated-input tool

Twelve minutes to integrate and test three representative sessions.

Q6 · Build task · 12 minutes

Deck 4 | 49

01

Add trip_log.py; preserve the earlier files.

02

Recognize DONE before numeric input; skip rejected records.

03

Keep each accepted report and update totals once.

04

Print the guarded summary after the loop.

05

Run: immediate DONE, one valid trip, and the mixed session.

Explain one state update, one continue path, and the condition that makes summary division safe.

50 of 60

Push a tested behavior change and its evidence

Use the existing repository and the same GitHub Desktop workflow.

Q6 · Project continuity

Deck 4 | 50

[G1] [G2]

01

Save and run trip_log.py from the existing project folder.

02

Record spec_deck4.md, tests_deck4.md, and ai_use_deck4.md.

03

Review selected changes; commit the working improvement.

04

Push origin; verify the latest commit and files online.

Commit idea: “Add repeated trip input and accepted-only summaries”.

51 of 60

Use the same patterns for a problem you care about

A small project becomes useful when it can handle a whole session.

Project motivation

Deck 4 | 51

Score analyzer

Read scores until DONE.

Reject values outside a stated range.

Count passes; report a mean.

​

A score of 0 is still data.

Study-session log

Read elapsed study minutes.

Skip invalid records.

Report total and mean duration.

​

Define empty-data behavior.

Your own utility

What is one record?

What ends the session?

What should be skipped?

What summary is useful?

​

Write two session tests.

Choose the question first. Then reuse the process, not somebody else’s unexplained code.

52 of 60

Can we answer today’s driving question?

A useful loop has a clear repeated unit, meaningful state, and justified stopping behavior.

Synthesis

Deck 4 | 52

01

Identify the unit of work and what should happen once.

02

Use for to visit items; use while to express a condition.

03

Maintain counters and totals with a clear invariant.

04

Specify stop and skip paths, including empty data.

05

Trace, test, repair, and keep evidence of the final behavior.

Human responsibility today: understand the process, its state, and the evidence that it works.

53 of 60

Exit ticket: explain without pressing Run

Three-minute individual check. The point is reasoning, not guessing syntax.

Exit ticket · 3 minutes

Deck 4 | 53

01

What values does range(1, 4) produce?

02

Why must an invalid trip not increase accepted_count?

03

What should happen when DONE is the first input?

04

Why use total distance / total elapsed time for overall speed?

05

How does reusing an address differ from visiting nearby ones?

Before next class: complete at least six session tests, commit, push, and verify online.

54 of 60

Next: can the tool understand less tidy text?

Deck 5 · How can a program process and interpret text?

Next driving question

Deck 4 | 54

Our current interface

Route, distance, and minutes

arrive as separate inputs.

​

Labels are preserved exactly.

A new request

“Accept this whole line:”

​

Campus, 12.5, 45

​

How do we find and clean each part?

Strings, indexing, slicing, and text methods will make the next improvement possible.

55 of 60

Optional: a loop can have an else clause

The else belongs to the loop and runs on normal completion, not after break.

Appendix · loop-else

Deck 4 | 55

[P1] [P2]

PYTHON

target = 7

for candidate in range(5):

if candidate == target:

print("Found")

break

else:

print("Not found")

Try target = 3 and target = 7. An empty iterable also completes normally.

56 of 60

Optional: recover from malformed numeric text

Parsing failure is different from rejecting a successfully parsed value.

Appendix · Input robustness

Deck 4 | 56

[P6]

INSIDE while · AFTER THE DONE CHECK

raw_distance = input("Distance in km: ")

raw_duration = input("Duration in minutes: ")

try:

distance_km = float(raw_distance)

duration_min = int(raw_duration)

except ValueError:

print("Error: enter distance as a number and minutes as an integer.")

continue

# Apply the same value checks next.

The core version does not claim to recover from parse errors. This extension makes a new promise.

57 of 60

Optional: remember the longest accepted trip

Choose the empty-data and tie policies before implementing the feature.

Appendix · Running maximum

Deck 4 | 57

[P2]

TWO FRAGMENTS · PLACE THEM AT THE INDICATED LOCATIONS

# Initialize before the loop:

longest_min = 0

longest_route = ""

​

# After validation, BEFORE accepted_count += 1:

if accepted_count == 0 or duration_min > longest_min:

longest_min = duration_min

longest_route = route_name

Tie policy: the first accepted trip wins. Empty session: no longest-trip result.

58 of 60

Reference: the session tests that catch common mistakes

Use the student worksheet to record complete expected and actual output.

Appendix · Test matrix

Deck 4 | 58

Session

Expected result

Likely bug exposed

DONE first

0; no averages

Sentinel checked too late

One valid trip; DONE

1; correct report/summary

Body or summary in wrong block

Valid → invalid → valid

Only two accepted in totals

Counting attempts; stale error

Valid → invalid → DONE

Keep the first valid totals

Resetting totals inside the loop

All invalid; DONE

0; no valid-trip report

Unsafe final division

Zero km / positive min

Accept; speed 0.00

Using 0 as a stop command

Also retain the earlier 30/60-minute boundary and finite-distance regression tests.

59 of 60

Technical references

Primary documentation and instructor-authored architecture notes; full links are in speaker notes.

Appendix · References

Deck 4 | 59

[P1] [P2] [P3] [P4] [P5] [P6] [H1] [H2]

Python semantics

[P1] Tutorial: control flow

[P2] Reference: while / for

[P3] Built-in types: range

[P4] Assignment, break, continue

[P5] math.isfinite

[P6] Errors and exceptions

Memory and execution

[H1] Cornell CS 3410: Caches

(2024 course notes)

​

[H2] Cornell: Performance Basics

Numerical Methods for Data Science

Classroom policies, numerical examples, worksheets, and toy traces are identified separately.

60 of 60

Course continuity and provenance

Earlier material, new requirements, and illustrative models are kept distinct.

Appendix · Sources and adaptation

Deck 4 | 60

[G1] [G2]

Course sources

[U1] Deck 3: contract and report

[U2] Legacy Loop: traces and control

[U3] Foundations map: loop + cache

​

New: session protocol, totals, labs,

and independently worked tests.

Teaching conventions

Prepared bugs are clearly labeled.

AI prompts are templates.

Assembly and cache models are toys.

​

[G1–G2] GitHub Desktop:

review, commit, push, verify.

Legacy wording is selectively adapted and technically checked, not copied as authority.