Program Execution Model Visualizations

An execution model tells you what a program means while it runs. Source code is static; execution is a sequence of current lines, bindings, object changes, branches, and outputs. This collection makes that hidden sequence visible before later lessons ask you to reason about loops, data structures, or recursion at full speed.

The order matters. First learn to follow the program counter. Then separate a name from the object it reaches. Those two ideas explain most beginner surprises without inventing folklore about values "living inside" variables.

How to read an execution-model lesson

Track two questions on every beat:

  • Which source line is running now?
  • Did the program change a binding, change an object, or only inspect state?

The current line locates the action. The state panel or name-object graph tells you what the action did. If those two surfaces disagree, your trace is wrong.

Execution-model lessons

LessonMain ideaWhat to watch
Execution TraceA program runs one statement at a time under a moving program counterloop-back and exit jumps, variable updates, and output
Variables & MutationAssignment changes a name binding; mutation changes an existing objectbinding arrows stay during mutation and move during rebinding
Arrays & IndexingA non-negative index is a slot coordinate from 0; length is the first past-end indexrange(len(values)) stops safely before the no-slot boundary
Loops & InvariantsA checkpoint promise turns repeated updates into a proof of the final resultthe proved prefix, the next candidate, and the false condition

Start with Execution Trace. It gives you the debugger grammar: current line, current state, and a ledger of what executed.

Then open Variables & Mutation. The same program-counter grammar now drives a memory graph. A shared list makes aliasing concrete, and the immutable-int contrast shows why operator syntax alone cannot tell you whether an update mutates.

Continue with Arrays & Indexing. A fixed row of slots turns i into a coordinate: 0 names the first slot, 2 names the last, and 3 names no slot at all. The default run first stops safely before 3, then really tries values[3] and raises IndexError, so the usual range(len(values)) pattern stops looking like a spell someone copied from Stack Overflow.

Finish with Loops & Invariants. The same i now marks a proof boundary. A maximum scan establishes a claim for the first value, restores it as each candidate joins the prefix, and uses the false loop condition to turn a prefix fact into a whole-list answer. The wrong best = 0 variant shows exactly where that chain can break.

All execution-model visualizations

Choose a lesson below and step one beat at a time. Do not ask only what value changed. Ask where that value lives and which name can still reach it.