code-playpad

Two editors, one Python

Both playgrounds below import the same runtime module, so they share a single Web Worker and a single Pyodide instance. Run them back to back: the second one does not reboot anything. Run them at the same time and the second waits — Python is single-threaded, so runs are queued.

import sys print("widget A ·", sys.version.split()[0]) total = sum(range(1, 101)) total import time print("widget B — sleeping 2s, keeping the queue busy") time.sleep(2) print("widget B done")
Proof of the shared worker: press Run on B, then immediately on A. A shows Running… but only starts once B finishes. If each widget had its own Pyodide, both would boot ~11 MB separately.

Stopping runaway code

There is no cooperative interrupt without SharedArrayBuffer (which needs site-wide COOP/COEP headers), so Stop terminates the worker and boots a fresh one. Queued runs survive and land on the new worker.

while True: pass

Reading input

input() really blocks: the prompt appears, a caret waits in the output, and the program continues when you answer. What you type is echoed the way a terminal echoes it, so the transcript reads back properly. Enter sends a line, EOF ends input.

The standard-input box is optional now — lines in it are used up first, before you are asked. Handy for scripted exercises; leave it empty to answer live.

name = input("name? ") age = int(input("age? ")) print(f"hello {name}, next year you turn {age + 1}")

Prompting in a loop works the same way — press EOF or send a blank line to stop.

total = 0 while True: line = input("number (blank to finish)? ") if not line: break total += int(line) print("sum:", total)

Packages load themselves

loadPackagesFromImports() runs before your code, so an import is all it takes.

import numpy as np grid = np.arange(9).reshape(3, 3) print(grid) grid.sum()

Lazy loading

↓ scroll — the widget below boots only as it nears the viewport ↓
print("I did not exist in the network tab until you scrolled here.")