Seite anzeigenÄltere VersionenLinks hierherCopy this pageFold/unfold allNach oben Diese Seite ist nicht editierbar. Du kannst den Quelltext sehen, jedoch nicht verändern. Kontaktiere den Administrator, wenn du glaubst, dass hier ein Fehler vorliegt. # 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 [[https://bottom.ch/editor/stable/doc/|public documentation]] for all options. Also see [[~kara]] for a Kara shim on top of bottom-editor. ## Basic Usage ### Direct HTML Requires HTML-authoring (which may be a security risk with broad authorship). Within Dokuwiki, the HTML needs to be embedded into `<html>` tags for verbatim HTML. <code 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> </code> ### With Plugin To avoid needing raw trusted HTML access, install the [[https://www.dokuwiki.org/plugin:bottomeditor|bottomeditor plugin]] and create editors without `<html>`: <code html> <bottom-editor style="min-height: 6lh;" autorun> print(42) </bottom-editor> </code> ## Shared Sessions 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: <code html> <bottom-editor session="one" autorun> def greet(name): print(f'Hi, {name}!') </bottom-editor> <bottom-editor session="one" autorun> greet('Harry') # works </bottom-editor> <bottom-editor session="two" autorun> greet('Harry') # fails </bottom-editor> </code> <bottom-editor session="one" autorun> def greet(name): print(f'Hi, {name}!') </bottom-editor> <bottom-editor session="one" autorun> greet('Harry') # works </bottom-editor> <bottom-editor session="two" autorun> greet('Harry') # fails </bottom-editor> ## Turtle Standard Python turtle with a small canvas. Use `layout="split"` to have both canvas and console. <code html> <bottom-editor layout="canvas" autorun id="turtle"> 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> </code> <bottom-editor layout="canvas" autorun id="turtle"> 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> ## Matplotlib `plt.show()` renders to the canvas. <code html> <bottom-editor layout="canvas" autorun id="matplotlib"> # 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> </code> <bottom-editor layout="canvas" autorun id="matplot"> # 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> ## OpenCV `cv2.imshow()` renders to the canvas. <code html> <bottom-editor layout="canvas" autorun id="opencv"> # 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> </code> <bottom-editor layout="canvas" autorun id="opencv"> # 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> ## Installing files You can install files from an URL (with CORS headers if from a different domain!): <code html> <bottom-editor zip='https://bottom.ch/ksr/py/files/2m.zip' id="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> </code> <bottom-editor zip='https://bottom.ch/ksr/py/files/2m.zip' id="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> ## Exercises <code html> <bottom-exercise id="sum-to_n"> Write a function <tt>sum_to(n)</tt> that returns <tt>1 + 2 + … + n</tt>. Return <tt>0</tt> for <tt>n ≤ 0</tt>. <script type="text/x-starter"> def sum_to(n): pass </script> <script type="text/x-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" </script> <script type="text/x-solution"> def sum_to(n): return sum(range(n+1)) </script> </bottom-exercise> </code> <bottom-exercise id="sum-to_n"> Write a function <tt>sum_to(n)</tt> that returns <tt>1 + 2 + … + n</tt>. Return <tt>0</tt> for <tt>n ≤ 0</tt>. <script type="text/x-starter"> def sum_to(n): pass </script> <script type="text/x-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" </script> <script type="text/x-solution"> def sum_to(n): return sum(range(n+1)) </script> </bottom-exercise> ## Persistence Editors or excercises with an `id` attribute store the current state in the browser's local storage. If enabled, user's can opt to store a copy on Google Drive or Microsoft OneDrive. <code html> <bottom-editor style="min-height: 6lh;" id="storage-42"> print(42) </bottom-editor> </code> <bottom-editor style="min-height: 6lh;" id="storage-42"> print(42) </bottom-editor> user/hof/pyeditor.txt Zuletzt geändert: 2026-04-24 14:29von hof