Python.exe: run code right here on the blog — mattiasfest.in

Python.exe: run code right here on the blog

See a Python snippet on this blog, press ▶ Try me, and it opens in Python.exe, a little Notepad-style editor with an MS-DOS output pane. Edit the code, press Run (or F5, like the good old days), and it executes in your browser. No installs, no server, nothing sent anywhere.

Under the hood it's Pyodide, real CPython compiled to WebAssembly. The runtime (~10 MB) is downloaded only when you open the editor, and cached after that. If you never click, this page is as light as any other.

Start small

The classic, but make it 1998:

for greeting in ["Hello, World!", "It is now safe to run some Python."]:
    print(greeting)

Change the strings, press F5, live a little.

Estimate π by throwing darts

Monte Carlo estimation: throw random darts at a square, count how many land inside the circle. Crank n up and watch the estimate improve:

import random

def estimate_pi(n):
    inside = sum(
        1
        for _ in range(n)
        if random.random() ** 2 + random.random() ** 2 <= 1
    )
    return 4 * inside / n

for n in [100, 10_000, 1_000_000]:
    print(f"n = {n:>9,}  ->  pi ~ {estimate_pi(n):.5f}")

Check the math post's homework

In Math on this blog I claimed that n=11n2=π26. Don't take my word for it:

import math

partial = sum(1 / n**2 for n in range(1, 100_001))
print(f"sum of 1/n^2 (100k terms): {partial:.10f}")
print(f"pi^2 / 6:                  {math.pi**2 / 6:.10f}")

Even numpy works

Imports of scientific packages are fetched automatically on first use. numpy is an extra download (a few MB), so the first run takes a moment. Here's the rotation matrix from the math post, as code:

import numpy as np

theta = np.radians(90)
R = np.array([
    [np.cos(theta), -np.sin(theta)],
    [np.sin(theta),  np.cos(theta)],
])

x = np.array([1.0, 0.0])
print("x rotated 90 degrees:", np.round(R @ x, 3))

Some snippets come pre-run

A block with a black Output pane under it didn't wait for you: it ran when this page was built, on a real CPython, and whatever it printed was pasted in. Read the answer without clicking, then click anyway if you don't believe it. Same code, two runtimes, and the pane is my problem if they ever disagree.

How much of a problem 1998 would have had with this page, for instance:

runtime_bytes = 10 * 1024 * 1024   # Pyodide, roughly
floppy_bytes = 1_474_560           # one 1.44 MB HD floppy, actual capacity
modem_kbps = 56                    # V.90, downstream, on a good day

floppies = -(-runtime_bytes // floppy_bytes)          # ceiling division
minutes = runtime_bytes * 8 / (modem_kbps * 1000) / 60

print(f"Python runtime:   {runtime_bytes:,} bytes")
print(f"Floppy disks:     {floppies}   (label them 1 of {floppies}...)")
print(f"Over a 56k modem: {minutes:.0f} minutes")
Python runtime:   10,485,760 bytes
Floppy disks:     8   (label them 1 of 8...)
Over a 56k modem: 25 minutes

The catch, for me rather than for you: a pre-run snippet has to print the same thing every time, or the post would quietly rewrite itself on every build. Which is exactly why the darts above aren't pre-run. Being different every time is the whole point of them.

The fine print

  • Everything runs client-side in a sandbox, so you can't break the blog. Go wild.
  • The editor shares one Python session per page visit, so variables survive between runs until you close the tab.
  • File → Save writes to the virtual C:\ drive (your browser's localStorage). No cloud, no sync, no backups, just like a real hard drive from 1998.
  • It runs on the page's main thread: while True: pass will freeze the tab, exactly like it froze the family computer in 1998. Some traditions are worth keeping.
Comments

429 words

Modified: 2026-07-28

© 2026 Mattias

Blog — mattiasfest.in

10 object(s)

untitled.py - Python.exe

        

Ready

Python 3 (Pyodide)

The Internet

Connecting to The Information Superhighway
Dialing 555-1998...

Ready

Internet zone (1998)

Find: All Files

Ready

Monitoring New Items