Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
user:hof:pyeditor [2024-05-21 20:42] – [Bottom.ch with direct component] hofuser:hof:pyeditor [2026-08-20 19:49] (aktuell) – [Installing files] hof
Zeile 1: Zeile 1:
-# Inline Python Editors+# Bottom Python Editor
  
-## Bottom.ch with iframe +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.
-With iframe on bottom.ch/ksr/py/embed.html, which is based on pyodide and codemirror.+
  
-<code html> +Also see [[~kara]] for a Kara shim on top of bottom-editor. 
-<html><iframe frameborder="0" width="100%" allow="clipboard-write" src="https://tkilla77.github.io/python_editor_wasm/embed.html?autorun&code=print%28%27Hello%2C+dokuwiki%21%27%29"></iframe></html></code>+## 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.
  
-<html><iframe frameborder="0" width="100%" allow="clipboard-write" src="https://tkilla77.github.io/python_editor_wasm/embed.html?autorun&code=print%28%27Hello%2C+dokuwiki%21%27%29"></iframe></html> 
-## Bottom.ch with direct component 
 <code html> <code html>
-<!-- Include the script once (or from a DokuWiki plugin, or from userscripts. --> +<!-- Include the script once (or from a DokuWiki plugin, or from userscripts). --> 
-<html><script type="module" src="https://bottom.ch/ksr/ed/bottom-editor.js"></script></html>+<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. --> <!-- Include a custom component in HTML. Use height, min-height, max-height to control the size. -->
-<html><bottom-editor style="min-height: 10lh;">print(42)</bottom-editor></html>+<!-- Leading empty lines will be dropped. --> 
 +<html><bottom-editor style="min-height: 6lh;" autorun> 
 +print(42) 
 +</bottom-editor></html>
 </code> </code>
-<html><script type="module" src="https://bottom.ch/ksr/ed/bottom-editor.js"></script></html> 
  
-<html><bottom-editor style="min-height: 10lh;">print(42) +### With Plugin 
-print(21)</bottom-editor></html>+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/2m/data/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/2m/data/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 + &hellip; + n</tt>. Return <tt>0</tt> for 
 +            <tt>n &le; 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 + &hellip; + n</tt>. Return <tt>0</tt> for 
 +            <tt>n &le; 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>
  
-## JupyterLite 
  
-Also based on pyodide, but with jupyter support all around.+<bottom-editor style="min-height: 6lh;" id="storage-42"> 
 +print(42) 
 +</bottom-editor>
  
-<code html><iframe 
-  src="https://jupyterlite.github.io/demo/repl/index.html" 
-  width="100%" 
-  height="500px"></iframe></code> 
  • user/hof/pyeditor.1716324136.txt.gz
  • Zuletzt geändert: 2024-05-21 20:42
  • von hof