Bottom Python Editor

Bottom Editor offers a standalone editor version at https://bottom.ch/editor/ and a web component embeddable as normal HTML elements after loading the module once. See the public documentation for all options.

Also see Python Kara im Wiki for a Kara shim on top of bottom-editor.

Within Dokuwiki, the HTML needs to be embedded into <html> tags for verbatim HTML.

<!-- Include the script once (or from a DokuWiki plugin, or from userscripts). -->
<html><script type="module" src="https://bottom.ch/editor/stable/bottom-editor.js"></script></html>
 
<!-- Include a custom component in HTML. Use height, min-height, max-height to control the size. -->
<!-- Leading empty lines will be dropped. -->
<html><bottom-editor style="min-height: 6lh;" autorun>
print(42)
</bottom-editor></html>

By default, all editors on a page share a single python runtime. Functions defined in one execution are available in all editors afterwards, similar to jupyter notebooks. If you want an editor to have a separate python runtime, use the session attribute:

<html><bottom-editor session="one" autorun>
def greet(name):
    print(f'Hi, {name}!')
</bottom-editor></html>
 
<html><bottom-editor session="one" autorun>
greet('Harry') # works
</bottom-editor></html>
 
<html><bottom-editor session="two" autorun>
greet('Harry') # fails
</bottom-editor></html>

def greet(name): print(f'Hi, {name}!')

greet('Harry') # works

greet('Harry') # fails

Standard Python turtle with a small canvas. Use layout="split" to have both canvas and console.

<html><bottom-editor layout="canvas" autorun>
import turtle
 
t = turtle.Turtle()
t.speed(9)
colors = ['red', 'orange', 'gold', 'green', 'blue', 'purple']
for i in range(90):
    t.pencolor(colors[i % len(colors)])
    t.forward(i * 0.5)
    t.left(59)
</bottom-editor></html>

import turtle t = turtle.Turtle() t.speed(9) colors = ['red', 'orange', 'gold', 'green', 'blue', 'purple'] for i in range(90): t.pencolor(colors[i % len(colors)]) t.forward(i * 0.5) t.left(59)

plt.show() renders to the canvas.

<html><bottom-editor layout="canvas" autorun>
# Load packages from within python using micropip
import micropip
await micropip.install('matplotlib')
 
import matplotlib.pyplot as plt
import math
 
x = [i * 0.1 for i in range(63)]
plt.figure(figsize=(5, 4))
plt.plot(x, [math.sin(v) for v in x], label='sin')
plt.plot(x, [math.cos(v) for v in x], label='cos')
plt.legend()
plt.title('Trigonometric functions')
plt.tight_layout()
plt.show()
</bottom-editor></html>

# Load packages from within python using micropip import micropip await micropip.install('matplotlib') import matplotlib.pyplot as plt import math x = [i * 0.1 for i in range(63)] plt.figure(figsize=(5, 4)) plt.plot(x, [math.sin(v) for v in x], label='sin') plt.plot(x, [math.cos(v) for v in x], label='cos') plt.legend() plt.title('Trigonometric functions') plt.tight_layout() plt.show()

cv2.imshow() renders to the canvas.

<html><bottom-editor layout="canvas" autorun>
# Load packages from within python using micropip
import micropip
await micropip.install('numpy')
await micropip.install('opencv-python')
 
import numpy as np
import cv2
 
# Gradient image with a circle
img = np.zeros((300, 300, 3), dtype=np.uint8)
for y in range(300):
    for x in range(300):
        img[y, x] = [x * 255 // 300, y * 255 // 300, 128]
cv2.circle(img, (150, 150), 80, (255, 255, 255), 3)
cv2.putText(img, 'OpenCV', (75, 160), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2)
cv2.imshow('result', img)
</bottom-editor></html>

# Load packages from within python using micropip import micropip await micropip.install('numpy') await micropip.install('opencv-python') import numpy as np import cv2 # Gradient image with a circle img = np.zeros((300, 300, 3), dtype=np.uint8) for y in range(300): for x in range(300): img[y, x] = [x * 255 // 300, y * 255 // 300, 128] cv2.circle(img, (150, 150), 80, (255, 255, 255), 3) cv2.putText(img, 'OpenCV', (75, 160), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2) cv2.imshow('result', img)

You can install files from an URL (with CORS headers if from a different domain!):

<html><bottom-editor zip='https://bottom.ch/ksr/py/files/2m.zip'>
with open('gemeinden.csv', 'r') as infile:
    for line in infile:
        tokens = line.split(',')
        town = tokens[0]
        if town == 'Romanshorn':
            print(f'Romanshorn hat {tokens[2]} Einwohner')
</bottom-editor></html>

with open('gemeinden.csv', 'r') as infile: for line in infile: tokens = line.split(',') town = tokens[0] if town == 'Romanshorn': print(f'Romanshorn hat {tokens[2]} Einwohner')

   <html><script type="module" src="https://bottom.ch/editor/latest/bottom-exercise.js"></script></html>
   <html><bottom-exercise>
        <div slot="prompt">
            <p>Write a function <tt>sum_to(n)</tt> that returns
            <tt>1 + 2 + &hellip; + n</tt>. Return <tt>0</tt> for
            <tt>n &le; 0</tt>.</p>
        </div>
        <template data-type="starter">
def sum_to(n):
    pass
        </template>
        <template data-type="test">
assert sum_to(5) == 15, "sum_to(5) should be 15"
assert sum_to(1) == 1, "sum_to(1) should be 1"
assert sum_to(0) == 0, "sum_to(0) should be 0"
        </template>
    </bottom-exercise></html>

Write a function sum_to(n) that returns 1 + 2 + … + n. Return 0 for n ≤ 0.

  • user/hof/pyeditor.1776029063.txt.gz
  • Zuletzt geändert: 2026-04-12 21:24
  • von hof