The Edit-Run-Observe Loop

Lesson 2 of 9020 minStart Here: Python as a Working Tool
In this lesson5 sections

If a mechanic replaces a cable, a cassette, and a chain before testing the bike, the rattle may disappear without revealing which change fixed it. Small, separate edits make a program easier to investigate for the same reason.

By the end of this page you can run a short program and change one thing at a time. After each run you can name the line that owns every difference in the output.

The whiteboard belongs to Priya today, and the figure she is asked for most is how many jobs are still waiting. We build that figure once and then disturb it three times. Each disturbance stays small enough to read as a diff against the run before it.

Run once, then change one thing

Three names hold the state of the board. jobs_on_board is everything chalked up this morning, and jobs_done is what has rolled back out of the workshop. jobs_left is the figure Priya reads out when someone asks how long the queue is.

Read this before running anything:

jobs_on_board = 9
jobs_done = 4
jobs_left = jobs_on_board - jobs_done

Line 3 subtracts at the moment the interpreter reaches it and binds the finished number 5 to jobs_left. It is a subtraction that happened, not a formula that keeps watching the two names above it.

Run the program and read the one sentence it prints:

Reporting the queue length from a subtraction and an f-string

Python 3 · Edit the code and run it without leaving the lesson.

Language
Run code to see results here.

The subtraction on line 4 produced 5, and the f-string on line 6 pulled mechanic, jobs_left, and jobs_on_board into one sentence: Priya has 5 jobs left of 9.

The edit that does not spread

Priya wheels out three more bikes, so jobs_done becomes 7. The tempting prediction is that jobs_left drops to 2. It does not. Line 4 finished its subtraction long before the new line runs. Rebinding jobs_done underneath it moves one name and leaves the other where it was.

The only change below is that rebinding plus a probe print, so you can watch the two names disagree:

Rebinding a finished job count and watching the queue figure stay put

Python 3 · Edit the code and run it without leaving the lesson.

Language
Run code to see results here.

The run says jobs_done is now 7 and then Priya has 5 jobs left of 9, two lines that contradict each other because only one of the two names was rebound.

To recompute a result from changed inputs, run the calculation again. Reassigning an input does not automatically update a result stored earlier.

What the f-string prefix does

One character is the difference between a sentence that reads names and a sentence that merely quotes them. The next run adds a third print, identical to the second except for the f before its opening quote. Without that prefix, {mechanic} is not an instruction, just braces around a word Python never looks up.

Nothing fails here, and that is the danger: the label comes out wrong and Python raises nothing at all.

Printing the same sentence with and without the f prefix

Python 3 · Edit the code and run it without leaving the lesson.

Language
Run code to see results here.

The third output line is {mechanic} has {jobs_left} jobs left of {jobs_on_board}, printed character for character as typed, sitting directly under the correct version of itself.

Your turn: catch what print gives back

For the last edit, drop the unprefixed line and try board_receipt = print(...). The sentence appears on screen, but the assignment stores the value returned by the call. print returns None, so that is what the name holds. To keep the sentence for another use, build the string separately and then print it.

Run it, then strip print( off the front of line 9 and its closing bracket off the end, leaving board_receipt = f"{mechanic} has {jobs_left} jobs left of {jobs_on_board}". The last line stops reporting None and carries the sentence instead.

Binding a name to the value print hands back

Python 3 · Edit the code and run it without leaving the lesson.

Language
Run code to see results here.

The final line reads board_receipt holds: None, because print put the sentence on screen first and then returned None for the name to catch.

Common traps

  • Changing two lines between runs, which leaves you unable to say which one moved the output.

  • Waiting for jobs_left to catch up after jobs_done moves, when only re-running the subtraction will do it.

  • Typing the braces and forgetting the f, which ships a label full of variable names to a real customer.

  • Treating board_receipt as the sentence rather than as None, then wondering why the report line says None.

Next is Checkpoint: Read Before You Run. It hands you three snippets from a market stall and asks for the output before you press Run.