Skip to content

Visualizer: indexing a named list is one step; long values abbreviated (P39) - #47

Merged
cedricvogel-leo merged 1 commit into
mainfrom
feature/visualizer-lists
Nov 4, 2026
Merged

cedricvogel-leo merged 1 commit into
mainfrom
feature/visualizer-lists

Conversation

@cedricvogel-leo

Copy link
Copy Markdown
Collaborator

P39: two visualizer changes for lists.

1. Indexing a named list is one step

name[index] steps straight to the element when name is a variable. The name gets no step of its own, and the list stays in the variables panel. This works in Ersetzung and in Kasten, and in the → chain, which takes the same steps.

dauer[0] + dauer[1]  →  1 + dauer[1]  →  1 + 2  →  3
  • Which values: the rule doesn't depend on the type. It holds for lists, tuples, strings, dicts and slices (w[1:3]). In m[i][0] the step is m[1] → [3, 4][0] → 3, and i keeps its step, since an index variable is a value like any other.
  • Unchanged:
    • A named list passed to a call: notenschnitt(noten) → notenschnitt([5, 4.5, 6]).
    • A literal list indexed directly: [1, 2, 30][1] keeps its own step.
    • dauer[3] stops at the error step with IndexError: list index out of range.
  • The → chain's reason comment keeps the name too: # dauer[0] > 0 is True.

2. Long values: abbreviated, never overflowing

l = list(range(1, 101)) now shows [1, 2, 3, 4, 5, …, 100], the same text in the step and in the variables panel. The panel adds «100 Werte» below the value («Einträge» for a dict, «Zeichen» for a string).

Threshold:

  • Shown completely: a list, tuple, set or dict of up to 10 elements, as long as the whole value fits in 160 characters. Strings up to 80 characters are also complete.
    • The course's expression trees (depth ≤ 3, a dozen elements) are always complete, e.g. ['+', ['*', 2, ['-', 7, 3]], ['/', ['+', 1, 2], 3]].
    • 10 elements is your «about 10». 160 characters was already the cut-off before, and 80 characters is about a sentence.
  • Abbreviated:
    • A longer container keeps its first 5 elements and its last, as reprlib does but with the last element kept.
    • If that is still over 160 characters, it keeps 3 elements (then 1) and shortens long elements as well.
    • A long string is cut in the middle ('Es war einmal…Ende.').
    • Nested lists are abbreviated per level.

The full value on request:

  • An abbreviated value is underlined with dots.
  • A click or Enter opens a dialog with the whole value and its length, wrapped and scrollable. This works in the step, in the variables panel, in a loop's =… annotation and in a box's parameter.
  • Escape, ✕ or a click outside closes it.
  • The runtime keeps up to 50 000 characters of a value. Longer ones are marked as cut.

No overflow: a long value in a line now wraps within the code instead of running on under the panel, which was the screenshot's problem.

Texts (optional CoreStrings, de/en): visualizerShowFullValue («Ganzen Wert zeigen»), visualizerValueLength («100 Werte», «1 Wert», «20 Einträge», «200 Zeichen»), visualizerFullValueTitle, visualizerFullValueCut («Nur der Anfang dieses Werts wird gezeigt: Er ist zu lang.»), visualizerCloseFullValue («Schliessen»).

Checks

  • scripts/check-runtime-lists.py (new, in test:runtime), each case under CPython:
    • dauer[1] is one step, and dauer[0] + dauer[1] takes 3;
    • notenschnitt(noten) and [1, 2, 30][1] are unchanged;
    • dauer[3] ends at the IndexError step;
    • the reason comment keeps the name;
    • list(range(1, 101)) is abbreviated in the step and in the panel, with the full value and its length in the trace;
    • expression trees and short values are complete;
    • the abbreviation of dicts, sets, tuples, strings and recursive lists.
  • check-console-browser.mjs, in Chrome with Pyodide:
    • the chain in Ersetzung, step by step;
    • the long list abbreviated in the line and in the panel, staying within the code's width;
    • the full value from the panel and from the step, with «100 Werte»;
    • the expression tree complete.
  • All checks pass locally. Lint has only the known cursor warning.

Follow-ups (not done)

  • Expandable tree: the full view shows the value as wrapped text. Folding sublists is a follow-up if long trees (parse("1 + 2 + 3 + 4 + 5")) need it.
  • Parameters in a short-form function are still replaced by their value, since the name doesn't exist at the call site. So zweites(dauer) with return liste[1] reads zweites([1, 2, 30]) → [1, 2, 30][1] → 2 in Ersetzung. In Kasten, liste[1] is one step. Please say if you want this changed.
  • Copy → chain copies abbreviated values as they appear (with …).
  • A long source line (not a value) can still run under the panel, as before.
  • A slice's step label reads w[slice(1, 3, None)] (unchanged).
  • One rare case: if two different long values with the same abbreviation appear in one step, the dialog shows the later one.

How it goes live

  1. The embed: merging to main deploys it to GitHub Pages, so LiaScript courses get it right away. The macro doesn't change.
  2. The IDE: set the tag v0.1.23 on the merge commit, then bump the IDE. I'll open that PR when you tell me the tag is set.

Manual tests

On the desktop (Chrome/Safari) and on the iPad with the external keyboard, in the IDE after the bump and in a LiaScript course after the merge:

  1. dauer = [1, 2, 30] and x = dauer[0] + dauer[1], then Visualize in Ersetzung: four states of line 2, dauer[0] + dauer[1] → 1 + dauer[1] → 1 + 2 → 3. Then the same in Kasten.
  2. l = list(range(1, 101)), then the last step: l = [1, 2, 3, 4, 5, …, 100], with no overflow under the panel. The panel shows the same text and «100 Werte».
  3. Tap or click the value in the panel, then the one in the line: the dialog shows all 100 numbers and scrolls if needed. Close it with ✕, a tap outside, or Escape on the keyboard. On the iPad, also try Tab to the value + Enter.
  4. An expression tree, e.g. baum = ["+", ["*", 2, ["-", 7, 3]], ["/", ["+", 1, 2], 3]]: complete, not underlined.
  5. A narrow visualizer (LiaScript with the table of contents open): the variables sit below the code, and the long value wraps there too.

🤖 Generated with Claude Code

…d (P39)

dauer[1] steps straight to the element instead of first replacing the
name by the whole list. Long values read "[1, 2, 3, 4, 5, …, 100]" in the
step and in the variables panel, open in full on click, and wrap within
the code instead of running on below the panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cedricvogel-leo
cedricvogel-leo merged commit c5f73b7 into main Nov 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant