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-02-28 18:37] – [First try: bottom.ch] hofuser:hof:pyeditor [2026-04-24 14:29] (aktuell) hof
Zeile 1: Zeile 1:
-First try: bottom.ch +Bottom Python Editor 
-With iframe on bottom.ch/ksr/py/embed.html, which is based on pyodide and codemirror.+ 
 +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> <code 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></code>+<!-- 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>
  
-<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>+<!-- 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-height6lh;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 + &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>
  
-# Second try: JupyterLite 
  
-Also based on pyodide, but with jupyter support all around.+<bottom-editor style="min-height: 6lh;" id="storage-42"> 
 +print(42) 
 +</bottom-editor>
  
-<html><iframe 
-  src="https://jupyterlite.github.io/demo/repl/index.html" 
-  width="100%" 
-  height="500px"></iframe></html> 
  • user/hof/pyeditor.1709145463.txt.gz
  • Zuletzt geändert: 2024-02-28 18:37
  • von hof