mirror of https://github.com/pyodide/pyodide.git
Partially address #338: Provide simple method for interactive testing
This adds a basic repl-like console webpage that can be used for testing of the local pyodide install. It removes the broken examples based on standalone iodide.
This commit is contained in:
parent
89eca5f5b7
commit
7441d5250e
25
Makefile
25
Makefile
|
@ -50,10 +50,7 @@ all: build/pyodide.asm.js \
|
|||
build/pyodide.asm.data \
|
||||
build/pyodide.js \
|
||||
build/pyodide_dev.js \
|
||||
build/python.html \
|
||||
build/python_dev.html \
|
||||
build/matplotlib.html \
|
||||
build/matplotlib-sideload.html \
|
||||
build/console.html \
|
||||
build/renderedhtml.css \
|
||||
build/test.data \
|
||||
build/packages.json \
|
||||
|
@ -91,26 +88,14 @@ build/pyodide.js: src/pyodide.js
|
|||
sed -i -e "s#{{ABI}}#$(PYODIDE_PACKAGE_ABI)#g" $@
|
||||
|
||||
|
||||
build/python.html: src/python.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/python_dev.html: src/python_dev.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/matplotlib.html: src/matplotlib.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/matplotlib-sideload.html: src/matplotlib-sideload.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/test.html: src/test.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/console.html: src/console.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/renderedhtml.css: src/renderedhtml.less
|
||||
lessc $< $@
|
||||
|
||||
|
|
13
README.md
13
README.md
|
@ -66,24 +66,27 @@ on your `PATH`.
|
|||
|
||||
# Manual Testing
|
||||
|
||||
The port 8000 of the docker environment and the host system are automatically
|
||||
The port 8000 of the docker environment and the host system are automatically
|
||||
binded when ``./run_docker`` is run.
|
||||
|
||||
This can be used to test the ``pyodide`` builds running within the docker
|
||||
This can be used to test the ``pyodide`` builds running within the docker
|
||||
environment using external browser programs on the host system.
|
||||
|
||||
To do this, simply run ``./bin/pyodide serve``
|
||||
|
||||
This serves the ``build`` directory of the ``pyodide`` project on port 8000.
|
||||
|
||||
* To serve a different directory, use the ``--build_dir`` argument followed by
|
||||
* To serve a different directory, use the ``--build_dir`` argument followed by
|
||||
the path of the directory
|
||||
* To serve on a different port, use the ``--port`` argument followed by the
|
||||
* To serve on a different port, use the ``--port`` argument followed by the
|
||||
desired port number
|
||||
|
||||
Make sure that the port passed in ``--port`` argument is same as the one
|
||||
Make sure that the port passed in ``--port`` argument is same as the one
|
||||
defined as ``DOCKER_PORT`` in the ``run_docker`` script.
|
||||
|
||||
Once the webserver is running, for simple interactive testing, visit the URL
|
||||
[http://localhost:8000/console.html](http://localhost:8000/console.html)
|
||||
|
||||
# Benchmarking
|
||||
|
||||
Install the same dependencies as for testing.
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script src="https://code.jquery.com/jquery-latest.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>
|
||||
<script src="./pyodide_dev.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
languagePluginLoader.then(() => {
|
||||
pyodide.runPython('import io, code, sys');
|
||||
pyodide.runPython('_c = code.InteractiveConsole(locals=globals())')
|
||||
var c = pyodide.pyimport('_c')
|
||||
function handleResult(result) {
|
||||
if (result) {
|
||||
term.set_prompt('[[;gray;]... ]')
|
||||
} else {
|
||||
term.set_prompt('[[;red;]>>> ]')
|
||||
}
|
||||
var stderr = pyodide.runPython("sys.stderr.getvalue()").trim()
|
||||
if (stderr) {
|
||||
term.echo(`[[;red;]${stderr}]`)
|
||||
} else {
|
||||
var stdout = pyodide.runPython("sys.stdout.getvalue()")
|
||||
term.echo(stdout.trim())
|
||||
}
|
||||
}
|
||||
function pushCode(line) {
|
||||
pyodide.runPython('sys.stdout = io.StringIO()')
|
||||
pyodide.runPython('sys.stderr = io.StringIO()')
|
||||
if (line.startsWith('import ')) {
|
||||
pyodide.runPythonAsync(line).then(handleResult)
|
||||
} else {
|
||||
handleResult(c.push(line))
|
||||
}
|
||||
}
|
||||
var term = $('body').terminal(
|
||||
pushCode,
|
||||
{
|
||||
greetings: "Welcome to the Pyodide terminal emulator 🐍",
|
||||
prompt: "[[;red;]>>> ]"
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -2,45 +2,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Python - iodide</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://iodide.io/dist/iodide.pyodide-20180623.css">
|
||||
<title>Loading matplotlib example...</title>
|
||||
</head>
|
||||
<body>
|
||||
<script id="jsmd" type="text/jsmd">
|
||||
%% meta
|
||||
{
|
||||
"title": "Python",
|
||||
"languages": {
|
||||
"js": {
|
||||
"pluginType": "language",
|
||||
"languageId": "js",
|
||||
"displayName": "Javascript",
|
||||
"codeMirrorMode": "javascript",
|
||||
"module": "window",
|
||||
"evaluator": "eval",
|
||||
"keybinding": "j",
|
||||
"url": ""
|
||||
},
|
||||
"py": {
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
},
|
||||
"lastExport": "2018-05-04T17:13:00.489Z"
|
||||
}
|
||||
|
||||
%% md
|
||||
|
||||
Press Shift+Enter on the cell below to display the plot.
|
||||
|
||||
%% code {"language":"py"}
|
||||
</script>
|
||||
<script>
|
||||
var blackout = document.createElement('div');
|
||||
blackout.setAttribute('style', 'width: 100%; height: 100%; position: absolute; left: 0; top: 0; background-color: #00000066; z-index: 10');
|
||||
|
@ -48,24 +12,20 @@ Press Shift+Enter on the cell below to display the plot.
|
|||
|
||||
var url_string = window.location;
|
||||
var url = new URL(url_string);
|
||||
var content = url.searchParams.get("sideload");
|
||||
var content = url.searchParams.get("example");
|
||||
fetch(content).then((response) => response.text())
|
||||
.then((text) => {
|
||||
let jsmd = document.getElementById('jsmd');
|
||||
jsmd.innerHTML = jsmd.innerHTML + text;
|
||||
let script = document.createElement('script');
|
||||
script.src = 'https://iodide.io/dist/iodide.pyodide-20180623.js';
|
||||
script.onload = () => {
|
||||
let pyodide = document.createElement('script');
|
||||
pyodide.src = 'https://iodide.io/pyodide-demo/pyodide.js';
|
||||
pyodide.onload = () => {
|
||||
languagePluginLoader.then(() => {
|
||||
window.pyodide.loadPackage('matplotlib').then(() => {
|
||||
window.pyodide.runPython('__name__ = "__main__"');
|
||||
blackout.parentNode.removeChild(blackout);
|
||||
});
|
||||
let pyodide = document.createElement('script');
|
||||
pyodide.src = 'pyodide_dev.js';
|
||||
pyodide.onload = () => {
|
||||
languagePluginLoader.then(() => {
|
||||
window.pyodide.loadPackage('matplotlib').then(() => {
|
||||
window.pyodide.runPython('__name__ = "__main__"');
|
||||
blackout.parentNode.removeChild(blackout);
|
||||
});
|
||||
};
|
||||
});
|
||||
document.body.appendChild(pyodide);
|
||||
}
|
||||
document.body.appendChild(script);
|
||||
|
|
|
@ -1,209 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Python - iodide</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://iodide.io/dist/iodide.pyodide-20180623.css">
|
||||
</head>
|
||||
<body>
|
||||
<script id="jsmd" type="text/jsmd">
|
||||
%% meta
|
||||
{
|
||||
"title": "Python",
|
||||
"languages": {
|
||||
"js": {
|
||||
"pluginType": "language",
|
||||
"languageId": "js",
|
||||
"displayName": "Javascript",
|
||||
"codeMirrorMode": "javascript",
|
||||
"module": "window",
|
||||
"evaluator": "eval",
|
||||
"keybinding": "j",
|
||||
"url": ""
|
||||
},
|
||||
"py": {
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
},
|
||||
"lastExport": "2018-05-04T17:13:00.489Z"
|
||||
}
|
||||
|
||||
%% plugin
|
||||
{
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
|
||||
%% js
|
||||
|
||||
pyodide.loadPackage('matplotlib')
|
||||
|
||||
%% code {"language":"py"}
|
||||
from matplotlib import pyplot as plt
|
||||
plt.plot([1,2,3])
|
||||
plt.show()
|
||||
|
||||
%% code {"language":"py"}
|
||||
import matplotlib.cm as cm
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Circle, PathPatch
|
||||
from matplotlib.path import Path
|
||||
from matplotlib.transforms import Affine2D
|
||||
import numpy as np
|
||||
|
||||
|
||||
r = np.random.rand(50)
|
||||
t = np.random.rand(50) * np.pi * 2.0
|
||||
x = r * np.cos(t)
|
||||
y = r * np.sin(t)
|
||||
|
||||
fig, ax = plt.subplots(figsize=(6, 6))
|
||||
circle = Circle((0, 0), 1, facecolor='none',
|
||||
edgecolor=(0, 0.8, 0.8), linewidth=3, alpha=0.5)
|
||||
ax.add_patch(circle)
|
||||
|
||||
im = plt.imshow(np.random.random((100, 100)),
|
||||
origin='lower', cmap=cm.winter,
|
||||
interpolation='spline36',
|
||||
extent=([-1, 1, -1, 1]))
|
||||
im.set_clip_path(circle)
|
||||
|
||||
plt.plot(x, y, 'o', color=(0.9, 0.9, 1.0), alpha=0.8)
|
||||
|
||||
# Dolphin from OpenClipart library by Andy Fitzsimon
|
||||
# <cc:License rdf:about="http://web.resource.org/cc/PublicDomain">
|
||||
# <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
|
||||
# <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
|
||||
# <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
|
||||
# </cc:License>
|
||||
|
||||
dolphin = """
|
||||
M -0.59739425,160.18173 C -0.62740401,160.18885 -0.57867129,160.11183
|
||||
-0.57867129,160.11183 C -0.57867129,160.11183 -0.5438361,159.89315
|
||||
-0.39514638,159.81496 C -0.24645668,159.73678 -0.18316813,159.71981
|
||||
-0.18316813,159.71981 C -0.18316813,159.71981 -0.10322971,159.58124
|
||||
-0.057804323,159.58725 C -0.029723983,159.58913 -0.061841603,159.60356
|
||||
-0.071265813,159.62815 C -0.080250183,159.65325 -0.082918513,159.70554
|
||||
-0.061841203,159.71248 C -0.040763903,159.7194 -0.0066711426,159.71091
|
||||
0.077336307,159.73612 C 0.16879567,159.76377 0.28380306,159.86448
|
||||
0.31516668,159.91533 C 0.3465303,159.96618 0.5011127,160.1771
|
||||
0.5011127,160.1771 C 0.63668998,160.19238 0.67763022,160.31259
|
||||
0.66556395,160.32668 C 0.65339985,160.34212 0.66350443,160.33642
|
||||
0.64907098,160.33088 C 0.63463742,160.32533 0.61309688,160.297
|
||||
0.5789627,160.29339 C 0.54348657,160.28968 0.52329693,160.27674
|
||||
0.50728856,160.27737 C 0.49060916,160.27795 0.48965803,160.31565
|
||||
0.46114204,160.33673 C 0.43329696,160.35786 0.4570711,160.39871
|
||||
0.43309565,160.40685 C 0.4105108,160.41442 0.39416631,160.33027
|
||||
0.3954995,160.2935 C 0.39683269,160.25672 0.43807996,160.21522
|
||||
0.44567915,160.19734 C 0.45327833,160.17946 0.27946869,159.9424
|
||||
-0.061852613,159.99845 C -0.083965233,160.0427 -0.26176109,160.06683
|
||||
-0.26176109,160.06683 C -0.30127962,160.07028 -0.21167141,160.09731
|
||||
-0.24649368,160.1011 C -0.32642366,160.11569 -0.34521187,160.06895
|
||||
-0.40622293,160.0819 C -0.467234,160.09485 -0.56738444,160.17461
|
||||
-0.59739425,160.18173
|
||||
"""
|
||||
|
||||
vertices = []
|
||||
codes = []
|
||||
parts = dolphin.split()
|
||||
i = 0
|
||||
code_map = {
|
||||
'M': (Path.MOVETO, 1),
|
||||
'C': (Path.CURVE4, 3),
|
||||
'L': (Path.LINETO, 1)
|
||||
}
|
||||
|
||||
while i < len(parts):
|
||||
code = parts[i]
|
||||
path_code, npoints = code_map[code]
|
||||
codes.extend([path_code] * npoints)
|
||||
vertices.extend([[float(x) for x in y.split(',')] for y in
|
||||
parts[i + 1:i + npoints + 1]])
|
||||
i += npoints + 1
|
||||
vertices = np.array(vertices, np.float)
|
||||
vertices[:, 1] -= 160
|
||||
|
||||
dolphin_path = Path(vertices, codes)
|
||||
dolphin_patch = PathPatch(dolphin_path, facecolor=(0.6, 0.6, 0.6),
|
||||
edgecolor=(0.0, 0.0, 0.0))
|
||||
ax.add_patch(dolphin_patch)
|
||||
|
||||
vertices = Affine2D().rotate_deg(60).transform(vertices)
|
||||
dolphin_path2 = Path(vertices, codes)
|
||||
dolphin_patch2 = PathPatch(dolphin_path2, facecolor=(0.5, 0.5, 0.5),
|
||||
edgecolor=(0.0, 0.0, 0.0))
|
||||
ax.add_patch(dolphin_patch2)
|
||||
|
||||
plt.show()
|
||||
|
||||
%% code {"language":"py"}
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.tri import Triangulation
|
||||
from matplotlib.patches import Polygon
|
||||
import numpy as np
|
||||
|
||||
|
||||
def update_polygon(tri):
|
||||
if tri == -1:
|
||||
points = [0, 0, 0]
|
||||
else:
|
||||
points = triang.triangles[tri]
|
||||
xs = triang.x[points]
|
||||
ys = triang.y[points]
|
||||
polygon.set_xy(np.column_stack([xs, ys]))
|
||||
|
||||
|
||||
def motion_notify(event):
|
||||
if event.inaxes is None:
|
||||
tri = -1
|
||||
else:
|
||||
tri = trifinder(event.xdata, event.ydata)
|
||||
update_polygon(tri)
|
||||
plt.title('In triangle %i' % tri)
|
||||
event.canvas.draw()
|
||||
|
||||
|
||||
# Create a Triangulation.
|
||||
n_angles = 16
|
||||
n_radii = 5
|
||||
min_radius = 0.25
|
||||
radii = np.linspace(min_radius, 0.95, n_radii)
|
||||
angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False)
|
||||
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
|
||||
angles[:, 1::2] += np.pi / n_angles
|
||||
x = (radii*np.cos(angles)).flatten()
|
||||
y = (radii*np.sin(angles)).flatten()
|
||||
triang = Triangulation(x, y)
|
||||
triang.set_mask(np.hypot(x[triang.triangles].mean(axis=1),
|
||||
y[triang.triangles].mean(axis=1))
|
||||
< min_radius)
|
||||
|
||||
# Use the triangulation's default TriFinder object.
|
||||
trifinder = triang.get_trifinder()
|
||||
|
||||
# Setup plot and callbacks.
|
||||
plt.subplot(111, aspect='equal')
|
||||
plt.triplot(triang, 'bo-')
|
||||
polygon = Polygon([[0, 0], [0, 0]], facecolor='y') # dummy data for xs,ys
|
||||
update_polygon(-1)
|
||||
plt.gca().add_patch(polygon)
|
||||
plt.gcf().canvas.mpl_connect('motion_notify_event', motion_notify)
|
||||
plt.show()
|
||||
</script>
|
||||
<div id='page'></div>
|
||||
<script src='https://iodide.io/dist/iodide.pyodide-20180623.js'></script>
|
||||
</body>
|
||||
</html>
|
267
src/python.html
267
src/python.html
|
@ -1,267 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Python - iodide</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://iodide.io/dist/iodide.pyodide-20180623.css">
|
||||
</head>
|
||||
<body>
|
||||
<script id="jsmd" type="text/jsmd">
|
||||
%% meta
|
||||
{
|
||||
"title": "Python",
|
||||
"languages": {
|
||||
"js": {
|
||||
"pluginType": "language",
|
||||
"languageId": "js",
|
||||
"displayName": "Javascript",
|
||||
"codeMirrorMode": "javascript",
|
||||
"module": "window",
|
||||
"evaluator": "eval",
|
||||
"keybinding": "j",
|
||||
"url": ""
|
||||
},
|
||||
"py": {
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
},
|
||||
"lastExport": "2018-05-04T17:13:00.489Z"
|
||||
}
|
||||
|
||||
%% md
|
||||
# Pyodide 🐍
|
||||
|
||||
Pyodide adds support for Python in an Iodide notebook, running inside your browser.
|
||||
|
||||
**This is early days. Everything here is subject to change.**
|
||||
|
||||
(A major shortcoming is that `print` from Python currently prints to the Javascript debugger console, rather than to the notebook cell, so some of these examples are more contrived than they need to be.)
|
||||
|
||||
**Also to note: If you have any issues, try disabling any ad or tracking blockers for this site.**
|
||||
|
||||
First, let's use a plugin cell to load the Python interpreter and tell Iodide about the new cell type.
|
||||
|
||||
%% plugin
|
||||
{
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
|
||||
%% md
|
||||
|
||||
## Make a Python cell. Import stuff and use it.
|
||||
|
||||
Most of the standard library (at least the parts that make sense) are here and available to use.
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
import sys
|
||||
sys.version
|
||||
|
||||
%% md
|
||||
## Basic data types
|
||||
|
||||
The basic data types (None, bool, ints, floats, lists, and dicts) are converted from Python to Javascript when they are output and displayed using the standard mechanisms in Iodide.
|
||||
|
||||
%% code {"language":"py"}
|
||||
[0, 1, 32.0, 'foo', {'a': 10, 'b': '20'}, b'bytes']
|
||||
|
||||
%% md
|
||||
## Sharing objects between Python and Javascript
|
||||
|
||||
The Python and Javascript sides can pass objects back and forth.
|
||||
|
||||
So, you can set a value in Javascript code:
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
secret = "Wklv#lv#olnh#pdjlf$"
|
||||
|
||||
%% md
|
||||
...and use it from Python by using `from js import ...`:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
from js import secret
|
||||
|
||||
decoded = ''.join(chr(ord(x) - 3) for x in secret)
|
||||
|
||||
%% md
|
||||
...and then get it back from Javascript using `pyodide.pyimport`:
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
var decoded = pyodide.pyimport("decoded")
|
||||
decoded
|
||||
|
||||
%% md
|
||||
## Custom data types
|
||||
|
||||
Non-basic data types, such as class instances, functions, File objects etc., can also be passed between Python and Javascript.
|
||||
|
||||
### Using Python objects from Javascript
|
||||
|
||||
For example, say we had the following Python function that we wanted to call from Javascript:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
def square(x):
|
||||
return x * x
|
||||
|
||||
%% md
|
||||
Since calling conventions are a bit different in Python than in Javascript, all Python callables take two arguments when called from Javascript: the positional arguments as an array, and the keyword arguments as an object.
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
var square = pyodide.pyimport("square")
|
||||
square(2.5)
|
||||
|
||||
%% md
|
||||
This is equivalent to the following Python syntax:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
square(2.5)
|
||||
|
||||
%% md
|
||||
You can also get the attributes of objects in a similar way. Say we had an instance of the following Python custom class:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
class Foo:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
foo = Foo(42)
|
||||
foo
|
||||
|
||||
%% md
|
||||
We can get the value of its `val` property as so:
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
var foo = pyodide.pyimport("foo")
|
||||
foo.val
|
||||
|
||||
%% md
|
||||
### Using Javascript objects from Python
|
||||
|
||||
Likewise, you can use Javascript objects from Python.
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
function cube(x) {
|
||||
return x*x*x;
|
||||
}
|
||||
|
||||
%% md
|
||||
To call this function from Python...
|
||||
|
||||
%% code {"language":"py"}
|
||||
from js import cube
|
||||
cube(4)
|
||||
|
||||
%% md
|
||||
## Exceptions
|
||||
|
||||
Python exceptions are converted to Javascript exceptions, and they include tracebacks.
|
||||
|
||||
%% code {"language":"py"}
|
||||
x = 5 / 0
|
||||
|
||||
%% md
|
||||
## World DOMination
|
||||
|
||||
By using `from js import document`, you can easily access the Web API from Python.
|
||||
|
||||
For example, get the title of the document:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
from js import document
|
||||
document.title
|
||||
|
||||
%% md
|
||||
You can set it, too:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
document.title = 'My mind is blown'
|
||||
|
||||
%% md
|
||||
We can set up a special `div` element from a markdown cell, and then manipulate it from Python.
|
||||
|
||||
<div id="targetDiv">This is a div we'll target from Python</div>
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
# Turn the div red
|
||||
document.getElementById("targetDiv").setAttribute("style", "background-color: red")
|
||||
|
||||
%% md
|
||||
## Numpy
|
||||
|
||||
You bet, [Numpy](http://numpy.org) works.
|
||||
|
||||
To save on download times, isn't loaded by default. We need to manually use
|
||||
the `pyodide.loadPackage` function from a Javascript cell.
|
||||
|
||||
%% js
|
||||
pyodide.loadPackage('numpy')
|
||||
|
||||
%% md
|
||||
Now that the Numpy package has been loaded (i.e. transferred to your local browser), we can import it:
|
||||
|
||||
%% code {"language":"py"}
|
||||
import numpy as np
|
||||
|
||||
%% md
|
||||
Let's make a simple array of zeros. When it's displayed, it's using the same output code that Iodide uses for Javascript.
|
||||
|
||||
(On a technical level, it's important to note that Pyodide doesn't need to copy the whole array over to the Javascript side to do this: it's only accessing the parts of the array it needs to make the display.)
|
||||
|
||||
%% code {"language":"py"}
|
||||
np.zeros((16, 16))
|
||||
|
||||
%% md
|
||||
### Estimating pi
|
||||
|
||||
Here's a fun example where we can estimate pi by generating a bunch of random (x, y) points and calculating the ratio of them that fall within the unit circle.
|
||||
|
||||
%% code {"language":"py"}
|
||||
from numpy import random
|
||||
points = (random.rand(1000, 2) * 2.0) - 1.0
|
||||
|
||||
%% code {"language":"py"}
|
||||
x = points[:, 0]
|
||||
y = points[:, 1]
|
||||
inside_circle = (x*x + y*y) < 1.0
|
||||
pi = (float(np.sum(inside_circle)) / float(len(points))) * 4.0
|
||||
pi
|
||||
|
||||
%% md
|
||||
## Coming soon..
|
||||
|
||||
A couple things that already work that will be coming to this example notebook soon...
|
||||
|
||||
- Pandas support
|
||||
- Plotting using D3 from Python
|
||||
|
||||
%% js
|
||||
</script>
|
||||
<div id='page'></div>
|
||||
<script src='https://iodide.io/dist/iodide.pyodide-20180623.js'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,68 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Python - iodide</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://iodide.io/dist/iodide.pyodide-20180623.css">
|
||||
</head>
|
||||
<body>
|
||||
<script id="jsmd" type="text/jsmd">
|
||||
%% meta
|
||||
{
|
||||
"title": "Python",
|
||||
"languages": {
|
||||
"js": {
|
||||
"pluginType": "language",
|
||||
"languageId": "js",
|
||||
"displayName": "Javascript",
|
||||
"codeMirrorMode": "javascript",
|
||||
"module": "window",
|
||||
"evaluator": "eval",
|
||||
"keybinding": "j",
|
||||
"url": ""
|
||||
},
|
||||
"py": {
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "./pyodide_dev.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
},
|
||||
"lastExport": "2018-05-04T17:13:00.489Z"
|
||||
}
|
||||
|
||||
%% md
|
||||
# Pyodide dev notebook 🐍
|
||||
|
||||
An iodide notebook used for developpement that loads the locally build packages
|
||||
|
||||
%% plugin
|
||||
{
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "./pyodide_dev.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
|
||||
%% js
|
||||
pyodide.loadPackage('numpy')
|
||||
|
||||
%% code {"language":"py"}
|
||||
import numpy as np
|
||||
|
||||
np.arange(2)
|
||||
|
||||
%% js
|
||||
</script>
|
||||
<div id='page'></div>
|
||||
<script src='https://iodide.io/dist/iodide.pyodide-20180623.js'></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue