Do not just run Python code. Watch it think.
Code Explorer is a beginner-friendly Python learning tool that turns a program into a step-by-step visual story. Paste or write Python code, run a trace, and move through the recorded execution one instruction at a time.
The workspace helps answer questions that are often difficult when learning Python:
- Which line ran next?
- What changed after this instruction?
- What value does each variable hold right now?
- Is a list being changed, or is a variable being reassigned?
- Which branch of an
ifstatement did Python choose? - How many times did a loop run?
- What local variables exist inside a function?
- Which lines were reached, repeated, or skipped?
- What caused an error, and what should I inspect next?
Code Explorer is intended for learning, experimentation, demonstrations, and small Python exercises. It runs the program privately in the browser and does not require an account, project setup, or server workspace.
This README is the living beginner guide for Code Explorer. It is reviewed whenever the tool changes so its controls, examples, limits, workflows, and expected behavior remain synchronized with the website.
The landing page also links to the separate Python Data Structures and Algorithms workspace. Chunk 7 completes Tier A with 535 reviewed programs, local trace playback, and 18 DSA learning views. Its implemented behavior, limits, and later-tier boundaries are documented in README_DSA.md.
- Choose a learning path
- Start here
- What happens when you run a trace
- Workspace map
- The editor
- Automatic Learning Comments
- Trace controls
- Trace views
- Data views
- Flow views
- Labs
- Starter programs
- Guided beginner walkthroughs
- Expected behavior
- Errors and helpful messages
- Limits
- Saved preferences and privacy
- Tips for learning effectively
- Troubleshooting
- Python concepts glossary
Code Explorer landing page
|
+-- Start exploring Python
| +-- this implemented 134-program Python workspace
| +-- Tool Guide -> README.md
|
+-- Start exploring Python Data Structures and Algorithms
+-- complete Tier A workspace with 535 reviewed programs
+-- local execution, playback, and 18 DSA learning views
+-- Tool Guide -> README_DSA.md
The landing page does not display one ambiguous Tool Guide. Open a workspace to reach the guide that matches the selected learning path.
The Python page identifies itself as Python Programming workspace and explains that learners can write, run, replay, and inspect programs step by step.
The DSA path covers algorithm foundations, abstract data types, Python-native containers, array and sequence techniques, searching, sorting, stacks, queues, deques, linked structures, hash tables, sets, trees, binary search trees, heaps, priority queues, tries, string-search algorithms, Union-Find, graph representations, traversal, connectivity, shortest paths, spanning trees, recursion, backtracking, divide and conquer, greedy algorithms, dynamic programming, bit manipulation, elementary mathematical algorithms, boundary investigations, debugging investigations, and integrated guided challenges. All 535 approved Tier A programs are implemented and documented in README_DSA.md. Tier B and Tier C remain separate planning references, not learner-visible promises.
- Open Code Explorer.
- Select Start exploring Python.
- Leave the starter program in the editor, or replace it with your own Python.
- Select Run trace.
- Use the Next step button to move through the execution.
- Read the explanation in Trace > Story.
- Open Data > Variables to inspect a value in detail.
- Open Flow > Loop Table if the program contains a loop.
The first Python runtime load can take longer than later runs. Wait until the header reports Python ready.
price = 8
quantity = 3
total = price * quantity
print("Total:", total)Expected final output:
Total: 24
Expected learning story:
Step 1: price is created with the value 8
Step 2: quantity is created with the value 3
Step 3: total is created from price * quantity
Step 4: the text and final value are sent to the console
The exact number of recorded steps can include function return or completion events. The important idea is that each selected step represents an observed moment in the real execution.
Your Python source
|
v
Select Run trace
|
v
Python executes the program
|
+--------------------+
| |
v v
Execution snapshots Console output
|
v
Recorded timeline
|
+----------+-----------+-----------+
| | | |
v v v v
TRACE DATA FLOW LABS
| | | |
v v v v
Explanations Variables Paths and Inputs, run
and errors and values loop views comparisons,
and bookmarks
Running a trace does not slowly execute Python in front of you. The program runs first, Code Explorer records a bounded timeline, and the playback controls let you study that timeline at your own pace.
This distinction matters for breakpoints. A Code Explorer breakpoint pauses timeline playback when it reaches a marked source line. It does not pause the original Python process while that process is running.
The workspace is organized into four learning areas. Each area groups views that answer a related kind of question.
CODE EXPLORER WORKSPACE
|
+-- EDITOR
| +-- Python source
| +-- Wrap on or off
| +-- Font size
| +-- Copy complete program
| +-- Paste complete program
| +-- Line numbers and replay breakpoints
| +-- Automatic comments on or off inside the editor
| +-- Exportable Learning Comments study copy
|
+-- TRACE: What is Python doing now?
| +-- Story
| +-- Before and After
| +-- Conditions
| +-- Function Journey
| +-- Error Coach
|
+-- DATA: What values and objects exist now?
| +-- Variables
| +-- Watches
| +-- Structures
| +-- References
| +-- Mutation Explorer
|
+-- FLOW: Where did execution travel?
| +-- Execution Path
| +-- Coverage
| +-- Loop Table
| +-- Loop Lab
|
+-- LABS: How can I experiment with the trace?
| +-- Input Playground
| +-- Compare Runs
| +-- Trace Bookmarks
|
+-- PLAYBACK
| +-- Previous
| +-- Play or pause
| +-- Next
| +-- Restart
| +-- Bookmark
| +-- Timeline slider
| +-- Playback speed
|
+-- CONSOLE OUTPUT
+-- Output visible at the selected step
+-- Runtime or syntax error details
What are you wondering?
|
+-- "What did this line do?"
| -> Trace > Story
|
+-- "Exactly what value changed?"
| -> Trace > Before and After
|
+-- "Why did Python choose this branch?"
| -> Trace > Conditions
|
+-- "What happened inside the function?"
| -> Trace > Function Journey
|
+-- "Why did the program stop?"
| -> Trace > Error Coach
|
+-- "What is inside this variable?"
| -> Data > Variables
|
+-- "How do I keep an eye on this name?"
| -> Data > Watches
|
+-- "What are the indexes or keys?"
| -> Data > Structures
|
+-- "Do two names point to the same object?"
| -> Data > References
|
+-- "Was this list changed or replaced?"
| -> Data > Mutation Explorer
|
+-- "Which line ran after which line?"
| -> Flow > Execution Path
|
+-- "Which source lines were skipped?"
| -> Flow > Coverage
|
+-- "How did values differ per iteration?"
| -> Flow > Loop Table
|
+-- "Where am I inside the loop?"
| -> Flow > Loop Lab
|
+-- "How do I provide input()?"
| -> Labs > Input Playground
|
+-- "What changes when I use different input?"
| -> Labs > Compare Runs
|
+-- "How do I save important trace moments?"
| -> Labs > Trace Bookmarks
|
+-- "Can I read teaching comments without changing my code?"
| -> Run a trace, then select Automatic comments
|
+-- "Can I export a real commented copy of my program?"
-> Run a trace, then select Learning comments
The editor is where you write, paste, and review the complete Python program.
- Python syntax is highlighted when the enhanced editor is available.
- Selecting an inbuilt example shows its reviewed title and description directly above the editor.
- The selected question remains visible while you edit that example and after a reload.
- Pasting or replacing the complete document clears the selected question because Code Explorer must not invent curriculum wording for custom source.
- The footer reports the current number of lines and characters.
- Your current source is saved automatically in the browser.
- Reloading the workspace restores the most recently saved source.
- Editing source after a trace clears that old trace because it no longer describes the current program.
- If the enhanced editor cannot load, Code Explorer provides a basic text editor so source editing remains available.
Select Wrap on or Wrap off in the editor toolbar.
- Wrap on keeps long lines inside the visible editor width.
- Wrap off preserves each source line on one visual row and allows horizontal scrolling.
- Wrapping changes presentation only. It does not insert newline characters into the Python source.
- The choice is remembered after a reload.
Choose one of these sizes:
12 px 14 px 16 px 18 px 20 px 22 px
The font-size choice affects editor readability only. It does not change the code or the graph zoom level. The choice is remembered after a reload.
The toolbar actions operate on the complete editor document.
- Copy copies the entire Python program, not only the current selection.
- Paste replaces the entire editor document with plain text from the clipboard.
- Pasting new source clears an old trace.
- An empty clipboard does not erase the current program.
- If clipboard reading is blocked, Code Explorer shows a clear permission alert and suggests using
Ctrl+Vinside the editor. - If copying is blocked, Code Explorer suggests selecting the editor and using
Ctrl+C.
Select a line number in the editor gutter to add or remove a breakpoint.
Source line number selected
|
v
Breakpoint marker appears
|
v
Play the recorded trace
|
v
Playback pauses when that source line is reached
Use replay breakpoints when you want automatic playback to stop before a line that deserves closer inspection.
Important behavior:
- Breakpoints affect automatic trace playback.
- Previous, Next, and the timeline slider still work normally.
- A line can be reached several times, so a loop breakpoint can pause repeatedly.
- A breakpoint does not interrupt the original live execution.
After a trace is ready, editor lines communicate execution activity:
- The current line receives the strongest highlight.
- Reached lines are visually marked.
- Repeated lines show that a loop or repeated call visited them more than once.
- Lines that did not run remain unhighlighted.
Use Flow > Coverage when you want a numbered summary instead of editor highlighting.
After a useful trace completes, select Automatic comments off to turn the inline learning view on. Code Explorer places trace-powered notes above supported source lines. Select Automatic comments on to hide them again.
This is a reading mode. The notes look like Python comments, but they are visual editor widgets rather than characters inserted into the document.
ORIGINAL EDITOR DOCUMENT VISUAL LEARNING LAYER
total = 0 # Code Explorer: total became 0.
for number in range(1, 4): # Code Explorer: the body ran 3 times.
total += number # Code Explorer: total was updated.
| |
+------------------+-------------------+
|
v
WHAT THE LEARNER SEES
comment, then source line
|
+----------------+----------------+
| |
v v
Copy still copies Trace line numbers,
original Python breakpoints, and heatmap
remain aligned
Why this matters:
- The program's natural reading flow can be restored instantly.
- Each temporary explanation has a visible Trace note label, so it cannot be mistaken for Python that the learner typed.
- Line numbers still refer to the real Python source.
- Breakpoints and execution highlighting do not move to artificial comment lines.
- Copy and Paste continue to operate on the original editor document.
- The learner can compare the explanation with the line it describes without opening another dialog.
The inline view follows the selected comment detail level from the Learning Comments dialog. Guided is the default. If Automatic comments is already on, changing Essential, Guided, or Detailed refreshes the visible notes immediately without rerunning Python.
Automatic comments has a deliberate lifecycle:
No current trace
|
v
Automatic comments disabled
|
| successful or useful partial trace
v
Automatic comments available, initially off
|
+-- select on -> visual notes appear
+-- select off -> visual notes disappear
|
+-- edit, paste, or load another program
| |
| v
| notes and stale trace are cleared
|
+-- start a new run
|
v
old notes hide while new
evidence is collected
If the enhanced CodeMirror editor cannot load, the fallback editor uses a separate read-only commented preview while the original textarea remains the actual source. This keeps the same source-protection promise in both editor modes.
Best for: reading explanations beside source and turning a completed trace into a portable commented study copy of the exact program you ran.
Code Explorer provides two related surfaces from the same conservative note set:
| Surface | Best use | Does it edit source? | What Copy does |
|---|---|---|---|
| Automatic comments editor toggle | Temporarily study explanations beside the related lines | No | The normal editor Copy action copies the original Python program |
| Learning comments dialog | Preview, copy, or deliberately adopt a real commented document | No by default | Copy commented code copies source plus generated # Code Explorer: lines |
Use the editor toggle when you want to preserve flow and switch explanations on and off. Use the dialog when you want a portable study artifact for notes, teaching, or later review.
The Learning Comments dialog presents the generated document as a read-only IDE-style study view. Its structure is designed to make a long commented program easier to scan, not to pretend that the preview is another editable file.
AUTOMATIC LEARNING COMMENTS
+-- Read only status
+-- Comment detail: Essential, Guided, or Detailed
+-- Legend
| +-- purple: trace-powered teaching note
| +-- green: original Python source
+-- IDE study surface
| +-- main.py tab
| +-- visual line-number gutter
| +-- conservative Python syntax colors
| +-- full-width Trace note bands
| +-- Python 3, line count, UTF-8, and LF status
+-- Copy commented code
+-- Replace editor, with confirmation
The study surface follows the website's Light mode or Dark mode. There is no separate IDE-theme setting to learn or save. Light mode uses a bright editor palette, while Dark mode uses a low-glare dark palette with stronger contrast for comments, strings, keywords, numbers, and note text.
The visual line numbers, file tab, legend, colors, and status strip are presentation only. Copy commented code copies the exact generated Python document, including real # Code Explorer: lines, but it never copies the visual gutter, badges, file name, or status text. The lightweight syntax coloring also changes presentation only. It does not rewrite, parse differently, or execute the displayed source.
On a narrow phone screen, the dialog becomes a compact vertical workspace. The preview scrolls inside its own bounded region, long notes wrap within their rows, and the whole page avoids sideways scrolling. On a larger screen, the same hierarchy has more room without stretching the code into an excessively wide reading line.
Automatic Learning Comments combines two kinds of evidence. Python's parsed syntax explains the role of a statement, while the completed trace supplies facts that were actually observed during this run.
CURRENT PYTHON SOURCE COMPLETED TRACE
structure of each statement values and execution counts
| |
+------------------+-------------------+
|
v
CONSERVATIVE LEARNING NOTES
|
+---------------+---------------+
| |
v v
Inline editor view Separate export preview
source unchanged source unchanged by default
|
+------+------+
| |
v v
Copy the copy Replace editor only
after confirmation
- Write or load a Python program.
- Select Run trace and wait for the run to finish.
- Choose a study route:
- Select Automatic comments off to read notes inside the editor without changing the document.
- Select Learning comments to open the export preview.
- Choose the amount of detail.
- Read the preview before copying or replacing anything.
- Select Copy commented code to keep the editor untouched, or select Replace editor and confirm the replacement.
The button is disabled before a useful trace exists. This prevents Code Explorer from presenting source-only guesses as observed runtime explanations.
| Level | What it includes | When to use it |
|---|---|---|
| Essential | The most important structure and state-changing statements | First reading, classroom projection, or a short revision sheet |
| Guided | Essential notes plus common calls, loop bodies, conditions, and useful observed facts | Recommended for most beginners |
| Detailed | Every supported explanation that Code Explorer can justify | Careful self-study or reviewing a longer example |
Changing the detail level refreshes the export preview and any visible inline notes. It does not rerun Python and does not edit the original program.
Original program:
total = 0
for number in range(1, 4):
total += number
print(total)A generated preview can look like this:
# Code Explorer: Creates or updates total. This run stored 0.
total = 0
# Code Explorer: Repeats the indented block for values from range(1, 4). The body started 3 times in this run.
for number in range(1, 4):
# Code Explorer: Updates total using its previous value and number. This line executed 3 times.
total += number
# Code Explorer: Attempts to evaluate the supplied values and send them to Console Output with print.
print(total)The exact wording depends on the source and recorded evidence. A value that changes several times is described as repeated behavior instead of being presented as one permanent value.
- Assignments and augmented assignments such as
total += number if,elif, andelsebranchesforandwhileloops- Function definitions, calls, and returns
breakandcontinuetry,except,finally, andraiseinput()andprint()calls- Common list, dictionary, and set mutations
- Imports, context managers, assertions, and simple expression calls
- Observed values, line execution counts, loop body counts, and condition outcomes when trace evidence is available
- An observed exception on a failing statement without claiming that the statement completed
Automatic comments are learning aids, not a proof of every behavior the program could have.
- A comment describes the run that just happened. Another input may choose another branch or produce another value.
- Code Explorer does not invent a note for an unsupported or ambiguous construct.
- Long or complex values may be shortened for readability.
- Floating-point values may be labelled as approximate.
- A missed branch is not described as impossible. It only was not observed in this run.
- Syntax errors cannot produce runtime-backed comments because Python never began executing the program.
Generated lines begin with # Code Explorer:. This recognizable prefix lets the tool remove its own older generated lines before producing another study copy, which prevents duplicate comment layers after a rerun. Comments written by the learner are preserved.
Select Learning comments
|
v
Preview opens, source unchanged
|
+-----+-----+
| |
v v
Close Copy
| |
v v
No change Clipboard receives
commented copy
Replace editor
|
v
Confirmation required
|
+-- Cancel -> source unchanged
+-- Confirm -> commented source becomes editor source
and the old trace is cleared
After replacement, the commented source is saved like any other editor change. Run a new trace if you want the comments to reflect the new document. The separate preview itself is not stored after the trace is cleared or the page is reloaded.
The playback bar controls the recorded timeline.
| Control | Meaning | Expected behavior |
|---|---|---|
| Previous | Move backward one recorded step | Variables, explanation, output, and diagrams return to the earlier snapshot |
| Play or pause | Automatically advance or pause | Playback follows the selected speed and stops at the end or at a breakpoint |
| Next | Move forward one recorded step | Every active view updates to the same selected moment |
| Restart | Return to the first step | The program is not rerun |
| Star | Add or remove a bookmark | The selected step appears in Trace Bookmarks |
| Timeline slider | Jump directly to a step | Useful for long traces and granular control |
| Speed | Choose 0.5x, 1x, or 2x |
Changes playback delay only, not Python execution speed |
The step counter uses this form:
STEP 03 / 09
This means the third recorded snapshot is selected out of nine total snapshots.
The percentage below the slider reports the selected position between the start and end of the trace.
Every view follows the same selected timeline position. Moving one control never creates a separate, conflicting version of program state.
Previous, Next, Play, Restart, or slider
|
v
SELECTED TRACE STEP
|
+-----------+-----------+
| | |
v v v
Source line Variables Console so far
| | |
+-----------+-----------+
|
+-----------+-----------+
| | |
v v v
TRACE DATA FLOW
explanation objects path and loop
|
v
LABS
bookmarks and comparisons
If two views appear to tell different stories, first confirm that they are describing the same selected step and remember that some views emphasize values before a loop body update.
Trace views explain what Python is doing and why.
Best for: reading execution as a beginner-friendly narrative.
Story can show:
- The selected source line
- The kind of instruction, such as assignment, loop, condition, function call, return, output, or error
- A plain-language explanation
- Variables created, changed, or removed by the selected step
- Output produced by that particular step
- Visible variable cards with names, values, and Python types
- The active call stack and local values
Example:
total = 0
total += 5Possible story sequence:
LINE 01 // ASSIGNMENT
Python created total and gave it the value 0.
LINE 02 // ASSIGNMENT
Python updated total from 0 to 5.
Story explanations are educational summaries. They describe observed trace data and common Python statement patterns. They are not a replacement for reading the source line itself.
STORY STEP
|
+-- Where am I?
| +-- Trace step number
| +-- Source line number
| +-- Highlighted editor line
|
+-- What instruction is this?
| +-- Assignment
| +-- Condition
| +-- Loop
| +-- Function call or return
| +-- Output or error
|
+-- What changed?
| +-- Name created
| +-- Value updated
| +-- Name left scope
| +-- No visible value change
|
+-- What context surrounds it?
+-- Visible variables
+-- Active function frames
+-- Output produced so far
Best for: isolating the state change caused by one instruction.
For each affected variable, the view shows:
variable name before value -> after value
Example:
points = 10
points += 3At the second assignment:
points 10 -> 13
Creation and scope changes use readable labels:
not created -> 10
value -> out of scope
If an instruction does not change a visible variable, the view says so instead of inventing a change.
Best for: understanding if, elif, and while decisions.
The Conditions view reports the path Python actually took.
age = 20
has_ticket = True
if age >= 18 and has_ticket:
print("Enter")Expected explanation:
age >= 18 True
and
has_ticket True
True path observed
For supported simple expressions, Code Explorer can break a condition into readable pieces. It recognizes common primitive values, len(name), comparison operators, not, and straightforward and or or combinations.
Code Explorer does not execute the condition a second time. This avoids repeating function calls or other side effects merely to produce an explanation.
For a complex expression that cannot be safely isolated, the view still reports the observed branch and clearly states that the result could not be decomposed.
Best for: seeing how a function call creates a local working area and returns a value.
CALLER
global frame
|
v
FUNCTION
double()
|
v
LOCAL VALUES
number = 4
result = 8
|
v
RETURN
8
Try this program:
def double(number):
result = number * 2
return result
answer = double(4)
print(answer)The view becomes useful after execution has entered a user-defined function. Before that point, it displays a calm empty state.
The Story view also contains the call stack, which is helpful for nested function calls:
global frame
|
+-- outer()
|
+-- inner()
The active frame shows up to six visible local values so the display remains readable.
Best for: turning a Python failure into a specific next step.
The Error Coach shows:
- The original Python error type and message
- A beginner-friendly meaning
- A practical inspection or correction suggestion
Built-in guidance is available for common failures:
| Error type | What it means in beginner language | Tiny example that can cause it | First thing to inspect |
|---|---|---|---|
SyntaxError |
Python could not understand the program's grammar, so execution never started. | if ready is missing its final colon. |
Check the highlighted line and the line immediately before it for missing colons, commas, quotes, or brackets. |
IndentationError |
Statements inside a block do not have the indentation Python expects. It is a specialized kind of SyntaxError. |
Writing print("Go") directly under if ready: without indenting it. |
Align statements that belong to the same block and use spaces consistently. Code Explorer handles compile-time indentation problems through its syntax-error path, so the heading may say SyntaxError while the message describes indentation. |
NameError |
Python tried to use a variable or function name that has not been created in the current scope. | print(score) before assigning score. |
Check spelling, capitalization, statement order, and whether the name exists inside the active function or global scope. |
TypeError |
An operation received a kind of value it cannot use in that way. | "5" + 2 tries to add text and an integer. |
Open Variables and compare the visible types. Convert a value only when that conversion matches the program's intention. |
ValueError |
The operation accepts this general type, but the particular value is unsuitable. | int("twelve") receives text that is not an integer representation. |
Inspect the exact value, including spaces and punctuation, then validate or clean it before conversion. |
IndexError |
A list, tuple, string, or other sequence was asked for a position outside its available range. | colors[2] when colors contains only two items. |
Inspect the sequence length. Indexes begin at 0, so a sequence of length 2 has indexes 0 and 1. |
KeyError |
A dictionary was asked for a key it does not contain. | prices["marker"] when only "pen" and "book" exist. |
Open Structures and inspect the actual keys. Use membership checking or dict.get() when a missing key is an expected possibility. |
ZeroDivisionError |
A division or remainder operation used zero as its divisor. | average = total / count when count is 0. |
Inspect the divisor and decide what the program should do when there are no values to divide by. |
AttributeError |
A value does not provide the requested attribute or method. | name.apend("!") misspells a method and also asks a string for list-like behavior. |
Inspect the value's type and check the attribute or method spelling. Different types provide different methods. |
EOFError |
input() requested another response, but Input Playground had no prepared line left. EOF means end of input. |
Three calls to input() with only two prepared response lines. |
Count the input() calls on the observed path and add one prepared line for each call. |
Do not read an error type as the whole explanation. A Python failure has several useful parts:
ERROR TYPE
What family of problem occurred?
|
v
MESSAGE
What specific operation or value caused Python to stop?
|
v
SOURCE LINE
Which statement was active?
|
v
RECORDED STATE
What values, types, keys, lengths, and frames existed just before it?
|
v
NEXT EXPERIMENT
What one small correction or input change will test your explanation?
An exception is not always a programming mistake. Programs can deliberately raise and catch exceptions to handle expected problems. Error Coach is most important when an error stops the run. If the program catches the exception successfully, execution can continue into its except block instead.
Example:
colors = ["mint", "purple"]
requested_index = 2
print(colors[requested_index])Expected result:
IndexError: list index out of range
Meaning:
The program requested a sequence position that does not exist.
Try this:
Remember that the first index is 0 and the final index is length minus 1.
Use Before and After, Variables, and Structures at the final step to inspect the state that produced the failure.
Data views explain variables, containers, and object relationships at the selected step.
Best for: detailed inspection of one name and its value history.
The scope browser separates:
- Global variables
- Local variables from the active function
Select a variable to inspect:
- Current value
- Python type
- Scope
- Length, when applicable
- Step where it was created
- Most recent recorded change
- Mutable or immutable behavior
- Other visible names sharing the same object
- Nested contents
- Complete meaningful value history
Example value tree:
student dict(2)
|
+-- ["name"] "Aman" str
|
+-- ["scores"] list(3)
|
+-- [0] 72 int
+-- [1] 84 int
+-- [2] 91 int
History rows are clickable. Selecting a history event jumps the complete workspace to that recorded step.
Name does not exist
|
| assignment or parameter binding
v
Name is created in a scope
|
+-------------------------+
| |
v v
Value remains unchanged Value or object changes
| |
| +------+------+
| | |
| v v
| reassigned mutated
| | |
+------------------+-------------+
|
v
More trace steps
|
+---------+---------+
| |
v v
still in scope leaves scope
Use Value History for the vertical timeline, References for shared objects, and Mutation Explorer when the distinction between reassignment and mutation matters.
Best for: following a small set of important variable names across a trace.
To watch a variable:
- Open Data > Variables.
- Select the variable.
- Select Watch.
- Open Data > Watches.
Each watch card shows:
- Variable name
- Current value
- Current Python type
- Whether the name is in scope
- An Inspect action
- A Remove action
If the selected step occurs before a watched variable is created, the card reports that the name is not in scope. It does not silently remove the watch.
Up to 12 names can be watched at once. Watch choices are remembered after reloads, so a watched name can remain useful across edited versions of the program.
Best for: understanding indexes, keys, positions, length, and container contents.
Supported structure presentations include:
listtupledictsetfrozensetstr
List example:
colors = ["mint", "purple", "cyan"]colors: list, 3 items
+-------+----------+
| index | value |
+-------+----------+
| 0 | "mint" |
| 1 | "purple" |
| 2 | "cyan" |
+-------+----------+
Dictionary example:
person = {"name": "Aman", "age": 25}+----------+--------+
| key | value |
+----------+--------+
| "name" | "Aman" |
| "age" | 25 |
+----------+--------+
The view also explains whether the selected name still has its original value, references a different object, or contains an object that was changed in place.
Best for: building a conceptual model of names and objects.
The reference map can contain:
GLOBAL SCOPE
|
v
variable name
|
| references
v
Python object or value
|
+-- nested item
+-- nested item
Aliasing example:
first = [1, 2]
second = first
second.append(3)Conceptual reference map:
first --------+
|
v
Object A
[1, 2, 3]
^
|
second --------+
Both names reference the same list object, so mutation through second is visible through first.
This is a conceptual object-reference map. It is not a display of physical RAM addresses, byte sizes, memory pages, or low-level memory allocation.
Graph controls:
- Use the slider for one-percent zoom control.
- Use minus and plus for five-percent changes.
- Use Fit to place the complete graph inside the visible canvas.
- Pan inside the graph when a larger program extends beyond the visible area.
- Graph zoom is available from 40% to 200%.
Best for: learning the difference between creation, mutation, and reassignment.
The Mutation Explorer focuses on mutable list, dict, and set values.
items = []BEFORE AFTER
items -> name did not exist items -> Object A: []
items.append("book")BEFORE AFTER
items -> Object A: [] items -> Object A: ["book"]
\________________/
same object
items = ["new"]BEFORE AFTER
items -> Object A items -> Object B
\________________/
new object
The view also reports visible aliases, which are other names that reference the same captured object.
Did the name exist before this step?
|
+-- No
| +-- CREATION
| name -> Object A
|
+-- Yes
|
+-- Does it still reference the same object?
|
+-- Yes
| |
| +-- Did visible contents change?
| +-- Yes -> MUTATION
| +-- No -> UNCHANGED
|
+-- No
+-- REASSIGNMENT
name: Object A -> Object B
This decision tree is especially useful when Before and After shows different text but you still need to know whether object identity stayed the same.
Flow views summarize paths, source coverage, and loop behavior.
Latest execution
|
+-- In what order did reached lines connect?
| -> Execution Path
|
+-- Which source lines ran or did not run?
| -> Coverage
|
+-- What values appeared at each loop entry?
| -> Loop Table
|
+-- Which iteration is current, complete, or waiting?
-> Loop Lab
Execution Path asks: "Where did Python travel?"
Coverage asks: "Which source locations did this run touch?"
Loop Table asks: "How did values compare across iterations?"
Loop Lab asks: "Where am I inside the repeated process?"
Best for: seeing the actual order in which source lines were reached.
Example:
count = 2
while count > 0:
print(count)
count -= 1
print("Done")Observed path:
line 1: count = 2
|
v
line 2: while count > 0
|
v
line 3: print(count)
|
v
line 4: count -= 1
|
+----------------+
|
v
line 2 repeated
|
v
line 5: Done
Each node contains:
- Source line number
- Source text
- Number of visits
Repeated transitions receive counts. Loop-back connections are visually distinguished. Selecting a graph node jumps to the first trace step for its source line.
The graph shows the path observed during the latest run. It does not predict every theoretically possible branch.
Execution Path has the same zoom, pan, plus, minus, percentage, and Fit controls as References.
Best for: finding reached, repeated, and missed source lines.
Coverage reports:
- Percentage of nonblank, noncomment source lines reached
- Number of reached lines
- A per-line status
- Repetition count for lines reached more than once
Legend:
✓ reached once
3x reached three times
○ not reached in this run
Selecting a reached line jumps to its first trace step. Selecting a missed line focuses that line in the editor.
Coverage is based on the latest observed run. A missed line is not necessarily incorrect. It may belong to a valid branch that the current inputs did not choose.
Best for: comparing variable values from one iteration to the next.
Try:
total = 0
for number in range(1, 4):
total += number
print(total)Expected table shape:
+-----------+--------+--------+
| Iteration | total | number |
+-----------+--------+--------+
| 1 | 0 | 1 |
| 2 | 1 | 2 |
| 3 | 3 | 3 |
+-----------+--------+--------+
The table captures values at loop-entry snapshots. This means the value shown for an accumulator can represent its state before the body updates it during that iteration.
Select an iteration number to jump directly to that moment in the trace.
Best for: following loop progress as an ordered sequence.
Loop Lab shows:
- Loop type, such as
FOR LOOPorWHILE LOOP - Original loop source
- Current iteration number
- A progress meter
- Completed iterations
- Current iteration
- Waiting iterations
- Loop target or condition summary
FOR LOOP: for number in range(1, 4)
[===========>................] Iteration 2 of 3
✓ Iteration 1 number = 1
● Iteration 2 number = 2
3 Iteration 3 waiting
When a program has no detected for or while loop, both loop views explain that no loop data is available.
Enter loop
|
v
Choose next value or check condition
|
+-- Cannot continue -> leave loop
|
+-- Can continue
|
v
Run loop body
|
+-----+------------------+
| |
v v
ordinary end control statement
| +------+------+
| | |
| v v
| continue break
| | |
+------------------+ v
| leave loop
v
Choose next value or check again
Use Execution Path to see the arrows, Coverage to see skipped source, and Loop Table to see the values carried through the cycle.
Labs help you deliberately vary, compare, and organize executions.
Choose one question
|
v
Prepare input or change one source value
|
v
Run and inspect the trace
|
+-- Save important step -> Trace Bookmarks
|
+-- Save complete run -> Capture Run A
|
v
Change exactly one factor
|
v
Run and capture Run B
|
v
Compare path, state, output, and error
|
v
Explain why the first difference occurred
Keeping one deliberate change between runs makes the comparison easier to explain.
Best for: programs that use input().
Enter one response per line. Python consumes the lines from top to bottom.
Program:
name = input("Your name: ")
age = int(input("Your age: "))
print(name, age)Input Playground:
Aman
25
Expected exchange:
Your name: Aman
Your age: 25
Aman 25
Input rules:
- Each line supplies one
input()response. - Responses are consumed in order.
- Prepared values are plain strings, just like ordinary Python
input()results. - Convert a value with
int(),float(), or another function when required. - If the program asks for more values than were prepared, it stops with
EOFErrorand Error Coach suggests adding another line. - Prepared input is remembered after a reload.
Best for: discovering how changed input or changed source affects behavior.
Recommended workflow:
Prepare first input or first source version
|
v
Run trace
|
v
Capture Run A
|
v
Change input or change the source
|
v
Run trace
|
v
Capture Run B
|
v
Compare inputs, output, step counts,
errors, and first observed difference
Compare Runs checks the recorded line path, console output, and visible variable state for each step. It reports the earliest recorded point where the two runs differ.
Example experiment:
score = int(input("Score: "))
if score >= 50:
print("Pass")
else:
print("Try again")Run A input:
72
Run B input:
40
Expected result:
- Run A prints
Pass. - Run B prints
Try again. - The comparison identifies the first trace position where path or state differs.
Use Clear to remove both captured comparison slots without clearing the current trace.
Best for: creating a personal table of contents for a long trace.
- Move to an important step.
- Select the star in the playback controls.
- Repeat for other important steps.
- Open Labs > Trace Bookmarks.
Each bookmark includes:
- Trace step number
- Source line number
- Source text
- A jump action
- A remove action
Bookmarks belong to the current execution. Running a new trace clears them because old step numbers would no longer describe the new timeline.
Select Examples to open a curated library of 134 programs. The library is a structured beginner curriculum, not a random code collection. It begins with the smallest useful print() programs, progresses through values, decisions, loops, functions, collections, references, debugging, and classes, and places 12 complete guided checkpoints after their prerequisite sections.
The current library is a blend rather than a replacement. The tested 54-program v2 corpus was reviewed, renamed or moved where useful, and combined with 80 new programs. Input, intentional errors, recursion, mutation, shallow copying, and nested collections were preserved instead of being lost during the reorganization.
The lesson row and its read-only preview show:
- The primary topic
- A difficulty level
- The exact number of source lines
- A short learning purpose
- The views that reveal its most useful behavior
- A fixed sequence number
- Recommended prerequisite concepts for guided checkpoints
- A visible learning-error label when failure is intentional
- The complete reviewed source before the learner decides to open it
ALL 134 PROGRAMS
|
+-- 01 First Steps .................... 10
+-- 02 Variables and Types ............ 10
+-- 03 Operators and Expressions ...... 10
+-- 04 Strings ......................... 8
+-- 05 Decisions ...................... 12
+-- 06 Loops .......................... 16
+-- 07 Functions and Scope ............ 16
+-- 08 Collections .................... 16
+-- 09 References and Mutation ......... 8
+-- 10 Input, Errors and Debugging ...... 8
+-- 11 Classes and Objects .............. 8
+-- 12 Guided Mini Programs ............ 12
The active filter reports both the visible count and the complete count. Categories use a vertical navigation region, so a learner never has to hunt left and right for a concept.
The search field finds programs through their complete reviewed information, not only the visible title.
Search words
|
+-- title and topic
+-- category and difficulty
+-- learning-purpose description
+-- recommended views
+-- guided prerequisites
+-- intentional error type
+-- reviewed Python source
|
v
Matching program cards
Search words are combined with AND behavior. Every word must appear somewhere in the same program record. For example:
intentional keyerrorfinds the reviewed dictionary-key investigation even though part of that phrase appears in its error metadata rather than its title.guided mutationnarrows the catalog to Guided Challenge records that also discuss mutation.- A variable, function, class, or method name can match reviewed source code.
The selected category and the search apply together:
Search: list
+
Category: Classes and Objects
|
v
Only class-and-object programs whose reviewed information contains list
Count badges update to show how many current search matches exist in each category. The result summary is announced politely to assistive technology. If nothing matches, the card area explains the result and provides Clear search without changing the selected category.
Search is temporary. The query remains only in the current page memory, is not stored after reload, is not added to analytics, and is never sent over the network.
Selecting a lesson row is now non-destructive. It changes only the read-only preview. The visible editor, saved source, prepared input, and trace remain unchanged until the learner selects Open in Python workspace.
DESKTOP EXAMPLES BROWSER
+------------------+----------------------+--------------------------+
| FIND | CHOOSE | INSPECT |
| | | |
| Search locally | 001 Hello, Python | title and purpose |
| | 002 Print values | difficulty and section |
| All programs 134 | 003 Clear output | prerequisite concepts |
| 01 First Steps | ... | best learning views |
| 02 Variables | | prepared input |
| ... | readable summary | complete read-only code |
| 12 Guided | difficulty and lines | |
| | | [Open in workspace] |
+------------------+----------------------+--------------------------+
PHONE EXAMPLES BROWSER
+----------------------------------+
| FIND AND CHOOSE |
+----------------------------------+
| search and vertical categories |
| one-column lesson rows |
+----------------------------------+
| select one lesson |
| |
| INSPECT |
| full preview and read-only code |
| [Back to program list] |
| [Open in Python workspace] |
+----------------------------------+
On a wide screen, Find, Choose, and Inspect remain visible together. Each region scrolls vertically inside its own boundary. The vertical category rows use larger 15-pixel text, generous height, a complete category name, and a visible result count. The middle rows use larger text, a stable sequence number, a concise two-line summary, difficulty, and exact source length.
The complete reviewed source now appears in a read-only IDE-style frame instead of a plain white code box. It includes:
- A visible
main.pyfile tab and Read only state. - Visual line numbers that are not part of the Python document.
- Lightweight Python syntax colors for keywords, strings, numbers, calls, and comments.
- A low-glare editor surface in both Light mode and Dark mode.
- A status strip showing Python 3, the exact line count, UTF-8, LF, and Preview.
- A 16-pixel desktop code size and 15-pixel phone code size.
- A bounded internal scrollbar for long programs.
The file chrome, line numbers, colors, and status text are presentation only. Open in Python workspace still loads the exact catalog source. The preview never adds its visual line numbers or labels to the editor.
On a narrow screen, Find and Choose appear first. Selecting a lesson opens Inspect as a second screen instead of compressing three columns into the phone width. Back to program list restores the list and keyboard focus to the selected lesson. Selecting a category returns its result list to the first program. Category names wrap inside vertical rows rather than creating horizontal navigation.
Select a lesson row
|
v
Preview metadata and source
|
+-- choose Back or another row
| |
| +-- editor remains unchanged
|
+-- choose Open in Python workspace
|
v
replace the editor deliberately
save that source locally
clear the previous trace
The preview deliberately starts at its heading every time a different lesson is selected. A scroll position from a longer lesson cannot make the next lesson appear to begin halfway through. Source is inserted as text, not trusted as HTML, and the preview action uses the same guarded source-loading path as the rest of the workspace.
The numbers are a fixed recommendation, not tracked progress. Code Explorer does not know which lesson a learner completed, whether someone is ready for a checkpoint, or how long anyone studied. There are no accounts, progress profiles, completion analytics, or learner scores. A learner may open, skip, or revisit any program at any time.
Code Explorer provides Code Explorer does not record
+-- recommended sequence +-- completed lessons
+-- prerequisite labels +-- study time
+-- difficulty and line count +-- learner readiness
+-- best-view suggestions +-- personal progress
- Beginner examples isolate one main idea and use direct names and control flow.
- Developing examples combine two or more familiar ideas, such as a loop with a condition or a function with a collection.
- Guided Challenge examples coordinate several familiar ideas. The 12 checkpoint projects range from 18 to 31 lines and increase the amount of state, structure, and control flow a learner must follow.
A Guided Challenge is not a test you must pass before using it. Load it, run it, and study one view at a time. Moving back to a shorter example is normal learning, not failure.
| Level | Example | Main learning goal |
|---|---|---|
| Beginner | Hello, Python | Run the smallest complete Python program |
| Beginner | Print text and a number | Display different literal types together |
| Beginner | Three steps in order | Follow statements from first to last |
| Beginner | Label every answer | Make console values understandable |
| Beginner | A comment for the reader | Distinguish explanation from execution |
| Beginner | Meet four literal values | Meet text, integer, decimal, and Boolean literals |
| Beginner | Calculate inside print | Evaluate an expression before output |
| Beginner | Ask Python about a value | Inspect the type of a literal |
| Beginner | Repeat a text pattern | Multiply a string to repeat text |
| Beginner | A morning routine | Read a five-step program in order |
| Level | Example | Main learning goal |
|---|---|---|
| Beginner | Store one value | Assign and print one descriptive name |
| Beginner | Change a variable | Observe reassignment and value history |
| Beginner | Create two names together | Use multiple assignment |
| Beginner | A tiny calculation | Follow names through multiplication |
| Beginner | Reserve an empty result | Use None for a result not chosen yet |
| Beginner | Celsius to Fahrenheit | Follow arithmetic and a rounded value |
| Beginner | Building status flags | Combine Boolean facts |
| Developing | Swap two values | Exchange values with tuple assignment |
| Developing | Convert text into numbers | Convert numeric text before calculation |
| Guided Challenge | Personal profile summary | Combine text, numbers, and Boolean state |
| Level | Example | Main learning goal |
|---|---|---|
| Beginner | Add and subtract | Calculate a remaining amount |
| Beginner | Multiply and raise a power | Compare multiplication and ** |
| Beginner | Compare two scores | Store comparison results as Booleans |
| Developing | Division and remainders | Compare /, //, and % |
| Developing | Pack complete boxes | Use quotient and remainder together |
| Developing | Control calculation order | Compare default precedence with parentheses |
| Developing | Require two facts | Use logical and |
| Developing | Accept either permission | Use logical or |
| Developing | Reverse a Boolean | Use logical not |
| Developing | Check collection membership | Compare in and not in |
| Level | Example | Main learning goal |
|---|---|---|
| Beginner | Building a message | Concatenate text values |
| Beginner | Read characters by position | Use positive and negative indexes |
| Beginner | Measure a message | Count characters with len |
| Developing | Cleaning a username | Chain strip, lower, and replace |
| Developing | Slice a word | Select a range of characters |
| Developing | Format a profile sentence | Insert values with an f-string |
| Developing | Rebuild a sentence | Use split and join |
| Developing | Build initials | Clean, split, and index a name |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Beginner | Pass or try again | Observe one true or false branch | Conditions, Coverage, Story |
| Developing | Checking multiple conditions | Understand and and its two facts |
Conditions, Before and After, Coverage |
| Beginner | Different inputs, different paths | Compare branches produced by input | Input Playground, Compare Runs, Conditions |
| Developing | Grade bands | See Python stop at the first matching elif branch |
Conditions, Coverage, Execution Path |
| Guided Challenge | Account access check | Follow nested identity and permission decisions | Conditions, Coverage, Execution Path |
| Beginner | Allowed color check | Test membership with in |
Conditions, Structures, Coverage |
| Guided Challenge | Shipping quote | Combine membership, totals, distance, and pricing rules | Conditions, Coverage, Before and After |
| Beginner | Classify a number | Choose even or odd with modulo | Conditions, Story, Coverage |
| Developing | Positive, zero, or negative | Follow three mutually exclusive paths | Conditions, Coverage, Execution Path |
| Developing | Check a safe range | Use a chained comparison | Conditions, Story, Coverage |
| Developing | Check an empty collection | Observe list truthiness | Conditions, Structures, Coverage |
| Guided Challenge | Choose a ticket price | Combine age bands and membership | Conditions, Before and After, Coverage |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Beginner | Running total | Follow an accumulator through a for loop |
Loop Table, Loop Lab, Coverage |
| Beginner | Countdown | Watch a while condition become false |
Conditions, Execution Path, Loop Lab |
| Developing | Find the first match | See break end a search |
Execution Path, Coverage, Loop Table |
| Developing | Skip unwanted values | See continue skip part of an iteration |
Execution Path, Coverage, Loop Table |
| Beginner | Even number squares | Combine filtering with list building | Loop Table, Mutation Explorer, Conditions |
| Developing | Count passing scores | Change a counter only when a rule matches | Loop Table, Conditions, Watches |
| Developing | Find the highest temperature | Maintain a running maximum | Loop Table, Before and After, Conditions |
| Beginner | Save until the goal | Repeat deposits until a target is reached | Loop Lab, Loop Table, Watches |
| Guided Challenge | Process a task queue | Mutate pending and completed lists in a while loop |
Loop Lab, Mutation Explorer, Structures |
| Guided Challenge | Build a session schedule | Coordinate nested outer and inner loops | Execution Path, Loop Table, Coverage |
| Beginner | Count by twos | Use a custom range step |
Loop Table, Loop Lab, Execution Path |
| Developing | Number a reading list | Receive positions and values with enumerate |
Loop Table, Variables, Structures |
| Developing | Visit product prices | Iterate through dictionary items | Loop Table, Structures, Before and After |
| Developing | Read until done | Stop at a sentinel input value | Input Playground, Loop Lab, Conditions |
| Guided Challenge | Search with a loop else | Run else when no break occurs |
Execution Path, Coverage, Loop Table |
| Guided Challenge | Build labels concisely | Construct a list with a comprehension | Story, Structures, Before and After |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Beginner | A function call | Follow a parameter, local value, and return | Function Journey, Story, Variables |
| Developing | One function calling another | Follow nested frames and returned values | Function Journey, Story, Variables |
| Beginner | Calculate a rectangle | Move two arguments into one calculation | Function Journey, Variables, Story |
| Developing | Greeting with a default | Compare omitted and supplied default arguments | Function Journey, Compare Runs, Variables |
| Developing | Same name, different scope | Distinguish a local name from a global name | Function Journey, Variables, Watches |
| Developing | Return minimum and maximum | Return a tuple and unpack it at the caller | Function Journey, Structures, Variables |
| Guided Challenge | Recursive factorial | Watch recursive frames grow and return | Function Journey, Story, Variables |
| Guided Challenge | Invoice calculation pipeline | Pass values through several focused functions | Function Journey, Before and After, Variables |
| Beginner | Define and call a greeting | See that a body waits for a call | Function Journey, Call Stack, Story |
| Beginner | Pass a name into a function | Follow an argument into a parameter | Function Journey, Call Stack, Variables |
| Developing | Return instead of only printing | Store and reuse a returned calculation | Function Journey, Before and After, Call Stack |
| Developing | Name the supplied arguments | Use clear keyword arguments | Function Journey, Variables, Call Stack |
| Developing | Calculate without changing outside state | Observe a pure calculation | Function Journey, Before and After, Variables |
| Developing | Average a list of values | Pass a collection and return a summary | Function Journey, Structures, Call Stack |
| Guided Challenge | Validate before calculating | Use an early return | Function Journey, Conditions, Coverage |
| Guided Challenge | Use a private helper function | Follow a nested helper frame | Function Journey, Call Stack, Execution Path |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Beginner | Growing a list | Observe repeated list mutation | Structures, Mutation Explorer, Loop Table |
| Developing | Nested student data | Inspect a dictionary containing a list | Variables, Structures, References |
| Developing | Counting words | Create and update dictionary entries | Structures, Mutation Explorer, Loop Table |
| Beginner | First, middle, and last | Compare positive and negative list indexes | Structures, Variables, Story |
| Beginner | Unpack a coordinate | Split a tuple into named values | Structures, Variables, Before and After |
| Developing | Unique visitors | Remove duplicates with a set | Structures, Variables, Before and After |
| Developing | Update a product record | Add and replace dictionary values | Structures, Mutation Explorer, References |
| Developing | Read a small matrix | Navigate nested row and column indexes | Structures, Variables, References |
| Beginner | Select part of a list | Create a new list with slicing | Structures, References, Before and After |
| Developing | Read a fixed coordinate record | Unpack a three-value tuple | Structures, Variables, Before and After |
| Developing | Find shared interests | Use set intersection | Structures, Before and After, Variables |
| Beginner | Use a default for a missing key | Read safely with dictionary get |
Structures, Story, Before and After |
| Developing | Build a price report | Iterate over dictionary items | Loop Table, Structures, Variables |
| Guided Challenge | Index words by length | Build a dictionary comprehension | Structures, Before and After, Story |
| Developing | Use a list as a stack | Observe last-in, first-out behavior | Structures, Mutation Explorer, Value History |
| Developing | Use a list as a small queue | Observe first-in, first-out behavior | Structures, Mutation Explorer, Value History |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Developing | Two names sharing one list | Observe shared mutation through aliases | References, Mutation Explorer, Variables |
| Developing | Mutate or replace a list | Contrast changing an object with rebinding a name | Mutation Explorer, References, Before and After |
| Developing | Copy an outer list | See a new outer list share nested objects | References, Mutation Explorer, Structures |
| Guided Challenge | Shared settings experiment | Compare an alias, shallow copy, and nested mutation | References, Mutation Explorer, Before and After |
| Beginner | Reassign an integer | Contrast immutable values with shared mutable objects | References, Mutation Explorer, Before and After |
| Developing | Copy before changing | Change a separate shallow list copy | References, Mutation Explorer, Structures |
| Guided Challenge | Share one nested list | Observe a shared list inside two dictionaries | References, Mutation Explorer, Structures |
| Guided Challenge | Mutate a list in a function | Follow a list reference through a call | Function Journey, References, Mutation Explorer |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Beginner | A personalized greeting | Consume two inputs and choose a branch | Input Playground, Conditions, Compare Runs |
| Beginner | An index to investigate | Connect IndexError to list state |
Error Coach, Variables, Structures |
| Beginner | A number to investigate | Connect ValueError to failed integer conversion |
Error Coach, Input Playground, Variables |
| Developing | A key to investigate | Connect KeyError to available dictionary keys |
Error Coach, Structures, Variables |
| Developing | Validate a positive number | Repeat prepared input until a value is accepted | Input Playground, Loop Lab, Conditions |
| Developing | Handle invalid number text | Catch ValueError and print a fallback |
Input Playground, Error Coach, Coverage |
| Developing | Validate a menu choice | Repeat until input belongs to an allowed set | Input Playground, Loop Lab, Conditions |
| Guided Challenge | Reject an impossible quantity | Raise and catch a meaningful exception | Error Coach, Function Journey, Execution Path |
| Level | Example | Main learning goal | Best views |
|---|---|---|---|
| Beginner | Create a simple object | Define a class and attach one attribute | Story, Variables, Structures |
| Developing | Initialize an object | Give an instance state with __init__ |
Function Journey, Variables, Structures |
| Developing | Change object state with a method | Mutate an attribute through a method | Function Journey, Mutation Explorer, Structures |
| Developing | Keep objects independent | Compare state on two instances | References, Structures, Variables |
| Developing | Ask an object for a result | Return a calculation from a method | Function Journey, Structures, Before and After |
| Guided Challenge | Share a class-level value | Compare class and instance attributes | Structures, References, Variables |
| Guided Challenge | Extend a base class | Inherit shared behavior | Function Journey, Call Stack, Structures |
| Guided Challenge | Place one object inside another | Explore composition and nested objects | Structures, References, Function Journey |
| Checkpoint | Program | Recommended prerequisites | Length |
|---|---|---|---|
| 01 | Smart Cafe Bill | Variables, arithmetic, simple conditions, output | 27 lines |
| 02 | Quiz Score Reporter | Variables, lists, loops, conditions | 22 lines |
| 03 | Temperature Week Summary | Lists, for loops, running totals, conditions |
19 lines |
| 04 | Habit Streak Tracker | Lists, loops, counters, conditions | 19 lines |
| 05 | Personal Expense Summary | Functions, lists, dictionaries, loops | 28 lines |
| 06 | Student Gradebook | Dictionaries, lists, loops, averages | 18 lines |
| 07 | Inventory Assistant | Nested records, loops, conditions | 19 lines |
| 08 | Classroom Attendance Report | Lists, sets, dictionaries, loops | 24 lines |
| 09 | Word and Sentence Analyzer | String methods, lists, dictionaries, loops | 24 lines |
| 10 | Library Loan Tracker | Functions, nested dictionaries, mutation | 25 lines |
| 11 | Resilient Order Intake | Input, conversion, exception handling, conditions | 31 lines |
| 12 | Object-Oriented Pet Care Tracker | Classes, methods, instances, lists, loops | 27 lines |
Guided checkpoints are interleaved in All programs after their prerequisite sections. The Guided Mini Programs filter also collects all 12 in one place. A prerequisite is advice, not a lock. The application does not record whether it was completed.
Three debugging examples intentionally stop. Their failure is the lesson, not a broken example:
| Investigation | Why Python stops | Evidence to inspect | A reasonable correction experiment |
|---|---|---|---|
| An index to investigate | It requests index 2 from a two-item list. The available indexes are 0 and 1, so Python raises IndexError. |
Open Structures to count the items and Variables to inspect requested_index. |
Change the requested index to 1, or check that the index is smaller than len(colors) before reading it. |
| A number to investigate | It passes the prepared text "twelve" to int(). That text does not represent an integer, so Python raises ValueError. |
Open Input Playground to see the original text and Variables to distinguish the text from a converted number. | Prepare 12, or validate the text and catch ValueError before continuing. |
| A key to investigate | It requests "marker" from a dictionary containing only "pen" and "book", so Python raises KeyError. |
Open Structures to inspect the existing keys and Variables to inspect requested_item. |
Request an existing key, check requested_item in prices, or use prices.get(requested_item) when absence is expected. |
These cards show an Intentional learning error warning before opening. Do not fix them immediately. First predict the error, run the trace, inspect the final recorded state, explain the mismatch in your own words, and then make one small correction.
Use a ladder when 134 choices feel like too many. Each row is a fixed suggested order, not a tracked requirement.
| Goal | Start | Continue | Finish |
|---|---|---|---|
| Start from scratch | Hello, Python | Store one value | Smart Cafe Bill |
| Understand values | Store one value | Division and remainders | Personal profile summary |
| Understand decisions | Pass or try again | Grade bands | Quiz Score Reporter |
Understand for loops |
Running total | Count passing scores | Temperature Week Summary |
Understand while loops |
Countdown | Save until the goal | Process a task queue |
| Understand functions | A function call | Same name, different scope | Invoice calculation pipeline |
| Understand collections | Growing a list | Update a product record | Inventory restock report |
| Understand references | Two names sharing one list | Copy an outer list | Shared settings experiment |
| Learn from errors | An index to investigate | A key to investigate | Fix each example and rerun it |
| Understand objects | Create a simple object | Change object state with a method | Object-Oriented Pet Care Tracker |
ONE CONCEPT
Beginner example
|
v
COMBINE TWO IDEAS
Developing example
|
v
READ A COMPLETE SMALL PROGRAM
Guided Challenge
|
v
CHANGE ONE INPUT OR VALUE
Compare Runs
|
v
EXPLAIN IT IN YOUR OWN WORDS
Learning comments and bookmarks
Select an example card
|
+-- Replaces the complete editor source
+-- Clears any trace belonging to older source
+-- Saves the new source in the browser
+-- Closes the example dialog
+-- Prepares sample input when the example needs input()
If you want to keep your current program, use Copy before choosing another example.
Examples that call input() prepare safe sample responses automatically. Selecting one replaces the Input Playground text with the values required by that example.
Different inputs, different paths: 72
A personalized greeting: Aman, then 25
A number to investigate: twelve
Validate a positive number: -3, then 7
Read until done: Read chapter, Practise loops, then done
Validate a menu choice: 9, then 2
Resilient Order Intake: Notebook, 3, then yes
You can replace these values in Input Playground before running.
Hello, Python
|
v
Store one value
|
v
Add and subtract
|
v
Pass or try again
|
v
Smart Cafe Bill
|
v
Running total -----> Countdown
| |
v v
A function call Checking multiple conditions
| |
v v
Growing a list Find and skip loop examples
| |
+--------+--------+
|
v
Two names sharing one list
and nested data
|
v
Input comparison and errors
|
v
Functions and collections
|
v
Classes and objects
|
v
Object-Oriented Pet Care Tracker
|
v
Turn on Automatic comments
Export a study copy if useful
The walkthroughs below are lessons, not merely demonstrations. For each one, predict first, inspect several views, explain what happened, and then change the program to test your understanding.
Learning objective: understand the relationship between source lines, trace steps, variable state, and console output.
Load Variables and Types > A tiny calculation:
price = 8
quantity = 3
total = price * quantity
print("Total:", total)Before running, predict:
- Which variable will be created first?
- What value will
totalreceive? - Which line will produce output?
Procedure:
- Select Run trace.
- Confirm that the counter reports four recorded steps.
- Stay in Trace > Story.
- Select Next once at a time.
- At each step, compare the selected source line with the variable cards.
- Move backward once and confirm that later variables disappear from that earlier snapshot.
- Drag the timeline slider to the final step.
Expected state progression:
Step 1 price = 8
Step 2 price = 8, quantity = 3
Step 3 price = 8, quantity = 3, total = 24
Step 4 output includes Total: 24
Expected final output:
Total: 24
Why it behaves this way: Python executes ordinary top-level statements from top to bottom. The multiplication reads two existing names and assigns the result to a third name.
Common misunderstanding: the trace does not create additional program behavior. It records the behavior that actually occurred.
Try changing:
quantity = 5Check your answer: the final total and output should become 40, while the source path remains the same.
Learning objective: use variable history, Watches, and Before and After to study reassignment.
Paste:
balance = 10
balance = balance + 5
balance = balance * 2
print(balance)Before running, write the three expected values of balance on paper.
Procedure:
- Run the trace.
- Open Trace > Before and After.
- Select each assignment step.
- Confirm the transitions
not created -> 10,10 -> 15, and15 -> 30. - Open Data > Variables and select
balance. - Read its creation step and last-change step.
- Select each row in Value History to jump through time.
- Select Watch, then open Data > Watches.
- Move backward and forward to see the watch card update.
Expected history:
created 10
changed 15
changed 30
Expected final output:
30
Why it behaves this way: the right side of an assignment is evaluated using the current value, and the resulting value becomes the new value associated with the name.
Common misunderstanding: balance = balance + 5 is not an algebra equation. It is an ordered instruction.
Challenge: replace the second line with balance += 5.
Check your answer: the final result remains 30, and Story should still explain an update to balance.
Learning objective: see that strings are values with indexed contents and that concatenation creates a new string.
Load Strings > Building a message:
language = "Python"
adjective = "visual"
message = language + " is " + adjective
print(message)Before running, predict the spaces in the final string exactly.
Procedure:
- Run the trace.
- Open Trace > Before and After when
messageis created. - Confirm that the before value says
not created. - Open Data > Variables and select
message. - Confirm that its type is
strand its length is reported. - Open Data > Structures.
- Inspect the character indexes at the beginning of the string.
- Move to the print step and confirm the console output.
Expected output:
Python is visual
Why it behaves this way: + concatenates strings in their written order. The spaces come from the literal " is ".
Common misunderstanding: Python does not automatically insert spaces when strings are joined with +.
Challenge: add another variable and include it in the message:
audience = "beginners"Check your answer: if you append " for " + audience, the output should become Python is visual for beginners.
Learning objective: connect a condition result to reached and missed source lines.
Load Decisions > Pass or try again:
score = 72
if score >= 50:
result = "Pass"
else:
result = "Try again"
print(result)Before running, predict which assignment will be skipped.
Procedure for Run A:
- Run the trace.
- Open Trace > Conditions.
- Confirm that
score >= 50followed the True path. - Open Flow > Coverage.
- Identify the reached
Passline and missedTry againline. - Capture this execution as Run A in Labs > Compare Runs.
Procedure for Run B:
- Change
scoreto40. - Run the trace again.
- Confirm the False path in Conditions.
- Confirm that the coverage states of the branch bodies are reversed.
- Capture this execution as Run B.
- Read the first observed comparison difference.
Expected outputs:
Run A: Pass
Run B: Try again
Why it behaves this way: Python executes exactly one of the two branch bodies for each evaluation of this condition.
Common misunderstanding: a missed branch is not necessarily broken. It was simply not selected by this run.
Challenge: test the boundary value 50.
Check your answer: 50 >= 50 is True, so the output should be Pass.
Learning objective: understand how and combines two Boolean facts.
Load Decisions > Checking multiple conditions:
age = 20
has_ticket = True
if age >= 18 and has_ticket:
result = "Enter"
else:
result = "Wait"
print(result)Before running, evaluate each part separately:
age >= 18 ?
has_ticket ?
combined with and
Procedure:
- Run the trace.
- Open Trace > Conditions.
- Read each supported condition piece.
- Confirm that both pieces are True.
- Open Trace > Before and After to see
resultcreated. - Open Flow > Coverage to locate the missed alternative.
Expected output:
Enter
Why it behaves this way: an and expression is True only when both required facts are truthy.
Common misunderstanding: changing only age is not the only way to choose the alternative. A missing ticket also makes the combined result False.
Challenge: change has_ticket to False without changing age.
Check your answer: the output should become Wait and the false branch should be covered.
Learning objective: follow a loop target and accumulator across iterations.
Load Loops > Running total:
total = 0
for number in range(1, 4):
total += number
print("Added", number)
print("Total:", total)Before running, complete this prediction table:
+-----------+--------+--------------+
| number | before | after adding |
+-----------+--------+--------------+
| 1 | ? | ? |
| 2 | ? | ? |
| 3 | ? | ? |
+-----------+--------+--------------+
Procedure:
- Run the trace.
- Open Flow > Loop Table.
- Select each iteration number and observe the selected trace step.
- Open Flow > Loop Lab and compare current, completed, and waiting iterations.
- Open Data > Watches after watching
totalandnumber. - Play the trace at
0.5xspeed. - Observe the repeated editor-line heatmap.
Expected accumulator sequence:
0 -> 1 -> 3 -> 6
Expected final output:
Added 1
Added 2
Added 3
Total: 6
Why it behaves this way: range(1, 4) produces 1, 2, and 3. The ending value 4 is excluded.
Common misunderstanding: Loop Table records loop-entry snapshots, so an accumulator cell can show its value before the body updates it for that iteration.
Challenge: change the range to range(1, 6).
Check your answer: there should be five iterations and the final total should be 15.
Learning objective: understand repeated condition checks and the final false result.
Load Loops > Countdown:
count = 3
while count > 0:
print(count)
count -= 1
print("Lift off!")Before running, predict the value of count when the loop ends.
Procedure:
- Run the trace.
- Open Trace > Conditions at a loop check.
- Follow
count > 0while it is True. - Use Flow > Execution Path to identify the loop-back edge.
- Open Flow > Loop Lab and move through each iteration.
- Continue until Story explains that the loop has no more iterations.
- Confirm that
Lift off!prints only after the loop exits.
Expected state sequence:
count = 3
count = 2
count = 1
count = 0
condition becomes False
Expected output:
3
2
1
Lift off!
Why it behaves this way: the body decreases count, and Python checks the condition again before each possible iteration.
Common misunderstanding: the value 0 is reached, but it is not printed inside the loop because 0 > 0 is False.
Challenge: remove count -= 1 only as a thought experiment.
Check your reasoning: the loop would never make progress and Code Explorer would eventually stop it through a safety limit.
Learning objective: distinguish ending a loop from skipping the rest of one iteration.
First load Loops > Find the first match:
numbers = [4, 7, 12, 15]
target = 12
found_at = -1
for index in range(len(numbers)):
if numbers[index] == target:
found_at = index
break
print("Found at:", found_at)Procedure for break:
- Run the trace.
- Open Flow > Execution Path.
- Notice that no later iteration follows the successful match.
- Open Flow > Coverage.
- Confirm that the assignment and
breaklines were reached. - Open Flow > Loop Table and count the entered iterations.
Expected output:
Found at: 2
Now load Loops > Skip unwanted values:
kept = []
for number in range(1, 7):
if number % 2 == 0:
continue
kept.append(number)
print(kept)Procedure for continue:
- Run the trace.
- Watch that all six loop values are considered.
- Confirm that
kept.append(number)is skipped for even values. - Compare the repeated paths and coverage.
Expected output:
[1, 3, 5]
Why they differ:
break -> leave the loop completely
continue -> skip to the next iteration
Common misunderstanding: continue does not finish the loop.
Challenge: change the target in the first program to 99.
Check your answer: every iteration should run and found_at should remain -1.
Learning objective: observe a function frame, parameter binding, local calculation, and returned result.
Load Functions and Scope > A function call:
def double(number):
result = number * 2
return result
answer = double(4)
print(answer)Before running, identify which names should be global and which should be local.
Procedure:
- Run the trace.
- Move forward until Python enters
double(). - Open Trace > Function Journey.
- Confirm that the parameter
numberreceives4. - Confirm that
resultis local todouble(). - Return to Trace > Story and inspect the call stack.
- Open Data > Variables while the function is active.
- Move past the return and observe the local frame leave scope.
- Confirm that global
answerreceives8.
Expected journey:
global frame
|
v
double(number = 4)
|
v
result = 8
|
v
return 8
|
v
answer = 8
Expected output:
8
Common misunderstanding: result and answer can hold the same value while belonging to different scopes.
Challenge: call double(7) instead.
Check your answer: the local result, returned value, global answer, and output should all become 14.
Learning objective: understand nested function frames and values moving through multiple calls.
Load Functions and Scope > One function calling another:
def add_tax(price):
return price * 1.10
def final_price(price, discount):
reduced = price - discount
return add_tax(reduced)
total = final_price(50, 5)
print(round(total, 2))Before running, calculate the reduced price and then the taxed price.
Procedure:
- Run the trace.
- Move into
final_price(). - Open Trace > Function Journey and inspect its parameters.
- Move to the call to
add_tax(reduced). - Return to Story and inspect the stacked frames.
- Confirm that
reducedfrom the caller becomespriceinadd_tax(). - Follow both returns back to the global frame.
- Inspect
totalin Variables.
Expected value journey:
50 - 5
|
v
reduced = 45
|
v
add_tax(price = 45)
|
v
49.5 returned
|
v
total = 49.5
Expected output:
49.5
Common misunderstanding: both functions use a parameter named price, but each active frame owns its own local name.
Challenge: change the discount to 10.
Check your answer: (50 - 10) * 1.10 produces 44.0.
Learning objective: navigate a container inside another container and observe a nested mutation.
Load Collections > Nested student data:
student = {
"name": "Aman",
"scores": [72, 84]
}
student["scores"].append(91)
average = sum(student["scores"]) / len(student["scores"])
print(student["name"], round(average, 1))Before running, predict the final length of student["scores"].
Procedure:
- Run the trace.
- Open Data > Variables and select
student. - Expand the dictionary and then its
scoreslist. - Move to the
append()step. - Open Trace > Before and After.
- Open Data > Structures and inspect the dictionary keys.
- Open Data > References to see the dictionary and nested list as separate conceptual objects.
- Move to the calculation of
average.
Expected structure:
student
|
+-- "name" -> "Aman"
|
+-- "scores" -> [72, 84, 91]
Expected output:
Aman 82.3
Why it behaves this way: the dictionary stores a reference to a list. Appending changes that nested list without replacing the outer dictionary.
Common misunderstanding: nested containers are not flattened into one value. Each container has its own contents and identity.
Challenge: append 100 before calculating the average.
Check your answer: the scores length becomes four and the rounded average becomes 86.8.
Learning objective: use References and Mutation Explorer to understand aliasing.
Load Collections > Two names sharing one list:
first = [1, 2]
second = first
second.append(3)
print("first:", first)
print("second:", second)Before running, decide whether first will include 3.
Procedure:
- Run the trace.
- Move to the step where
secondis created. - Open Data > References.
- Confirm that both names connect to one list object.
- Move to
second.append(3). - Open Data > Mutation Explorer.
- Confirm that Object A remains Object A while its contents change.
- Open Variables and check the Shared with fact.
Expected conceptual map:
first -----+
|
v
Object A
[1, 2, 3]
^
|
second -----+
Expected output:
first: [1, 2, 3]
second: [1, 2, 3]
Why it behaves this way: second = first copies the reference to the list. It does not create an independent copy of the list.
Common misunderstanding: two variable names do not guarantee two objects.
Challenge: replace the second line with second = first.copy().
Check your answer: after appending through second, first should remain [1, 2] while second becomes [1, 2, 3].
Learning objective: distinguish changing Object A from connecting a name to Object B.
Load Collections > Mutate or replace a list:
items = []
original = items
items.append("book")
items = ["new"]
print("original:", original)
print("items:", items)Before running, predict the final values of both names.
Procedure:
- Run the trace.
- Move to
items.append("book"). - Open Data > Mutation Explorer and read same object.
- Open References and confirm that
itemsandoriginalshare Object A. - Move to
items = ["new"]. - Return to Mutation Explorer and read new object.
- Open References again.
- Confirm that
originalstill points to Object A whileitemspoints to Object B. - Use Before and After to inspect the reassignment.
Expected identity story:
After append:
items --------+
v
Object A: ["book"]
^
original -----+
After reassignment:
original -----> Object A: ["book"]
items --------> Object B: ["new"]
Expected output:
original: ['book']
items: ['new']
Common misunderstanding: reassignment does not travel backward and rename or erase the earlier object while another name still references it.
Challenge: replace items = ["new"] with items.clear().
Check your answer: both items and original should then show the same empty Object A because clear() mutates the shared list.
Learning objective: combine Input Playground, Compare Runs, breakpoints, Watches, bookmarks, Coverage, and Error Coach into a repeatable debugging method.
Part A uses Decisions > Different inputs, different paths:
score = int(input("Score: "))
if score >= 50:
message = "Pass"
else:
message = "Try again"
print(message)Procedure for comparison:
- Open Labs > Input Playground and confirm the prepared value
72. - Run the trace and capture Run A.
- Watch
scoreandmessagein Data. - Bookmark the condition step.
- Change the prepared input to
40. - Run again and capture Run B.
- Open Compare Runs and read the earliest difference.
- Open Conditions and Coverage to connect that difference to the selected branch.
Expected outputs:
Run A with 72: Pass
Run B with 40: Try again
Part B uses Input, Errors and Debugging > An index to investigate:
colors = ["mint", "purple"]
requested_index = 2
print(colors[requested_index])Before running, list the valid indexes for a two-item list.
Procedure for investigation:
- Select source line 3 in the editor gutter to add a replay breakpoint.
- Run the trace.
- Select Play and confirm that replay pauses at the marked line.
- Bookmark the paused step.
- Move to the final step.
- Read Trace > Error Coach.
- Watch
requested_index. - Inspect
colorsin Structures. - Compare its indexes
0and1with the requested index2. - Open Coverage and confirm which lines were reached before failure.
Expected error:
IndexError: list index out of range
Debugging flow:
Read the original error
|
v
Locate the failing source line
|
v
Inspect variables and structures
|
v
Compare expected and actual values
|
v
Form one small correction
|
v
Run a new trace and verify
Common misunderstanding: changing the index to 1 is not merely hiding the error. It makes the request valid because 1 is the final index of a two-item list.
Final challenge: change requested_index to 1 and run again.
Check your answer: the trace should finish successfully and print purple.
Open workspace
|
v
READY FOR SOURCE
|
| select Run trace
v
RUNNING
|
+-- Stop selected ---------> STOPPED
|
+-- Safety limit reached --> LIMIT MESSAGE
|
+-- Syntax failure --------> ERROR COACH, no timeline
|
+-- Runtime failure -------> ERROR COACH, partial timeline
|
+-- Success ---------------> TRACE READY
|
+------------+------------+
| |
v v
inspect steps edit source
| |
+-------------------------+
|
v
old trace is cleared
- Empty views explain what data they need.
- Playback controls remain disabled.
- Automatic comments remains disabled because there are no trace-backed notes to show.
- Learning comments remains disabled because no runtime evidence exists yet.
- The console says output will appear there.
- The header may report that Python is loading.
- Run trace enters a loading state.
- A Stop button becomes available.
- Any inline notes from the previous trace hide immediately so they cannot be mistaken for evidence from the new run.
- The console explains that a safe trace is being prepared.
- The interface remains separate from the Python execution.
- Playback controls become available.
- The first trace step is selected.
- Editor line activity appears.
- Story, Data, Flow, and Lab views receive data from the same timeline.
- Console output follows the selected step.
- Selecting another step updates every view consistently.
- Automatic comments becomes available in the off state. Turning it on adds visual notes without adding source lines.
- Learning comments becomes available and opens a separate preview of the current source with trace-backed teaching notes.
- The source is saved automatically.
- The previous trace is cleared.
- Old coverage, path, loop, variable, and bookmark results disappear.
- Visible automatic comments disappear immediately.
- Old generated learning-note metadata disappears, and both Automatic comments and Learning comments become disabled.
- A new Run trace is required.
- Steps recorded before the failure remain inspectable.
- The failing line and original Python message are shown.
- Error Coach provides beginner guidance.
- Console output produced before the error remains available.
- Automatic comments and Learning comments may still be available for statements that Python parsed and for trace evidence recorded before the failure.
- Python does not produce an execution timeline because the program could not start.
- Code Explorer points to the syntax line when available.
- Error Coach opens with a grammar-focused suggestion.
- Automatic comments and Learning comments remain disabled because there is no valid parsed program or runtime trace to support them.
This section contains two different kinds of messages:
Python error
+-- comes from the learner program
+-- examples: NameError, TypeError, IndexError
+-- investigate with Error Coach and recorded state
Code Explorer status or limit
+-- comes from the learning workspace
+-- examples: Runtime unavailable, trace limit reached
+-- follow the recovery action in the table below
The table below explains workspace messages. For Python exception types, use the detailed Error Coach reference.
| Message or situation | Meaning | What to do |
|---|---|---|
| Add some Python code first | The editor contains no executable source | Enter or load a program |
| Python ready | The browser runtime can run a trace | Select Run trace |
| Runtime unavailable | Python could not load | Check the connection and reload |
| Execution stopped | Stop was selected | Reduce the work or run again when ready |
| Execution time limit reached | The program ran for 30 seconds | Check for an infinite loop or reduce work |
| Trace limit reached | 3,000 snapshots were recorded | Reduce loop iterations, calls, or source size |
| Input Playground has no prepared value left | input() was called too many times |
Add one response line per call |
| Clipboard permission is blocked | The browser denied clipboard reading | Allow permission or use Ctrl+V |
| Graph renderer unavailable | The optional graph could not load | Check the connection; other views still work |
| No loop detected yet | No supported loop was found or reached | Run a program containing for or while |
| No references yet | No completed trace is available | Run the program first |
| Name is not in scope | The watched name does not exist at this step | Move to a later step or inspect another scope |
| Learning comments is disabled | No supported completed trace exists for the current source | Run the current program, or correct a syntax error and run again |
| A source line has no generated note | The construct is unsupported, ambiguous, or not useful at the chosen detail level | Choose Detailed, or study that line with Story and Before and After |
| Replace editor asks for confirmation | The action will replace the complete editor document | Review the preview, then confirm or cancel |
Limits keep the workspace responsive and the visual explanations readable.
Program stopped by a safety limit
|
+-- Message says 3,000 trace steps
| +-- Reduce loop iterations
| +-- Test a smaller collection
| +-- Isolate one function
| +-- Remove unnecessary repeated calls
|
+-- Message says 30 seconds
| +-- Check for an infinite while loop
| +-- Confirm loop state changes toward an exit
| +-- Remove delays or intensive work
| +-- Use a smaller teaching input
|
+-- A value preview says items were omitted
+-- Read the reported true length
+-- Inspect a smaller sample
+-- Remember that Python kept the complete live value
| Limit | Value | What happens at the limit |
|---|---|---|
| Maximum trace | 3,000 steps | Execution stops with a clear trace-limit message |
| Execution timeout | 30 seconds | The run is stopped and the Python runtime is reset |
| Non-finite float transport | inf, -inf, and nan |
Python keeps the live value; the detached trace carries its type and readable spelling as strict JSON-safe text |
| Area | Display limit | Purpose |
|---|---|---|
| Watches | 12 variable names | Keeps the dashboard focused |
| Container preview | 30 child items | Prevents very large values from overwhelming each step |
| Nested value preview | 4 levels | Prevents cycles and excessive nesting |
| Compact value text | About 120 characters | Keeps cards readable while showing a useful preview |
| Variable history | 200 meaningful rows | Keeps long traces navigable |
| Loop Lab | 40 iterations | Keeps the visual iteration list concise |
| Loop Table | 100 iterations and up to 5 variable columns | Keeps comparisons readable |
| Reference map | Up to 180 graph elements | Protects graph performance |
| Graph zoom | 40% to 200% | Supports overview and close inspection |
A shortened display does not mean Python shortened the live value. It means the visual snapshot shows a bounded preview. Length information and omitted-item messages help indicate when more data exists.
Code Explorer works best with:
- Beginner exercises
- Small scripts
- Variables and expressions
if,elif, andelseforandwhileloops- User-defined functions
- Lists, tuples, dictionaries, sets, and strings
- Short input-driven programs
- Small algorithm examples
Code Explorer is not intended to replace a complete local Python development environment. Very large algorithm runs, long recursion, intensive numerical work, interactive graphical programs, operating-system access, and programs requiring many external packages may not fit the visual trace limits.
float("inf"), float("-inf"), and float("nan") are valid Python values.
When they appear in a recorded snapshot, Code Explorer preserves their
float type and readable Python spelling while using strict JSON-safe trace
text. The transport representation does not change the value used by the
running Python program.
Code Explorer runs the learner's program inside the browser.
Code Explorer does not collect learner data for analytics, telemetry, advertising, profiling, product metrics, or behavior tracking. There is no account system, application server, analytics SDK, tracking pixel, cookie, browser fingerprint, event beacon, remote log collector, crash-report upload, or hidden form submission in the project.
LEARNER SOURCE AND INPUT
|
v
Browser page
|
v
Local Web Worker running Pyodide
|
v
Trace returned to the same browser page
No analytics endpoint
No Code Explorer database
No learner profile
No source upload
The audited privacy behavior is:
| Data or action | Where it goes | Is it collected by Code Explorer? |
|---|---|---|
| Python source | Local browser storage and the page's local Web Worker | No |
Prepared input() responses |
Local browser storage and the local Web Worker | No |
| Trace snapshots and console output | Memory in the current browser page | No |
| Theme, editor, graph, watch, input, and selected-question preferences | Local browser storage for this site | No |
| Clipboard text | Read or written only after the learner selects Paste or Copy and the browser permits it | No |
| Automatic comments and bookmarks | Current browser session, unless commented source is deliberately copied or adopted | No |
| Analytics events | No analytics system exists | No |
Local storage is persistence, not collection. The application reads those values back on the same browser origin and contains no code that uploads them.
Code Explorer does make ordinary network requests to load the website and pinned browser dependencies. Current external assets include fonts from Google Fonts, editor and graph modules from esm.sh, and Pyodide from jsDelivr. GitHub Pages serves the deployed website. Those providers can receive normal web-request metadata such as an IP address, browser headers, and requested asset path under their own policies. Code Explorer does not attach learner source, prepared input, traces, clipboard text, local-storage values, or a learner identifier to those dependency requests.
That provider-side request metadata is not returned to Code Explorer. The application and project maintainers cannot view IP addresses, browser headers, or provider request logs through the website, source repository, or a Code Explorer analytics dashboard because no such collection or dashboard exists.
GitHub has a separate repository Insights feature for people with push access. According to GitHub's repository traffic guide, it can summarize recent repository visitors, full clones, referring sites, and popular repository content. This belongs to GitHub's own platform, not to Code Explorer's application.
A beginner-friendly example:
WHAT A GITHUB REPOSITORY SUMMARY MAY SHOW
Repository views ........ a total count
Unique visitors ......... an aggregate count
Full repository clones .. a total count
Popular content ......... README.md received views
Referring sites ......... a site sent visits to the repository
WHAT CODE EXPLORER MAINTAINERS CANNOT SEE THERE
The Python program you typed
The values entered for input()
Your trace steps or console output
Your clipboard contents
Your locally saved source or preferences
Your IP address from Code Explorer dependency requests
Your browser headers from Code Explorer dependency requests
An individual history of which workspace buttons you selected
For example, a repository summary might say that a page had several views from several unique visitors. It does not give Code Explorer a copy of what those visitors typed into the tool. It does not turn a local trace into a repository statistic. It does not let the maintainer open one visitor's workspace. It is comparable to a library knowing that a book was requested several times without receiving the notes a reader wrote privately at home.
The privacy boundary can be summarized as three separate layers:
1. CODE EXPLORER LEARNING DATA
source, input, trace, output, clipboard, preferences
-> stays in the learner's browser
2. PROVIDER-SIDE REQUEST HANDLING
ordinary requests for a page, font, or pinned module
-> handled by that provider
-> raw provider logs are not available to Code Explorer maintainers
3. GITHUB REPOSITORY INSIGHTS
aggregate repository traffic supplied by GitHub
-> separate from the Code Explorer application
-> contains no learner program, input, trace, clipboard, or local-storage data
Selecting Tool Guide inside the Python workspace or selecting the GitHub icon deliberately navigates to GitHub in a new tab. Both links use noreferrer, so Code Explorer does not send the current page address as a referrer through those links.
This is a permanent project boundary: future contributors must not add first-party or third-party analytics, telemetry, tracking, advertising pixels, session recording, user profiling, fingerprinting, or automatic remote error reporting. A useful learning feature is not permission to monitor learners.
BROWSER-SAVED LEARNING SETUP
|
+-- Python source
+-- Theme
+-- Editor wrap and font size
+-- Graph zoom
+-- Watched names
+-- Prepared input text
CURRENT EXECUTION ONLY
|
+-- Recorded trace snapshots
+-- Selected step
+-- Console at each step
+-- Coverage and execution path
+-- Loop results
+-- Trace bookmarks
+-- Playback state
+-- Automatic Learning Comments metadata and export preview
+-- Automatic comments visible or hidden state
New run or changed source
|
v
Execution-only state is cleared, then rebuilt by the next run
If you confirm Replace editor, the commented document becomes ordinary editor source and is saved locally like any source edit. Merely showing automatic comments, opening the export preview, or copying the generated preview does not save a commented document.
The inline visibility state intentionally resets with the trace. A reload, source edit, example change, paste, or new run requires fresh runtime evidence and returns Automatic comments to off. The chosen detail level can remain available as a learning preference, but notes are always regenerated from the current run.
The following are saved locally when browser storage is available:
- Current Python source
- Light or dark theme
- Editor wrapping choice
- Editor font size
- Reference graph zoom
- Execution Path graph zoom
- Watched variable names
- Prepared Input Playground text
The following belong to the current trace and are not intended to survive a new execution:
- Current step
- Trace bookmarks
- Playback position
- Breakpoint pauses
- Recorded variable snapshots
- Coverage and path results
- Automatic comments visibility and generated note metadata
No sign-in is required. If the browser blocks local storage, the tool remains usable but may not restore saved source or preferences after reload.
When experimenting, change only one input, value, condition, or line before running again. This makes Compare Runs and Before and After much easier to interpret.
At each step, ask:
1. Which line will run next?
2. Which names might change?
3. What will be printed?
4. Will a mutable object change in place?
Then select Next and compare your prediction with the recorded state.
- Start with Story.
- Open Before and After when a change is unclear.
- Open Variables when a value is complex.
- Open Structures for indexes and keys.
- Open Mutation Explorer only when identity matters.
- Open Execution Path when control flow is confusing.
Bookmark a step before exploring other views. You can return to the exact line and state without trying to remember the slider position.
Two runs can print the same result while taking different paths or holding different intermediate variables. Compare Runs checks path and visible state as well as final output.
When Coverage marks a line as missed, ask what condition or input would make Python reach it. Then run that case and compare.
What is not working?
|
+-- Run does not begin
| +-- Is the editor empty? -> Add or load source
| +-- Is Python loading? -> Wait for Python ready
| +-- Runtime unavailable? -> Check connection and reload
|
+-- Run begins but stops
| +-- Python error? -> Open Error Coach
| +-- Missing input? -> Add Input Playground lines
| +-- Safety limit? -> Reduce repeated work
|
+-- A view is empty
| +-- No trace? -> Run the program
| +-- Wrong selected step? -> Move to where the concept exists
| +-- No relevant concept? -> Use another example or view
|
+-- Graph is unavailable
| +-- Wait briefly
| +-- Check the connection
| +-- Continue with Story, Variables, or Coverage
|
+-- Values seem to move backward
+-- Check the selected trace step
+-- Remember that output and state follow the timeline
- Check the header status.
- Wait for Python ready.
- Confirm that the editor is not empty.
- Reload if the runtime reports that it is unavailable.
- Check whether a network filter blocked the initial Python runtime download.
The program probably reached the 3,000-step limit or 30-second timeout.
Try:
- Reducing loop ranges
- Testing one function at a time
- Using a smaller input collection
- Removing deliberate delays
- Checking for an infinite
whileloop - Replacing a large stress test with a smaller teaching example
EOF means end of input. In a terminal it traditionally means that no more input can be read. In Code Explorer it means the program called input() after all prepared Input Playground lines had already been consumed.
Count the calls to input() along the path being tested. Remember that conditions and loops can make the number of calls vary between runs. Add at least one prepared line for every call on the path you want to test.
first = input()
second = input()Needs:
first response
second response
The browser blocked clipboard reading. Allow clipboard access for the site, or focus the editor and press Ctrl+V.
- Run a trace first.
- For References, make sure a visible variable exists at the selected step.
- For Execution Path, wait briefly for the graph to appear.
- Check the connection if the graph renderer reports that it could not load.
- Use Story, Variables, Coverage, or Loop Table while graphs are unavailable.
Move to a step after the variable is created or to a step where its function frame is active. A local variable naturally leaves scope when its function finishes.
Editing automatically clears stale results. Run a new trace for the current source.
This is expected. Console output is synchronized with the selected point in time. Move forward again to see output produced by later steps.
- Confirm that the visible source has been run since its last edit.
- Correct any syntax error and run again.
- Wait for the completed trace before selecting the button.
- If a runtime error occurred, check whether any source statements executed before the failure.
The same evidence rule applies when Automatic comments is disabled. Both controls become available from the same current note set.
This is expected after editing, pasting, loading an example, or starting another run. The former notes described the former source and trace, so Code Explorer removes them instead of leaving a stale explanation beside changed code. Complete the new trace and turn Automatic comments on again.
Visual notes occupy space above their related lines while the mode is on. They do not add source lines. The footer line count, Python line numbers, heatmap, and replay breakpoints still use the original document. Turn the mode off to return to the compact source-only layout.
This is intentional. The editor's Copy action always copies the original Python document. To copy real # Code Explorer: lines, open Learning comments and select Copy commented code.
Open the detail selector and choose Detailed. If the line still has no note, Code Explorer did not have enough reliable evidence to explain it. This is intentional. Use Story, Before and After, Function Journey, or the relevant specialist view instead of treating the missing note as an error.
First check the toolbar label:
- If it says Automatic comments on, the notes are temporary visual widgets. Turn the control off and the original compact source view returns.
- If Automatic comments is off and
# Code Explorer:lines remain as editable source, Replace editor was previously confirmed. You can remove them manually, undo the replacement while editor history remains available, or rerun the commented program and generate a fresh copy. A fresh generation removes older lines with that exact prefix before adding current notes, so it does not stack duplicate generated layers.
This glossary is designed to be used beside a trace. Each entry explains the idea, shows a small example, warns about a common misunderstanding, and points to the Code Explorer views that make the idea visible.
What kind of concept is confusing?
|
+-- Names and values
| +-- name, value, type, expression, assignment, reassignment
|
+-- Choosing and repeating
| +-- Boolean, condition, branch, for, while, iteration
| +-- accumulator, counter, break, continue
|
+-- Functions
| +-- definition, call, parameter, argument, return
| +-- scope, frame, call stack, recursion
|
+-- Collections
| +-- list, tuple, dictionary, set, index, key
| +-- nested structure, mutable object, immutable value
|
+-- Object relationships
| +-- reference, identity, alias, mutation, shallow copy
|
+-- Program communication and failure
| +-- input, output, syntax error, runtime error, exception
|
+-- Code Explorer evidence
+-- trace step, coverage, execution path, reference map
A name is the word used to refer to data. A value is the data itself. A type describes the kind of value and the operations Python supports for it.
score = 10
message = "Ready"Here, score is a name referring to the integer value 10. message refers to a string value.
Common misunderstanding: a variable is not a labelled physical box shown by Code Explorer. Python names refer to values or objects. Open Data > References when the relationship between a name and an object matters.
Best views: Variables, References, Story.
An expression is code that Python evaluates to produce a value.
subtotal = price * quantityprice * quantity is the expression. Assignment then connects subtotal to its result.
Common misunderstanding: not every source line is one expression. A line can contain a statement, an expression inside that statement, and a function call inside the expression.
Best views: Story, Before and After, Variables.
Assignment evaluates the expression on the right, then connects the name on the left to the resulting value or object.
price = 8
total = price * 3Common misunderstanding: = does not mean mathematical equality in an assignment. It performs an action. Use == when asking whether two values are equal.
Best views: Before and After, Variables, Story.
Reassignment makes an existing name refer to a different value or object.
status = "waiting"
status = "ready"The second line does not edit the string "waiting". It connects status to another string.
Common misunderstanding: reassignment and mutation can produce similar printed results but different reference relationships.
Best views: Before and After, Mutation Explorer, References.
A Boolean value is either True or False. Comparisons and logical operators often produce Booleans.
old_enough = age >= 18
can_enter = old_enough and has_ticketCommon misunderstanding: the strings "True" and "False" are text, not Boolean values.
Best views: Variables, Conditions, Before and After.
A condition is an expression Python treats as true or false. A branch is the path selected because of that result.
if score >= 50:
result = "Pass"
else:
result = "Try again"Only one assignment runs in this example. Another input can select the other branch.
Common misunderstanding: an else block does not have its own separate test. It runs when the earlier connected conditions did not select a branch.
Best views: Conditions, Coverage, Execution Path.
elif means "otherwise, check this next condition." Python checks the ladder from top to bottom and stops at the first matching branch.
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
else:
grade = "C or below"Common misunderstanding: every elif is not checked after a previous branch succeeds.
Best views: Conditions, Coverage, Execution Path.
A for loop takes values from an iterable, one at a time, and runs its body for each value.
for color in ["mint", "purple"]:
print(color)The list is iterable. color receives a different element during each iteration.
Common misunderstanding: the loop variable does not contain the whole collection at once.
Best views: Loop Table, Loop Lab, Variables.
A while loop repeats while its condition is true.
count = 3
while count > 0:
count -= 1Something in the loop normally needs to move the condition toward false.
Common misunderstanding: a while loop does not automatically update its condition variables. Forgetting the update can create an infinite loop.
Best views: Loop Lab, Conditions, Execution Path.
An iteration is one pass through a loop body.
for number in range(3):
print(number)The body has three iterations with number equal to 0, 1, and 2.
Common misunderstanding: a trace step and an iteration are not the same unit. One iteration can execute several source lines and therefore create several trace steps.
Best views: Loop Table, Loop Lab, Story.
An accumulator combines values over time. A counter records how many times something happened.
total = 0
passing_count = 0
for score in scores:
total += score
if score >= 50:
passing_count += 1Common misunderstanding: both often start at zero, but they answer different questions. total answers "how much?" while passing_count answers "how many?"
Best views: Loop Table, Watches, Before and After.
break ends the nearest loop. continue skips the rest of the current iteration and begins the next one.
for number in numbers:
if number < 0:
continue
if number == target:
breakCommon misunderstanding: continue does not end the whole loop, and break does not end the entire program.
Best views: Execution Path, Coverage, Loop Table.
A function definition creates reusable behavior. A function call runs that behavior.
def double(number):
return number * 2
answer = double(4)The def statement defines double. double(4) calls it.
Common misunderstanding: defining a function does not run its body immediately.
Best views: Function Journey, Story, Coverage.
A parameter is a name in a function definition. An argument is a value supplied by a particular call.
def greet(name): # name is a parameter
return "Hi " + name
message = greet("Ava") # "Ava" is an argumentCommon misunderstanding: the parameter belongs to the function's local scope. The argument expression is evaluated by the caller.
Best views: Function Journey, Variables, Before and After.
return ends the current function call and sends a value back to its caller.
def square(number):
return number * number
result = square(5)Common misunderstanding: print() displays a value, while return gives a value to the calling code. Printing is not a substitute for returning.
Best views: Function Journey, Story, Variables.
Scope describes where a name can be used. Code Explorer distinguishes global scope from active function-local scopes.
message = "global"
def show():
message = "local"
print(message)The two message names belong to different scopes.
Common misunderstanding: a local name with the same spelling does not automatically replace the global name.
Best views: Variables, Function Journey, Watches.
A frame is one active function call's working context. It includes the current execution position and that call's local variables.
Calling the same function twice creates two separate frames over time. Recursive calls can create several active frames for the same function at once.
Common misunderstanding: a function definition is not a frame. A frame exists while a particular call is active.
Best views: Function Journey, Variables, Story.
The call stack is the ordered collection of active frames. If outer() calls inner(), outer waits below inner until inner returns.
top: inner frame currently running
outer frame waiting for inner
bottom: global frame started the call chain
Common misunderstanding: the call stack is not a history of every completed call. Function Journey can also summarize completed events, while the active stack describes what is active at one moment.
Best views: Function Journey, Story, Variables.
Recursion occurs when a function calls itself, directly or through other functions.
def countdown(number):
if number <= 0:
return
countdown(number - 1)The condition is a base case that stops new calls.
Common misunderstanding: recursion is not automatically infinite. It becomes unsafe when calls do not move toward a reachable base case.
Best views: Function Journey, Variables, Execution Path.
A class is a reusable definition of data and behavior. An object is one value created from a class. The word instance means an object considered as a member of that class.
class Book:
pass
first_book = Book()
second_book = Book()Book is the class. first_book and second_book are separate Book instances.
Common misunderstanding: defining a class does not automatically create the useful instances a program needs. Calling the class creates an instance.
Best views: Story, Variables, Structures, References.
An attribute is a named value connected to an object. Attribute access uses a dot.
book.title = "Python Basics"
print(book.title)Code Explorer serializes a bounded set of ordinary instance attributes. A structure can therefore appear as:
book
+-- Book instance
+-- .title = "Python Basics"
+-- .pages = 240
Common misunderstanding: an attribute is not automatically a local variable. title and book.title can be different names in different places.
Best views: Structures, Variables, Mutation Explorer.
A method is a function defined inside a class. An instance method receives the current object through its first parameter, conventionally named self.
class Counter:
def increase(self):
self.value += 1Calling counter.increase() supplies counter as self automatically.
Common misunderstanding: self is not a reserved Python keyword, but using the conventional name makes code understandable to other Python programmers.
Best views: Function Journey, Call Stack, Structures, Mutation Explorer.
For these beginner lessons, the constructor call creates an instance and Python then calls __init__ to initialize its state.
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
student = Student("Maya", 82)Common misunderstanding: __init__ initializes an already-created instance. It normally does not return the new object explicitly.
Best views: Function Journey, Variables, Structures.
Inheritance lets a more specific class reuse and extend behavior from a base class.
class Animal:
def describe(self):
return "Animal"
class Dog(Animal):
def speak(self):
return "Woof"Common misunderstanding: inheritance is not required whenever two classes interact. Use it when the new class genuinely represents a more specific form of the base class.
Best views: Function Journey, Call Stack, Structures.
Composition means one object contains or collaborates with another object. A library containing book objects is composition.
library.books.append(Book("Python Basics"))Common misunderstanding: composition and inheritance answer different design questions. Inheritance describes an "is a" relationship. Composition describes a "has a" relationship.
Best views: Structures, References, Function Journey.
A list is an ordered, mutable collection. Positions use zero-based indexes.
colors = ["red", "green", "blue"]
first = colors[0]
colors.append("purple")Common misunderstanding: the first index is 0, and the final positive index is one less than the list length.
Best views: Structures, Mutation Explorer, Variables.
A tuple is an ordered, immutable collection. It is useful for fixed groups of values and multiple return values.
point = (12, 7)
x, y = pointCommon misunderstanding: parentheses do not make every expression a tuple. A comma creates the tuple structure.
Best views: Structures, Variables, Before and After.
A dictionary maps unique keys to values.
product = {"name": "Notebook", "stock": 4}
product["stock"] = 7"stock" is a key and 7 is its current value.
Common misunderstanding: dictionary access uses a key, not a numeric position unless numbers were deliberately used as keys. Requesting a missing key raises KeyError.
Best views: Structures, Mutation Explorer, Variables.
A set is a mutable collection of unique values. Sets are useful for membership tests and removing duplicates.
visits = ["Ava", "Noah", "Ava"]
people = set(visits)Common misunderstanding: a set is not designed around stable positional indexes. Do not expect people[0] to work.
Best views: Structures, Variables, Before and After.
An index identifies a position in an ordered collection such as a list, tuple, or string.
word = "Python"
first = word[0]
last = word[-1]Common misunderstanding: a six-character sequence has positive indexes 0 through 5, not 1 through 6.
Best views: Structures, Variables, Error Coach.
A nested structure contains another collection as a value or element.
student = {"name": "Ava", "scores": [82, 91]}
first_score = student["scores"][0]Read access from left to right: find the dictionary value at "scores", then find list element 0 inside that value.
Common misunderstanding: one pair of brackets handles one level of access.
Best views: Structures, References, Variables.
A mutable object can change its contents while remaining the same object. Lists, dictionaries, and sets are common mutable objects.
items = []
items.append(1)Common misunderstanding: mutation does not require assigning the collection back to the same name.
Best views: Mutation Explorer, References, Structures.
An immutable value cannot be changed in place. Integers, floats, Booleans, strings, and tuples are common immutable values.
count = 1
count = count + 1The second line produces another integer value and reassigns count.
Common misunderstanding: count += 1 looks like mutation, but an integer is immutable. The name receives another integer value.
Best views: Before and After, Variables, Mutation Explorer.
Mutation changes the contents of an existing mutable object.
numbers = [1, 2]
numbers.append(3)Common misunderstanding: a new visual snapshot does not necessarily mean a new Python object was created. Mutation Explorer distinguishes content change from reassignment.
Best views: Mutation Explorer, References, Before and After.
A reference connects a name or container position to an object. Identity answers whether two references lead to the same object. Two names are aliases when they reference the same object.
first = []
second = first
same_object = first is secondMutating second is visible through first because both names reach the same list.
Common misunderstanding: equality with == compares values, while identity with is asks whether references reach the same object.
Best views: References, Mutation Explorer, Variables.
A shallow copy creates a new outer container but keeps references to the same nested objects.
original = [[1, 2]]
copied = original.copy()
copied[0].append(3)The outer lists are different objects, but their first elements refer to the same inner list.
Common misunderstanding: shallow copying does not recursively duplicate every nested object.
Best views: References, Mutation Explorer, Structures.
input() reads text supplied by the learner. print() sends text representations to console output.
raw_age = input("Age: ")
age = int(raw_age)
print("Next age:", age + 1)Common misunderstanding: input() always returns a string. Numeric-looking text must be converted before numeric arithmetic.
Best views: Input Playground, Story, Console Output.
A syntax error means Python could not parse the program's grammar.
if ready
print("Go")The missing colon prevents execution from starting, so no runtime timeline exists.
Indentation problems are part of the same compile-time family. For example, the body below must move to the right because it belongs to the if block:
if ready:
print("Go")Code Explorer may show this through its SyntaxError path with a message about expected indentation. Because parsing failed, Variables, Coverage, and other runtime views have no execution evidence yet.
Common misunderstanding: a syntax error is not a false condition or a runtime branch. Python cannot begin the program.
Best views: Error Coach, editor line highlight.
A runtime error happens after valid code begins executing. Python represents the problem with an exception such as IndexError, KeyError, or ValueError.
numbers = [4, 8]
print(numbers[3])The earlier assignment can still appear in a partial trace before the IndexError.
Common misunderstanding: an exception message is evidence, not a judgement about the learner. Read the type, failing line, and current values together.
Several exception names sound similar at first. Use the object being accessed or the operation being attempted to separate them:
| Do not confuse | Key difference |
|---|---|
SyntaxError and a runtime exception |
A syntax error prevents the program from starting. A runtime exception happens after valid source has begun executing. |
TypeError and ValueError |
TypeError usually means the kind of value is unsuitable for the operation. ValueError usually means the kind is accepted but the particular content is unsuitable. |
IndexError and KeyError |
IndexError concerns a sequence position. KeyError concerns a missing dictionary key. |
NameError and AttributeError |
NameError concerns a name Python cannot find in scope. AttributeError concerns a method or attribute that a found value does not provide. |
See the Error Coach reference for individual meanings, examples, and first inspection steps.
Best views: Error Coach, Variables, Structures.
A trace step is one recorded execution snapshot. It includes a source line, visible variables, active frames, and output observed at that moment.
Common misunderstanding: one source line can produce several trace steps when a loop or function reaches it repeatedly.
Best views: Story, Before and After, timeline controls.
Coverage reports which executable source lines were reached, repeated, or missed during one run.
Common misunderstanding: 100 percent coverage for one input does not prove that the program is correct or that every possible value was tested.
Best views: Coverage, Execution Path, Compare Runs.
The execution path is the observed order of reached source lines. Edge counts show repeated transitions.
Common misunderstanding: the graph shows the path for this run, not every theoretical route through the program.
Best views: Execution Path, Coverage, Conditions.
A reference map is a conceptual diagram connecting scopes, names, and captured objects.
Common misunderstanding: the displayed object nodes are not physical RAM addresses and should not be used to estimate memory consumption.
Best views: References, Mutation Explorer, Variables.
PYTHON PROGRAM
|
+-- statements contain expressions
| |
| +-- expressions produce values with types
| +-- assignment connects names to values or objects
|
+-- control flow
| +-- conditions select branches
| +-- for loops consume iterables
| +-- while loops repeat while a condition is true
| +-- each pass is an iteration
|
+-- function calls
| +-- arguments enter parameters
| +-- each call creates a frame and local scope
| +-- active frames form the call stack
| +-- return sends a value to the caller
|
+-- collections and objects
| +-- list, tuple, dictionary, set
| +-- indexes and keys locate contents
| +-- mutable objects can change contents
| +-- aliases can share one object
| +-- shallow copies share nested objects
| +-- classes define reusable object blueprints
| +-- instances carry attributes and use methods
| +-- inheritance extends a parent class
| +-- composition connects one object to another
|
+-- communication and failure
| +-- input supplies strings
| +-- output displays values
| +-- syntax errors prevent execution
| +-- runtime exceptions stop an active path
|
+-- CODE EXPLORER EVIDENCE
+-- trace steps show moments
+-- coverage shows reached lines
+-- execution path shows observed order
+-- reference map shows conceptual relationships
+-- learning comments combine syntax with trace facts
WRITE
Enter a small Python program
|
v
RUN
Create a bounded execution trace
|
v
PREDICT
Guess the next line and state change
|
v
STEP
Move one snapshot forward
|
v
EXPLAIN
Read Story and Before and After
|
v
INSPECT
Open Variables, Structures, or References
|
v
ANNOTATE
Turn Automatic comments on for a trace-backed reading layer
Turn it off when you want the compact source flow again
|
v
COMPARE
Try another input or source value
|
v
REFLECT
Bookmark what surprised you
|
+-----------------------------+
|
v
Repeat and learn
Code Explorer is most useful when you stay curious about the space between two lines of code. Write a small example, predict what Python will do, and use the trace to check your mental model.
If an explanation is useful enough to keep, open Learning comments and copy the commented study document. If it is only useful for the current reading, leave the source untouched and use the Automatic comments toggle. That distinction lets the tool teach more without quietly taking ownership of the learner's program.