mirror of
https://github.com/peter-tanner/starcore-explorer-bad.git
synced 2024-11-30 09:00:28 +08:00
Initial commit
This commit is contained in:
commit
4f010cec32
48
.github/workflows/deploy.yml
vendored
Normal file
48
.github/workflows/deploy.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
name: Build and Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.10'
|
||||||
|
- name: Install the dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install -r requirements.txt
|
||||||
|
- name: Build the JupyterLite site
|
||||||
|
run: |
|
||||||
|
cp README.md content
|
||||||
|
jupyter lite build --contents content --output-dir dist
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@v1
|
||||||
|
with:
|
||||||
|
path: ./dist
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
permissions:
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v1
|
116
.gitignore
vendored
Normal file
116
.gitignore
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
*.bundle.*
|
||||||
|
lib/
|
||||||
|
node_modules/
|
||||||
|
.yarn-packages/
|
||||||
|
*.egg-info/
|
||||||
|
.ipynb_checkpoints
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/python
|
||||||
|
# Edit at https://www.gitignore.io/?templates=python
|
||||||
|
|
||||||
|
### Python ###
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
share/python-wheels/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# Mr Developer
|
||||||
|
.mr.developer.cfg
|
||||||
|
.project
|
||||||
|
.pydevproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# OS X stuff
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/python
|
||||||
|
|
||||||
|
# jupyterlite
|
||||||
|
*.doit.db
|
||||||
|
_output
|
29
README.md
Normal file
29
README.md
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# JupyterLite Demo
|
||||||
|
|
||||||
|
[![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://jupyterlite.github.io/demo)
|
||||||
|
|
||||||
|
JupyterLite deployed as a static site to GitHub Pages, for demo purposes.
|
||||||
|
|
||||||
|
## ✨ Try it in your browser ✨
|
||||||
|
|
||||||
|
➡️ **https://jupyterlite.github.io/demo**
|
||||||
|
|
||||||
|
![github-pages](https://user-images.githubusercontent.com/591645/120649478-18258400-c47d-11eb-80e5-185e52ff2702.gif)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
JupyterLite is being tested against modern web browsers:
|
||||||
|
|
||||||
|
- Firefox 90+
|
||||||
|
- Chromium 89+
|
||||||
|
|
||||||
|
## Deploy your JupyterLite website on GitHub Pages
|
||||||
|
|
||||||
|
Check out the guide on the JupyterLite documentation: https://jupyterlite.readthedocs.io/en/latest/quickstart/deploy.html
|
||||||
|
|
||||||
|
## Further Information and Updates
|
||||||
|
|
||||||
|
For more info, keep an eye on the JupyterLite documentation:
|
||||||
|
|
||||||
|
- How-to Guides: https://jupyterlite.readthedocs.io/en/latest/howto/index.html
|
||||||
|
- Reference: https://jupyterlite.readthedocs.io/en/latest/reference/index.html
|
1
content/data/Museums_in_DC.geojson
Normal file
1
content/data/Museums_in_DC.geojson
Normal file
File diff suppressed because one or more lines are too long
54
content/data/bar.vl.json
Normal file
54
content/data/bar.vl.json
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"a": "A",
|
||||||
|
"b": 28
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "B",
|
||||||
|
"b": 55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "C",
|
||||||
|
"b": 43
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "D",
|
||||||
|
"b": 91
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "E",
|
||||||
|
"b": 81
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "F",
|
||||||
|
"b": 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "G",
|
||||||
|
"b": 19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "H",
|
||||||
|
"b": 87
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a": "I",
|
||||||
|
"b": 52
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "A simple bar chart with embedded data.",
|
||||||
|
"encoding": {
|
||||||
|
"x": {
|
||||||
|
"field": "a",
|
||||||
|
"type": "ordinal"
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"field": "b",
|
||||||
|
"type": "quantitative"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mark": "bar"
|
||||||
|
}
|
8
content/data/fasta-example.fasta
Normal file
8
content/data/fasta-example.fasta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
>SEQUENCE_1
|
||||||
|
MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG
|
||||||
|
LVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK
|
||||||
|
IPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL
|
||||||
|
MGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGLEKKTEDFAAEVAAQL
|
||||||
|
>SEQUENCE_2
|
||||||
|
SATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQI
|
||||||
|
ATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICMH
|
151
content/data/iris.csv
Normal file
151
content/data/iris.csv
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
sepal_length,sepal_width,petal_length,petal_width,species
|
||||||
|
5.1,3.5,1.4,0.2,se
|
||||||
|
4.9,3,1.4,0.2,setosa
|
||||||
|
4.7,3.2,1.3,0.2,setosa
|
||||||
|
4.6,3.1,1.5,0.2,setosa
|
||||||
|
5,3.6,1.4,0.2,setosa
|
||||||
|
5.4,3.9,1.7,0.4,setosa
|
||||||
|
4.6,3.4,1.4,0.3,setosa
|
||||||
|
5,3.4,1.5,0.2,setosa
|
||||||
|
4.4,2.9,1.4,0.2,setosa
|
||||||
|
4.9,3.1,1.5,0.1,setosa
|
||||||
|
5.4,3.7,1.5,0.2,setosa
|
||||||
|
4.8,3.4,1.6,0.2,setosa
|
||||||
|
4.8,3,1.4,0.1,setosa
|
||||||
|
4.3,3,1.1,0.1,setosa
|
||||||
|
5.8,4,1.2,0.2,setosa
|
||||||
|
5.7,4.4,1.5,0.4,setosa
|
||||||
|
5.4,3.9,1.3,0.4,setosa
|
||||||
|
5.1,3.5,1.4,0.3,setosa
|
||||||
|
5.7,3.8,1.7,0.3,setosa
|
||||||
|
5.1,3.8,1.5,0.3,setosa
|
||||||
|
5.4,3.4,1.7,0.2,setosa
|
||||||
|
5.1,3.7,1.5,0.4,setosa
|
||||||
|
4.6,3.6,1,0.2,setosa
|
||||||
|
5.1,3.3,1.7,0.5,setosa
|
||||||
|
4.8,3.4,1.9,0.2,setosa
|
||||||
|
5,3,1.6,0.2,setosa
|
||||||
|
5,3.4,1.6,0.4,setosa
|
||||||
|
5.2,3.5,1.5,0.2,setosa
|
||||||
|
5.2,3.4,1.4,0.2,setosa
|
||||||
|
4.7,3.2,1.6,0.2,setosa
|
||||||
|
4.8,3.1,1.6,0.2,setosa
|
||||||
|
5.4,3.4,1.5,0.4,setosa
|
||||||
|
5.2,4.1,1.5,0.1,setosa
|
||||||
|
5.5,4.2,1.4,0.2,setosa
|
||||||
|
4.9,3.1,1.5,0.1,setosa
|
||||||
|
5,3.2,1.2,0.2,setosa
|
||||||
|
5.5,3.5,1.3,0.2,setosa
|
||||||
|
4.9,3.1,1.5,0.1,setosa
|
||||||
|
4.4,3,1.3,0.2,setosa
|
||||||
|
5.1,3.4,1.5,0.2,setosa
|
||||||
|
5,3.5,1.3,0.3,setosa
|
||||||
|
4.5,2.3,1.3,0.3,setosa
|
||||||
|
4.4,3.2,1.3,0.2,setosa
|
||||||
|
5,3.5,1.6,0.6,setosa
|
||||||
|
5.1,3.8,1.9,0.4,setosa
|
||||||
|
4.8,3,1.4,0.3,setosa
|
||||||
|
5.1,3.8,1.6,0.2,setosa
|
||||||
|
4.6,3.2,1.4,0.2,setosa
|
||||||
|
5.3,3.7,1.5,0.2,setosa
|
||||||
|
5,3.3,1.4,0.2,setosa
|
||||||
|
7,3.2,4.7,1.4,versicolor
|
||||||
|
6.4,3.2,4.5,1.5,versicolor
|
||||||
|
6.9,3.1,4.9,1.5,versicolor
|
||||||
|
5.5,2.3,4,1.3,versicolor
|
||||||
|
6.5,2.8,4.6,1.5,versicolor
|
||||||
|
5.7,2.8,4.5,1.3,versicolor
|
||||||
|
6.3,3.3,4.7,1.6,versicolor
|
||||||
|
4.9,2.4,3.3,1,versicolor
|
||||||
|
6.6,2.9,4.6,1.3,versicolor
|
||||||
|
5.2,2.7,3.9,1.4,versicolor
|
||||||
|
5,2,3.5,1,versicolor
|
||||||
|
5.9,3,4.2,1.5,versicolor
|
||||||
|
6,2.2,4,1,versicolor
|
||||||
|
6.1,2.9,4.7,1.4,versicolor
|
||||||
|
5.6,2.9,3.6,1.3,versicolor
|
||||||
|
6.7,3.1,4.4,1.4,versicolor
|
||||||
|
5.6,3,4.5,1.5,versicolor
|
||||||
|
5.8,2.7,4.1,1,versicolor
|
||||||
|
6.2,2.2,4.5,1.5,versicolor
|
||||||
|
5.6,2.5,3.9,1.1,versicolor
|
||||||
|
5.9,3.2,4.8,1.8,versicolor
|
||||||
|
6.1,2.8,4,1.3,versicolor
|
||||||
|
6.3,2.5,4.9,1.5,versicolor
|
||||||
|
6.1,2.8,4.7,1.2,versicolor
|
||||||
|
6.4,2.9,4.3,1.3,versicolor
|
||||||
|
6.6,3,4.4,1.4,versicolor
|
||||||
|
6.8,2.8,4.8,1.4,versicolor
|
||||||
|
6.7,3,5,1.7,versicolor
|
||||||
|
6,2.9,4.5,1.5,versicolor
|
||||||
|
5.7,2.6,3.5,1,versicolor
|
||||||
|
5.5,2.4,3.8,1.1,versicolor
|
||||||
|
5.5,2.4,3.7,1,versicolor
|
||||||
|
5.8,2.7,3.9,1.2,versicolor
|
||||||
|
6,2.7,5.1,1.6,versicolor
|
||||||
|
5.4,3,4.5,1.5,versicolor
|
||||||
|
6,3.4,4.5,1.6,versicolor
|
||||||
|
6.7,3.1,4.7,1.5,versicolor
|
||||||
|
6.3,2.3,4.4,1.3,versicolor
|
||||||
|
5.6,3,4.1,1.3,versicolor
|
||||||
|
5.5,2.5,4,1.3,versicolor
|
||||||
|
5.5,2.6,4.4,1.2,versicolor
|
||||||
|
6.1,3,4.6,1.4,versicolor
|
||||||
|
5.8,2.6,4,1.2,versicolor
|
||||||
|
5,2.3,3.3,1,versicolor
|
||||||
|
5.6,2.7,4.2,1.3,versicolor
|
||||||
|
5.7,3,4.2,1.2,versicolor
|
||||||
|
5.7,2.9,4.2,1.3,versicolor
|
||||||
|
6.2,2.9,4.3,1.3,versicolor
|
||||||
|
5.1,2.5,3,1.1,versicolor
|
||||||
|
5.7,2.8,4.1,1.3,versicolor
|
||||||
|
6.3,3.3,6,2.5,virginica
|
||||||
|
5.8,2.7,5.1,1.9,virginica
|
||||||
|
7.1,3,5.9,2.1,virginica
|
||||||
|
6.3,2.9,5.6,1.8,virginica
|
||||||
|
6.5,3,5.8,2.2,virginica
|
||||||
|
7.6,3,6.6,2.1,virginica
|
||||||
|
4.9,2.5,4.5,1.7,virginica
|
||||||
|
7.3,2.9,6.3,1.8,virginica
|
||||||
|
6.7,2.5,5.8,1.8,virginica
|
||||||
|
7.2,3.6,6.1,2.5,virginica
|
||||||
|
6.5,3.2,5.1,2,virginica
|
||||||
|
6.4,2.7,5.3,1.9,virginica
|
||||||
|
6.8,3,5.5,2.1,virginica
|
||||||
|
5.7,2.5,5,2,virginica
|
||||||
|
5.8,2.8,5.1,2.4,virginica
|
||||||
|
6.4,3.2,5.3,2.3,virginica
|
||||||
|
6.5,3,5.5,1.8,virginica
|
||||||
|
7.7,3.8,6.7,2.2,virginica
|
||||||
|
7.7,2.6,6.9,2.3,virginica
|
||||||
|
6,2.2,5,1.5,virginica
|
||||||
|
6.9,3.2,5.7,2.3,virginica
|
||||||
|
5.6,2.8,4.9,2,virginica
|
||||||
|
7.7,2.8,6.7,2,virginica
|
||||||
|
6.3,2.7,4.9,1.8,virginica
|
||||||
|
6.7,3.3,5.7,2.1,virginica
|
||||||
|
7.2,3.2,6,1.8,virginica
|
||||||
|
6.2,2.8,4.8,1.8,virginica
|
||||||
|
6.1,3,4.9,1.8,virginica
|
||||||
|
6.4,2.8,5.6,2.1,virginica
|
||||||
|
7.2,3,5.8,1.6,virginica
|
||||||
|
7.4,2.8,6.1,1.9,virginica
|
||||||
|
7.9,3.8,6.4,2,virginica
|
||||||
|
6.4,2.8,5.6,2.2,virginica
|
||||||
|
6.3,2.8,5.1,1.5,virginica
|
||||||
|
6.1,2.6,5.6,1.4,virginica
|
||||||
|
7.7,3,6.1,2.3,virginica
|
||||||
|
6.3,3.4,5.6,2.4,virginica
|
||||||
|
6.4,3.1,5.5,1.8,virginica
|
||||||
|
6,3,4.8,1.8,virginica
|
||||||
|
6.9,3.1,5.4,2.1,virginica
|
||||||
|
6.7,3.1,5.6,2.4,virginica
|
||||||
|
6.9,3.1,5.1,2.3,virginica
|
||||||
|
5.8,2.7,5.1,1.9,virginica
|
||||||
|
6.8,3.2,5.9,2.3,virginica
|
||||||
|
6.7,3.3,5.7,2.5,virginica
|
||||||
|
6.7,3,5.2,2.3,virginica
|
||||||
|
6.3,2.5,5,1.9,virginica
|
||||||
|
6.5,3,5.2,2,virginica
|
||||||
|
6.2,3.4,5.4,2.3,virginica
|
||||||
|
5.9,3,5.1,1.8,virginica
|
|
BIN
content/data/matplotlib.png
Normal file
BIN
content/data/matplotlib.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
86
content/javascript.ipynb
Normal file
86
content/javascript.ipynb
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "javascript"
|
||||||
|
},
|
||||||
|
"file_extension": ".js",
|
||||||
|
"mimetype": "text/javascript",
|
||||||
|
"name": "javascript",
|
||||||
|
"nbconvert_exporter": "javascript",
|
||||||
|
"pygments_lexer": "javascript",
|
||||||
|
"version": "es2017"
|
||||||
|
},
|
||||||
|
"kernelspec": {
|
||||||
|
"name": "javascript",
|
||||||
|
"display_name": "JavaScript",
|
||||||
|
"language": "javascript"
|
||||||
|
},
|
||||||
|
"toc-showcode": true
|
||||||
|
},
|
||||||
|
"nbformat_minor": 4,
|
||||||
|
"nbformat": 4,
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"source": "# JavaScript in `JupyterLite`\n\n![](https://jupyterlite.readthedocs.io/en/latest/_static/kernelspecs/javascript.svg)",
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"source": "## Standard streams",
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"source": "console.log('hello world')",
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"source": "console.error('error')",
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"source": "## JavaScript specific constructs",
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"source": "const delay = 2000;\n\nsetTimeout(() => {\n console.log('done');\n}, delay);",
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"source": "var str = \"hello world\"\nstr.split('').forEach(c => {\n console.log(c)\n})",
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"source": "## Markdown cells",
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"source": "Lorenz system of differential equations\n\n$$\n\\begin{aligned}\n\\dot{x} & = \\sigma(y-x) \\\\\n\\dot{y} & = \\rho x - y - xz \\\\\n\\dot{z} & = -\\beta z + xy\n\\end{aligned}\n$$\n",
|
||||||
|
"metadata": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
150
content/p5.ipynb
Normal file
150
content/p5.ipynb
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
{
|
||||||
|
"metadata":{
|
||||||
|
"kernelspec":{
|
||||||
|
"name":"p5js",
|
||||||
|
"display_name":"p5.js",
|
||||||
|
"language":"javascript"
|
||||||
|
},
|
||||||
|
"language_info":{
|
||||||
|
"codemirror_mode":{
|
||||||
|
"name":"javascript"
|
||||||
|
},
|
||||||
|
"file_extension":".js",
|
||||||
|
"mimetype":"text/javascript",
|
||||||
|
"name":"p5js",
|
||||||
|
"nbconvert_exporter":"javascript",
|
||||||
|
"pygments_lexer":"javascript",
|
||||||
|
"version":"es2017"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat_minor":4,
|
||||||
|
"nbformat":4,
|
||||||
|
"cells":[
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"# p5 notebook\n\nA minimal Jupyter notebook UI for [p5.js](https://p5js.org) kernels.",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"First let's define a couple of variables:",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"var n = 4;\nvar speed = 1;",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"## The `setup` function\n\nThe usual p5 setup function, which creates the canvas.",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"function setup () {\n createCanvas(innerWidth, innerHeight);\n rectMode(CENTER);\n}",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"## The `draw` function\n\nFrom the [p5.js documentation](https://p5js.org/reference/#/p5/draw):\n\n> The `draw()` function continuously executes the lines of code contained inside its block until the program is stopped or `noLoop()` is called.",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"function draw() {\n background('#ddd');\n translate(innerWidth / 2, innerHeight / 2);\n for (let i = 0; i < n; i++) {\n push();\n rotate(frameCount * speed / 1000 * (i + 1));\n fill(i * 5, i * 100, i * 150);\n const s = 200 - i * 10;\n rect(0, 0, s, s);\n pop();\n }\n}",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"## Show the sketch\n\nNow let's show the sketch by using the `%show` magic:",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"%show",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"## Tweak the values\n\nWe can also tweak some values in real time:",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"speed = 3",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"n = 20",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"markdown",
|
||||||
|
"source":"We can also show the sketch a second time taking into account the new values:",
|
||||||
|
"metadata":{
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"%show",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
231
content/pyodide/altair.ipynb
Normal file
231
content/pyodide/altair.ipynb
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Altair in `JupyterLite`\n",
|
||||||
|
"\n",
|
||||||
|
"**Altair** is a declarative statistical visualization library for Python.\n",
|
||||||
|
"\n",
|
||||||
|
"Most of the examples below are from: https://altair-viz.github.io/gallery"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Import the dependencies:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q altair"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Simple Bar Chart"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import altair as alt\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"\n",
|
||||||
|
"source = pd.DataFrame({\n",
|
||||||
|
" 'a': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],\n",
|
||||||
|
" 'b': [28, 55, 43, 91, 81, 53, 19, 87, 52]\n",
|
||||||
|
"})\n",
|
||||||
|
"\n",
|
||||||
|
"alt.Chart(source).mark_bar().encode(\n",
|
||||||
|
" x='a',\n",
|
||||||
|
" y='b'\n",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Simple Heatmap"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import altair as alt\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"\n",
|
||||||
|
"# Compute x^2 + y^2 across a 2D grid\n",
|
||||||
|
"x, y = np.meshgrid(range(-5, 5), range(-5, 5))\n",
|
||||||
|
"z = x ** 2 + y ** 2\n",
|
||||||
|
"\n",
|
||||||
|
"# Convert this grid to columnar data expected by Altair\n",
|
||||||
|
"source = pd.DataFrame({'x': x.ravel(),\n",
|
||||||
|
" 'y': y.ravel(),\n",
|
||||||
|
" 'z': z.ravel()})\n",
|
||||||
|
"\n",
|
||||||
|
"alt.Chart(source).mark_rect().encode(\n",
|
||||||
|
" x='x:O',\n",
|
||||||
|
" y='y:O',\n",
|
||||||
|
" color='z:Q'\n",
|
||||||
|
")\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Install the Vega Dataset"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q vega_datasets"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Interactive Average"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import altair as alt\n",
|
||||||
|
"from vega_datasets import data\n",
|
||||||
|
"\n",
|
||||||
|
"source = data.seattle_weather()\n",
|
||||||
|
"brush = alt.selection(type='interval', encodings=['x'])\n",
|
||||||
|
"\n",
|
||||||
|
"bars = alt.Chart().mark_bar().encode(\n",
|
||||||
|
" x='month(date):O',\n",
|
||||||
|
" y='mean(precipitation):Q',\n",
|
||||||
|
" opacity=alt.condition(brush, alt.OpacityValue(1), alt.OpacityValue(0.7)),\n",
|
||||||
|
").add_selection(\n",
|
||||||
|
" brush\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"line = alt.Chart().mark_rule(color='firebrick').encode(\n",
|
||||||
|
" y='mean(precipitation):Q',\n",
|
||||||
|
" size=alt.SizeValue(3)\n",
|
||||||
|
").transform_filter(\n",
|
||||||
|
" brush\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"alt.layer(bars, line, data=source)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Locations of US Airports"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import altair as alt\n",
|
||||||
|
"from vega_datasets import data\n",
|
||||||
|
"\n",
|
||||||
|
"airports = data.airports.url\n",
|
||||||
|
"states = alt.topo_feature(data.us_10m.url, feature='states')\n",
|
||||||
|
"\n",
|
||||||
|
"# US states background\n",
|
||||||
|
"background = alt.Chart(states).mark_geoshape(\n",
|
||||||
|
" fill='lightgray',\n",
|
||||||
|
" stroke='white'\n",
|
||||||
|
").properties(\n",
|
||||||
|
" width=500,\n",
|
||||||
|
" height=300\n",
|
||||||
|
").project('albersUsa')\n",
|
||||||
|
"\n",
|
||||||
|
"# airport positions on background\n",
|
||||||
|
"points = alt.Chart(airports).transform_aggregate(\n",
|
||||||
|
" latitude='mean(latitude)',\n",
|
||||||
|
" longitude='mean(longitude)',\n",
|
||||||
|
" count='count()',\n",
|
||||||
|
" groupby=['state']\n",
|
||||||
|
").mark_circle().encode(\n",
|
||||||
|
" longitude='longitude:Q',\n",
|
||||||
|
" latitude='latitude:Q',\n",
|
||||||
|
" size=alt.Size('count:Q', title='Number of Airports'),\n",
|
||||||
|
" color=alt.value('steelblue'),\n",
|
||||||
|
" tooltip=['state:N','count:Q']\n",
|
||||||
|
").properties(\n",
|
||||||
|
" title='Number of airports in US'\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"background + points\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
154
content/pyodide/folium.ipynb
Normal file
154
content/pyodide/folium.ipynb
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"# `folium` Interactive Map Demo\n",
|
||||||
|
"\n",
|
||||||
|
"Simple demonstration of rendering a map in a `jupyterlite` notebook.\n",
|
||||||
|
"\n",
|
||||||
|
"Note that the `folium` package has several dependencies which themselves may have dependencies.\n",
|
||||||
|
"\n",
|
||||||
|
"The following code fragement, run in a fresh Python enviroment into which `folium` has already been installed, identifies the packages that are loaded in when `folium` is loaded:\n",
|
||||||
|
"\n",
|
||||||
|
"```python\n",
|
||||||
|
"#https://stackoverflow.com/a/40381601/454773\n",
|
||||||
|
"import sys\n",
|
||||||
|
"before = [str(m) for m in sys.modules]\n",
|
||||||
|
"import folium\n",
|
||||||
|
"after = [str(m) for m in sys.modules]\n",
|
||||||
|
"set([m.split('.')[0] for m in after if not m in before and not m.startswith('_')])\n",
|
||||||
|
"```\n",
|
||||||
|
"\n",
|
||||||
|
"The loaded packages are:\n",
|
||||||
|
"\n",
|
||||||
|
"```\n",
|
||||||
|
"{'branca',\n",
|
||||||
|
" 'certifi',\n",
|
||||||
|
" 'chardet',\n",
|
||||||
|
" 'cmath',\n",
|
||||||
|
" 'csv',\n",
|
||||||
|
" 'dateutil',\n",
|
||||||
|
" 'encodings',\n",
|
||||||
|
" 'folium',\n",
|
||||||
|
" 'gzip',\n",
|
||||||
|
" 'http',\n",
|
||||||
|
" 'idna',\n",
|
||||||
|
" 'importlib',\n",
|
||||||
|
" 'jinja2',\n",
|
||||||
|
" 'markupsafe',\n",
|
||||||
|
" 'mmap',\n",
|
||||||
|
" 'numpy',\n",
|
||||||
|
" 'pandas',\n",
|
||||||
|
" 'pkg_resources',\n",
|
||||||
|
" 'pytz',\n",
|
||||||
|
" 'requests',\n",
|
||||||
|
" 'secrets',\n",
|
||||||
|
" 'stringprep',\n",
|
||||||
|
" 'urllib3',\n",
|
||||||
|
" 'zipfile'}\n",
|
||||||
|
" ```\n",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"The following packages seem to need installing in order load `folium`, along with folium itself:\n",
|
||||||
|
"\n",
|
||||||
|
"```\n",
|
||||||
|
"chardet, certifi, idna, branca, urllib3, Jinja2, requests, Markupsafe\n",
|
||||||
|
"```\n",
|
||||||
|
"\n",
|
||||||
|
"Universal wheels, with filenames of the form `PACKAGE-VERSION-py2.py3-none-any.whl` appearing in the *Download files* area of a PyPi package page ([example](https://pypi.org/project/requests/#files)] are required in order to install the package.\n",
|
||||||
|
"\n",
|
||||||
|
"One required package, [`Markupsafe`](https://pypi.org/project/Markupsafe/#files)) *did not* have a universal wheel available, so a wheel was manually built elsewhere (by hacking the [`setup.py` file](https://github.com/pallets/markupsafe/blob/main/setup.py) to force it to build the wheel in a platform and speedup free way) and pushed to a downloadable location in an [*ad hoc* wheelhouse](https://opencomputinglab.github.io/vce-wheelhouse/)."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Install folium requirements\n",
|
||||||
|
"%pip install -q folium"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Demo of `folium` Map\n",
|
||||||
|
"\n",
|
||||||
|
"Load in the `folium` package:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import folium"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"And render a demo map:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"m = folium.Map(location=[50.693848, -1.304734], zoom_start=11)\n",
|
||||||
|
"m"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4,
|
||||||
|
"toc-showcode": false
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
268
content/pyodide/interactive-widgets.ipynb
Normal file
268
content/pyodide/interactive-widgets.ipynb
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "9ca234f7-84b7-4107-9bcd-74f5a4ffd07d",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# `ipywidgets` Interactive Demo\n",
|
||||||
|
"\n",
|
||||||
|
"Simple demonstration of rendering Interactive widgets in a `jupyterlite` notebook.\n",
|
||||||
|
"\n",
|
||||||
|
"`ipywidgets` can be installed in this deployment (it provides the @jupyter-widgets/jupyterlab-manager federated extension), but you will need to make your own deployment to have access to other interactive widgets libraries."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d62fba6e",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q ipywidgets"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "3bab23f8-de91-43c9-9cec-84f4924425fc",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from ipywidgets import IntSlider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "a15c5acb-ee72-4005-8761-5693db853f22",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider = IntSlider()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "8ba89682-e0d7-4bd2-961a-f9956850fd5a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "50510ade-668f-4477-8cb2-41574609ac73",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "7bac1ed8-8c77-426b-a781-1c1a6cfad829",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider.value"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "976a70a0-e99d-4c20-b005-f59bbba10f85",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider.value = 5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "3134c76e-cffb-4701-8230-e6c4bfbbfdb9",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from ipywidgets import IntText, link"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "f7b3fe0a-5695-4ef2-a573-40785e68fbae",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"text = IntText()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "5e2fd50e-19e0-4e20-a1f7-ad65400ec636",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"text"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "bb3bedce-7311-48c0-aeab-8fe3aa554b92",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"link((slider, 'value'), (text, 'value'));"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "71b68c3e-184e-4320-9513-d0bc72800a85",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# `bqplot` Interactive Demo\n",
|
||||||
|
"\n",
|
||||||
|
"Plotting in JupyterLite\n",
|
||||||
|
"\n",
|
||||||
|
"`bqplot` can be installed in this deployment (it provides the bqplot federated extension), but you will need to make your own deployment to have access to other interactive widgets libraries."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "119eb9a3-ac98-42c3-98d4-1ac460eb75d3",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q bqplot"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "23b32857-2958-4083-b16a-ac26cd2408d4",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from bqplot import *\n",
|
||||||
|
"\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"\n",
|
||||||
|
"np.random.seed(0)\n",
|
||||||
|
"\n",
|
||||||
|
"n = 100\n",
|
||||||
|
"\n",
|
||||||
|
"x = list(range(n))\n",
|
||||||
|
"y = np.cumsum(np.random.randn(n)) + 100.\n",
|
||||||
|
"\n",
|
||||||
|
"sc_x = LinearScale()\n",
|
||||||
|
"sc_y = LinearScale()\n",
|
||||||
|
"\n",
|
||||||
|
"lines = Lines(\n",
|
||||||
|
" x=x, y=y,\n",
|
||||||
|
" scales={'x': sc_x, 'y': sc_y}\n",
|
||||||
|
")\n",
|
||||||
|
"ax_x = Axis(scale=sc_x, label='Index')\n",
|
||||||
|
"ax_y = Axis(scale=sc_y, orientation='vertical', label='lines')\n",
|
||||||
|
"\n",
|
||||||
|
"Figure(marks=[lines], axes=[ax_x, ax_y], title='Lines')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "ddb6b44e-06a0-4049-a79d-33ffc90d5a03",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"lines.colors = ['green']"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "e367e7fb-b403-41aa-9629-224827ec3005",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"lines.fill = 'bottom'"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d4a167f3-07c4-4880-92f5-7fcdea0c61c6",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"lines.marker = 'circle'"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "1d1342f7-ec08-4f53-84dc-d712226d9e46",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"n = 100\n",
|
||||||
|
"\n",
|
||||||
|
"x = list(range(n))\n",
|
||||||
|
"y = np.cumsum(np.random.randn(n))\n",
|
||||||
|
"\n",
|
||||||
|
"sc_x = LinearScale()\n",
|
||||||
|
"sc_y = LinearScale()\n",
|
||||||
|
"\n",
|
||||||
|
"bars = Bars(\n",
|
||||||
|
" x=x, y=y,\n",
|
||||||
|
" scales={'x': sc_x, 'y': sc_y}\n",
|
||||||
|
")\n",
|
||||||
|
"ax_x = Axis(scale=sc_x, label='Index')\n",
|
||||||
|
"ax_y = Axis(scale=sc_y, orientation='vertical', label='bars')\n",
|
||||||
|
"\n",
|
||||||
|
"Figure(marks=[bars], axes=[ax_x, ax_y], title='Bars', animation_duration=1000)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "f86bbcfb-5b02-4700-b8d6-f90068893b55",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"bars.y = np.cumsum(np.random.randn(n))"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4,
|
||||||
|
"toc-showcode": false
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
178
content/pyodide/ipycanvas.ipynb
Normal file
178
content/pyodide/ipycanvas.ipynb
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# ipycanvas: John Conway's Game Of Life"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Some of the following code is adapted from https://jakevdp.github.io/blog/2013/08/07/conways-game-of-life/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q ipycanvas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import asyncio\n",
|
||||||
|
"\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"\n",
|
||||||
|
"from ipycanvas import RoughCanvas, hold_canvas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def life_step(x):\n",
|
||||||
|
" \"\"\"Game of life step\"\"\"\n",
|
||||||
|
" nbrs_count = sum(np.roll(np.roll(x, i, 0), j, 1)\n",
|
||||||
|
" for i in (-1, 0, 1) for j in (-1, 0, 1)\n",
|
||||||
|
" if (i != 0 or j != 0))\n",
|
||||||
|
" return (nbrs_count == 3) | (x & (nbrs_count == 2))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def draw(x, canvas, color='black'):\n",
|
||||||
|
" with hold_canvas(canvas):\n",
|
||||||
|
" canvas.clear()\n",
|
||||||
|
" canvas.fill_style = '#FFF0C9'\n",
|
||||||
|
" canvas.rough_fill_style = 'solid'\n",
|
||||||
|
" canvas.fill_rect(-10, -10, canvas.width + 10, canvas.height + 10)\n",
|
||||||
|
" canvas.rough_fill_style = 'cross-hatch'\n",
|
||||||
|
"\n",
|
||||||
|
" canvas.fill_style = color\n",
|
||||||
|
" canvas.stroke_style = color\n",
|
||||||
|
"\n",
|
||||||
|
" living_cells = np.where(x)\n",
|
||||||
|
" \n",
|
||||||
|
" rects_x = living_cells[1] * n_pixels\n",
|
||||||
|
" rects_y = living_cells[0] * n_pixels\n",
|
||||||
|
"\n",
|
||||||
|
" canvas.fill_rects(rects_x, rects_y, n_pixels)\n",
|
||||||
|
" canvas.stroke_rects(rects_x, rects_y, n_pixels)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"glider_gun =\\\n",
|
||||||
|
"[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],\n",
|
||||||
|
" [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0],\n",
|
||||||
|
" [0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],\n",
|
||||||
|
" [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],\n",
|
||||||
|
" [1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\n",
|
||||||
|
" [1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0],\n",
|
||||||
|
" [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],\n",
|
||||||
|
" [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\n",
|
||||||
|
" [0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]\n",
|
||||||
|
"\n",
|
||||||
|
"x = np.zeros((50, 70), dtype=bool)\n",
|
||||||
|
"x[1:10,1:37] = glider_gun"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"n_pixels = 15\n",
|
||||||
|
"\n",
|
||||||
|
"canvas = RoughCanvas(width=x.shape[1]*n_pixels, height=x.shape[0]*n_pixels)\n",
|
||||||
|
"canvas.fill_style = '#FFF0C9'\n",
|
||||||
|
"canvas.rough_fill_style = 'solid'\n",
|
||||||
|
"canvas.fill_rect(0, 0, canvas.width, canvas.height)\n",
|
||||||
|
"\n",
|
||||||
|
"canvas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"draw(x, canvas, '#5770B3')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"for _ in range(300):\n",
|
||||||
|
" x = life_step(x)\n",
|
||||||
|
" draw(x, canvas, '#5770B3')\n",
|
||||||
|
"\n",
|
||||||
|
" await asyncio.sleep(0.1)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4,
|
||||||
|
"toc-showcode": false
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
259
content/pyodide/ipyleaflet.ipynb
Normal file
259
content/pyodide/ipyleaflet.ipynb
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q bqplot ipyleaflet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import os\n",
|
||||||
|
"from urllib.request import urlopen\n",
|
||||||
|
"import json\n",
|
||||||
|
"from datetime import datetime\n",
|
||||||
|
"\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"\n",
|
||||||
|
"from js import fetch\n",
|
||||||
|
"\n",
|
||||||
|
"from ipywidgets import Dropdown\n",
|
||||||
|
"\n",
|
||||||
|
"from bqplot import Lines, Figure, LinearScale, DateScale, Axis\n",
|
||||||
|
"\n",
|
||||||
|
"from ipyleaflet import Map, GeoJSON, WidgetControl"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"URL = \"https://raw.githubusercontent.com/jupyter-widgets/ipyleaflet/master/examples/nations.json\"\n",
|
||||||
|
"\n",
|
||||||
|
"res = await fetch(URL)\n",
|
||||||
|
"text = await res.text()\n",
|
||||||
|
"\n",
|
||||||
|
"data = pd.read_json(text)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def clean_data(data):\n",
|
||||||
|
" for column in ['income', 'lifeExpectancy', 'population']:\n",
|
||||||
|
" data = data.drop(data[data[column].apply(len) <= 4].index)\n",
|
||||||
|
" return data\n",
|
||||||
|
"\n",
|
||||||
|
"def extrap_interp(data):\n",
|
||||||
|
" data = np.array(data)\n",
|
||||||
|
" x_range = np.arange(1800, 2009, 1.)\n",
|
||||||
|
" y_range = np.interp(x_range, data[:, 0], data[:, 1])\n",
|
||||||
|
" return y_range\n",
|
||||||
|
"\n",
|
||||||
|
"def extrap_data(data):\n",
|
||||||
|
" for column in ['income', 'lifeExpectancy', 'population']:\n",
|
||||||
|
" data[column] = data[column].apply(extrap_interp)\n",
|
||||||
|
" return data"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"data = clean_data(data)\n",
|
||||||
|
"data = extrap_data(data)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"data"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"date_start = datetime(1800, 12, 31)\n",
|
||||||
|
"date_end = datetime(2009, 12, 31)\n",
|
||||||
|
"\n",
|
||||||
|
"date_scale = DateScale(min=date_start, max=date_end)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"date_data = pd.date_range(start=date_start, end=date_end, freq='A', normalize=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"country_name = 'Angola'\n",
|
||||||
|
"data_name = 'income'\n",
|
||||||
|
"\n",
|
||||||
|
"x_data = data[data.name == country_name][data_name].values[0]"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"x_scale = LinearScale()\n",
|
||||||
|
"\n",
|
||||||
|
"lines = Lines(x=date_data, y=x_data, scales={'x': date_scale, 'y': x_scale})\n",
|
||||||
|
"\n",
|
||||||
|
"ax_x = Axis(label='Year', scale=date_scale, num_ticks=10, tick_format='%Y')\n",
|
||||||
|
"ax_y = Axis(label=data_name.capitalize(), scale=x_scale, orientation='vertical', side='left')\n",
|
||||||
|
"\n",
|
||||||
|
"figure = Figure(axes=[ax_x, ax_y], title=country_name, marks=[lines], animation_duration=500,\n",
|
||||||
|
" layout={'max_height': '250px', 'max_width': '400px'})"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def update_figure(country_name, data_name):\n",
|
||||||
|
" try:\n",
|
||||||
|
" lines.y = data[data.name == country_name][data_name].values[0]\n",
|
||||||
|
" ax_y.label = data_name.capitalize()\n",
|
||||||
|
" figure.title = country_name\n",
|
||||||
|
" except IndexError:\n",
|
||||||
|
" pass"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"URL = \"https://raw.githubusercontent.com/jupyter-widgets/ipyleaflet/master/examples/countries.geo.json\"\n",
|
||||||
|
"\n",
|
||||||
|
"res = await fetch(URL)\n",
|
||||||
|
"text = await res.text()\n",
|
||||||
|
"\n",
|
||||||
|
"countries = json.loads(text)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"m = Map(zoom=3)\n",
|
||||||
|
"\n",
|
||||||
|
"geo = GeoJSON(data=countries, style={'fillColor': 'white', 'weight': 0.5}, hover_style={'fillColor': '#1f77b4'}, name='Countries')\n",
|
||||||
|
"m.add_layer(geo)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"widget_control1 = WidgetControl(widget=figure, position='bottomright')\n",
|
||||||
|
"\n",
|
||||||
|
"m.add_control(widget_control1)\n",
|
||||||
|
"\n",
|
||||||
|
"def on_hover(event, feature, **kwargs):\n",
|
||||||
|
" global country_name\n",
|
||||||
|
"\n",
|
||||||
|
" country_name = feature['properties']['name']\n",
|
||||||
|
" update_figure(country_name, data_name)\n",
|
||||||
|
"\n",
|
||||||
|
"geo.on_hover(on_hover)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"dropdown = Dropdown(\n",
|
||||||
|
" options=['income', 'population', 'lifeExpectancy'],\n",
|
||||||
|
" value=data_name,\n",
|
||||||
|
" description='Plotting:'\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"def on_click(change):\n",
|
||||||
|
" global data_name\n",
|
||||||
|
"\n",
|
||||||
|
" data_name = change['new']\n",
|
||||||
|
" update_figure(country_name, data_name)\n",
|
||||||
|
"\n",
|
||||||
|
"dropdown.observe(on_click, 'value')\n",
|
||||||
|
"\n",
|
||||||
|
"widget_control2 = WidgetControl(widget=dropdown, position='bottomleft')\n",
|
||||||
|
"\n",
|
||||||
|
"m.add_control(widget_control2)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"m"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4,
|
||||||
|
"toc-showcode": false
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
113
content/pyodide/matplotlib.ipynb
Normal file
113
content/pyodide/matplotlib.ipynb
Normal file
File diff suppressed because one or more lines are too long
158
content/pyodide/plotly.ipynb
Normal file
158
content/pyodide/plotly.ipynb
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Plotly in JupyterLite\n",
|
||||||
|
"\n",
|
||||||
|
"`plotly.py` is an interactive, open-source, and browser-based graphing library for Python: https://plotly.com/python/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pip install -q nbformat plotly"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"## Basic Figure"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import plotly.graph_objects as go\n",
|
||||||
|
"fig = go.Figure()\n",
|
||||||
|
"fig.add_trace(go.Scatter(y=[2, 1, 4, 3]))\n",
|
||||||
|
"fig.add_trace(go.Bar(y=[1, 4, 3, 2]))\n",
|
||||||
|
"fig.update_layout(title = 'Hello Figure')\n",
|
||||||
|
"fig.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"## Basic Table with a Pandas DataFrame"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import plotly.graph_objects as go\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"\n",
|
||||||
|
"from js import fetch\n",
|
||||||
|
"\n",
|
||||||
|
"URL = \"https://raw.githubusercontent.com/plotly/datasets/master/2014_usa_states.csv\"\n",
|
||||||
|
"\n",
|
||||||
|
"res = await fetch(URL)\n",
|
||||||
|
"text = await res.text()\n",
|
||||||
|
"\n",
|
||||||
|
"filename = 'data.csv'\n",
|
||||||
|
"\n",
|
||||||
|
"with open(filename, 'w') as f:\n",
|
||||||
|
" f.write(text)\n",
|
||||||
|
"\n",
|
||||||
|
"df = pd.read_csv(filename)\n",
|
||||||
|
"\n",
|
||||||
|
"fig = go.Figure(data=[go.Table(\n",
|
||||||
|
" header=dict(values=list(df.columns),\n",
|
||||||
|
" fill_color='paleturquoise',\n",
|
||||||
|
" align='left'),\n",
|
||||||
|
" cells=dict(values=[df.Rank, df.State, df.Postal, df.Population],\n",
|
||||||
|
" fill_color='lavender',\n",
|
||||||
|
" align='left'))\n",
|
||||||
|
"])\n",
|
||||||
|
"\n",
|
||||||
|
"fig.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Quiver Plot with Points"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import plotly.figure_factory as ff\n",
|
||||||
|
"import plotly.graph_objects as go\n",
|
||||||
|
"\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"\n",
|
||||||
|
"x,y = np.meshgrid(np.arange(-2, 2, .2),\n",
|
||||||
|
" np.arange(-2, 2, .25))\n",
|
||||||
|
"z = x*np.exp(-x**2 - y**2)\n",
|
||||||
|
"v, u = np.gradient(z, .2, .2)\n",
|
||||||
|
"\n",
|
||||||
|
"# Create quiver figure\n",
|
||||||
|
"fig = ff.create_quiver(x, y, u, v,\n",
|
||||||
|
" scale=.25,\n",
|
||||||
|
" arrow_scale=.4,\n",
|
||||||
|
" name='quiver',\n",
|
||||||
|
" line_width=1)\n",
|
||||||
|
"\n",
|
||||||
|
"# Add points to figure\n",
|
||||||
|
"fig.add_trace(go.Scatter(x=[-.7, .75], y=[0,0],\n",
|
||||||
|
" mode='markers',\n",
|
||||||
|
" marker_size=12,\n",
|
||||||
|
" name='points'))\n",
|
||||||
|
"\n",
|
||||||
|
"fig.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4,
|
||||||
|
"toc-showcode": false
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
649
content/pyodide/pyb2d/0_tutorial.ipynb
Normal file
649
content/pyodide/pyb2d/0_tutorial.ipynb
Normal file
|
@ -0,0 +1,649 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "b07a3b47-2262-4135-a1d2-52e8392b44eb",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "49c3f9ea-23ce-4c5c-b3fe-44f1cecadf20",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"pyb2d is imported as b2d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "dff93359-2c68-467a-9239-478a0e550a4b",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import b2d\n",
|
||||||
|
"# import pyb2d_jupyterlite_backend\n",
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import matplotlib.pylab as plt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "bc977c4e-75ee-4349-9408-650c3dcd01e0",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Tutorial 0: A free falling body\n",
|
||||||
|
"The first step with Box2D is the creation of the world. The world is parametrized by a gravity vector."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "4ff914a6-eb18-45a1-b1ed-e8ad7ab0d298",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# the world\n",
|
||||||
|
"gravity = (0, -10)\n",
|
||||||
|
"world = b2d.World(gravity)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "3afdbb2a-e694-4779-b95e-73a5b38d34b6",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Create a circle-shaped body"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "99837a63-4628-483c-8f2d-cc4aec9cb1d5",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# the body def\n",
|
||||||
|
"body_def = b2d.BodyDef()\n",
|
||||||
|
"body_def.type = b2d.BodyType.dynamic\n",
|
||||||
|
"body_def.position = (0, 0)\n",
|
||||||
|
"\n",
|
||||||
|
"# the body\n",
|
||||||
|
"body = world.create_body(body_def)\n",
|
||||||
|
"\n",
|
||||||
|
"# shape\n",
|
||||||
|
"circle_shape = b2d.CircleShape()\n",
|
||||||
|
"circle_shape.radius = 1.0\n",
|
||||||
|
"\n",
|
||||||
|
"# the fixture\n",
|
||||||
|
"fixture_def = b2d.FixtureDef()\n",
|
||||||
|
"fixture_def.shape = circle_shape\n",
|
||||||
|
"fixture_def.density = 1.0\n",
|
||||||
|
"\n",
|
||||||
|
"# create and add the fixture to the body\n",
|
||||||
|
"fixture = body.create_fixture(fixture_def)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "bf9758a6-fb6e-4f9c-b15f-783f9488cf7e",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We can now have a look at the world: We render the world st. each meter in the Box2D world will be 100 pixels in the image:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "8b433892-3c82-43be-a085-eda3e4279b2c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# from b2d.plot import render_world\n",
|
||||||
|
"b2d.plot.plot_world(world, ppm=100)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "5e1db1f1-6e47-454c-9ea9-86262d7da309",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Lets run the world for a total of 5 seconds. \n",
|
||||||
|
"Usually one wants to run the world at a certain frame rate.\n",
|
||||||
|
"With the frame rate and the total time we can compute the delta for each iteration and how many steps we need"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "41a232a9-a3c5-425d-9aed-d3adb90d6314",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"t = 5\n",
|
||||||
|
"fps = 40\n",
|
||||||
|
"dt = 1.0 / fps\n",
|
||||||
|
"n_steps = int(t / dt + 0.5)\n",
|
||||||
|
"print(f\"t={t} fps={fps} dt={dt} n_steps={n_steps}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "4d458acb-6d5c-47ba-bcbf-d15ea2cf2537",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"in each step we query the bodies position and velocity and store then for later plotting"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "4e042c7b-07a7-445f-ba04-e38173b46c0f",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"positions = np.zeros([n_steps, 2])\n",
|
||||||
|
"velocites = np.zeros([n_steps, 2])\n",
|
||||||
|
"timepoints = np.zeros([n_steps])\n",
|
||||||
|
"\n",
|
||||||
|
"t_elapsed = 0.0\n",
|
||||||
|
"for i in range(n_steps):\n",
|
||||||
|
"\n",
|
||||||
|
" # get the bodies center of mass\n",
|
||||||
|
" positions[i, :] = body.world_center\n",
|
||||||
|
"\n",
|
||||||
|
" # get the bodies velocity\n",
|
||||||
|
" velocites[i, :] = body.linear_velocity\n",
|
||||||
|
"\n",
|
||||||
|
" timepoints[i] = t_elapsed\n",
|
||||||
|
"\n",
|
||||||
|
" world.step(time_step=dt, velocity_iterations=1, position_iterations=1)\n",
|
||||||
|
" t_elapsed += dt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "0ec7d66c-c979-40fa-8af3-9e99873ec105",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"plot the y-position against the time. We can see that the body is falling down in an accelerating way:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "434cb907-1b76-414e-bb5e-6ea32dd1f829",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"plt.plot(timepoints, positions[:, 1])\n",
|
||||||
|
"plt.ylabel('y-poistion [meter]')\n",
|
||||||
|
"plt.xlabel('t [sec]')\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "b7f58954-4ea1-49f9-b0b0-7df38336860d",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"as expected the x position is not changing since the gravity vector is non-zero only in the x direction"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "39573eed-e6c8-45bf-8e35-4251b660ce3f",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"plt.plot(timepoints, positions[:, 0])\n",
|
||||||
|
"plt.ylabel('x-poistion [meter]')\n",
|
||||||
|
"plt.xlabel('t [sec]')\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "cdb98dc5-3bc8-4933-91a0-a1db3afb9c34",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Tutorial 1: A falling body in a box, more pythonic\n",
|
||||||
|
"Create a world, but in a more pythonic way, and animate the world"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d58c2639-21da-490b-8dcd-205962f63dfc",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# the world\n",
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"\n",
|
||||||
|
"# create the dynamic body\n",
|
||||||
|
"body = world.create_dynamic_body(\n",
|
||||||
|
" position=(5, 5),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=1), density=1, restitution=0.75),\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"# create a box\n",
|
||||||
|
"box_shape = b2d.ChainShape()\n",
|
||||||
|
"box_shape.create_loop([(0, 0), (0, 10),(10,10),(10, 0)])\n",
|
||||||
|
"box = world.create_static_body(\n",
|
||||||
|
" position=(0, 0), fixtures=b2d.fixture_def(shape=box_shape, friction=0)\n",
|
||||||
|
")\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=10)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "10dbb85a-84b0-4820-8fb3-6108d9c0fe00",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"note that when we animate that world again, the body has already been fallen"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "c919702c-7c62-4d87-bf1f-df5027d72a83",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=2)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "7322e9c5-8608-4375-81ed-766cbb2af927",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Tutorial 2: Interactive worlds\n",
|
||||||
|
"While animating the world already is already nice, interacting with the world is even better.\n",
|
||||||
|
"pyb2d has a framwork to interact with the world for multiple backends.\n",
|
||||||
|
"This framework is called `TestbedBase` since you can \"test\" your world in an interactive way"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "97cddd47-5a88-4cae-8543-cfcdf658255a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"\n",
|
||||||
|
"class InteractiveExample(TestbedBase):\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(InteractiveExample, self).__init__(settings=settings)\n",
|
||||||
|
" # create two balls\n",
|
||||||
|
" body = self.world.create_dynamic_body(position=(5, 5),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=1), density=1, restitution=0.5),\n",
|
||||||
|
" )\n",
|
||||||
|
" body = self.world.create_dynamic_body(position=(8, 5),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=1), density=1, restitution=0.8),\n",
|
||||||
|
" )\n",
|
||||||
|
" # create a box\n",
|
||||||
|
" box_shape = b2d.ChainShape()\n",
|
||||||
|
" box_shape.create_loop([(0, 0), (0, 10),(10,10),(10, 0)])\n",
|
||||||
|
" box = self.world.create_static_body(\n",
|
||||||
|
" position=(0, 0), fixtures=b2d.fixture_def(shape=box_shape, friction=0)\n",
|
||||||
|
" )\n",
|
||||||
|
" \n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [300,300]\n",
|
||||||
|
"b2d.testbed.run(InteractiveExample, backend=JupyterAsyncGui, gui_settings=s);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "64bf55d1-4117-4af0-8f1f-65de33751743",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"# Tutorial 3: Joints"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "07147cab-23be-4406-85f7-4b3d174e3954",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"## Tutorial 3.1: Prismatic Joint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "9a2d178d-33d7-4c51-b0ff-f66c98cac673",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"anchor_body = world.create_static_body(position=(0, 0))\n",
|
||||||
|
"b = world.create_dynamic_body(\n",
|
||||||
|
" position=(10, 10),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[2, 0.5]), density=1),\n",
|
||||||
|
" linear_damping=0.0,\n",
|
||||||
|
" angular_damping=0.0,\n",
|
||||||
|
")\n",
|
||||||
|
"world.create_prismatic_joint(anchor_body, b, local_axis_a=(1, 1))\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=3, bounding_box=((0,0),(10,10)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "07971d69-b2ef-4d74-8c1c-48f38dcc708c",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"## Tutorial 3.2: Pully Joint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "39b7fef2-4b4b-4904-9899-1a34f1039693",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"a = world.create_dynamic_body(\n",
|
||||||
|
" position=(-5, 0),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[2, 0.8]), density=1),\n",
|
||||||
|
" linear_damping=0.0,\n",
|
||||||
|
" angular_damping=0.0,\n",
|
||||||
|
")\n",
|
||||||
|
"b = world.create_dynamic_body(\n",
|
||||||
|
" position=(5, 0),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[2, 0.5]), density=1),\n",
|
||||||
|
" linear_damping=0.0,\n",
|
||||||
|
" angular_damping=0.0,\n",
|
||||||
|
")\n",
|
||||||
|
"world.create_pully_joint(\n",
|
||||||
|
" a,\n",
|
||||||
|
" b,\n",
|
||||||
|
" length_a=10,\n",
|
||||||
|
" length_b=10,\n",
|
||||||
|
" ground_anchor_a=(-5, 10),\n",
|
||||||
|
" ground_anchor_b=(5, 10),\n",
|
||||||
|
" local_anchor_a=(0, 0),\n",
|
||||||
|
" local_anchor_b=(0, 0),\n",
|
||||||
|
")\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=5, bounding_box=((-10,-12),(10,12)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "7e8fb17d-1dda-45cb-98df-6b98be5b4e6c",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Tutorial 3.3: Revolute Joint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "a2686e5f-3fa2-412d-8a40-2e9a67123d43",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"bodies = []\n",
|
||||||
|
"b = world.create_static_body(position=(0, 15))\n",
|
||||||
|
"bodies.append(b)\n",
|
||||||
|
"for i in range(5):\n",
|
||||||
|
" b = world.create_dynamic_body(\n",
|
||||||
|
" position=(i * 4 + 2, 15),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[2, 0.5]), density=1),\n",
|
||||||
|
" linear_damping=0.0,\n",
|
||||||
|
" angular_damping=0.0,\n",
|
||||||
|
" )\n",
|
||||||
|
" bodies.append(b)\n",
|
||||||
|
"world.create_revolute_joint(\n",
|
||||||
|
" bodies[0], bodies[1], local_anchor_a=(0, 0), local_anchor_b=(-2, 0.0)\n",
|
||||||
|
")\n",
|
||||||
|
"for i in range(1, len(bodies) - 1):\n",
|
||||||
|
" a = bodies[i]\n",
|
||||||
|
" b = bodies[i + 1]\n",
|
||||||
|
" world.create_revolute_joint(a, b, local_anchor_a=(2, 0.0), local_anchor_b=(-2, 0.0))\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=5, bounding_box=((-20,-10),(20,20)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "9caa18f0-4eb7-4e72-8445-8f6d096d9465",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"## Tutorial 3.4: Weld Joint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "3d74fb2f-7da5-4ad7-8f21-fba1f97acee2",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# the world\n",
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"bodies = []\n",
|
||||||
|
"\n",
|
||||||
|
"# create a static body as anchor\n",
|
||||||
|
"b = world.create_static_body(\n",
|
||||||
|
" position=(0, 4), fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[0.3, 0.5]))\n",
|
||||||
|
")\n",
|
||||||
|
"bodies.append(b)\n",
|
||||||
|
"\n",
|
||||||
|
"for i in range(4):\n",
|
||||||
|
" b = world.create_dynamic_body(\n",
|
||||||
|
" position=(i + 1.0, 4),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[0.3, 0.5]), density=0.1),\n",
|
||||||
|
" linear_damping=2.5,\n",
|
||||||
|
" angular_damping=2.5,\n",
|
||||||
|
" )\n",
|
||||||
|
" bodies.append(b)\n",
|
||||||
|
"\n",
|
||||||
|
"for i in range(len(bodies) - 1):\n",
|
||||||
|
" a = bodies[i]\n",
|
||||||
|
" b = bodies[i + 1]\n",
|
||||||
|
" world.create_weld_joint(\n",
|
||||||
|
" a,\n",
|
||||||
|
" b,\n",
|
||||||
|
" local_anchor_a=(0.5, 0.5),\n",
|
||||||
|
" local_anchor_b=(-0.5, 0.5),\n",
|
||||||
|
" damping=0.1,\n",
|
||||||
|
" reference_angle=0,\n",
|
||||||
|
" stiffness=20,\n",
|
||||||
|
" )\n",
|
||||||
|
" world.create_weld_joint(\n",
|
||||||
|
" a,\n",
|
||||||
|
" b,\n",
|
||||||
|
" local_anchor_a=(0.5, -0.5),\n",
|
||||||
|
" local_anchor_b=(-0.5, -0.5),\n",
|
||||||
|
" damping=0.1,\n",
|
||||||
|
" reference_angle=0,\n",
|
||||||
|
" stiffness=20,\n",
|
||||||
|
" )\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=5, bounding_box=((0,-5),(5,5)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "7373461e-d1fa-4ad9-aeaa-048287839fd9",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Tutorial 3.5: Wheel Joint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "1eb711e0-ae53-43ed-b0c1-c0a2fe42b407",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"edge = world.create_static_body(\n",
|
||||||
|
" position=(0, 0), fixtures=b2d.fixture_def(shape=b2d.edge_shape([(-20, 0), (5, 0)]))\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"# random slope\n",
|
||||||
|
"x = np.linspace(5, 50, 10)\n",
|
||||||
|
"y = np.random.rand(10) * 4 - 2\n",
|
||||||
|
"y[0] = 0\n",
|
||||||
|
"xy = np.stack([x, y]).T\n",
|
||||||
|
"xy = np.flip(xy, axis=0)\n",
|
||||||
|
"edge = world.create_static_body(\n",
|
||||||
|
" position=(0, 0),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.chain_shape(xy, prev_vertex=(10, 0))),\n",
|
||||||
|
")\n",
|
||||||
|
"# create car\n",
|
||||||
|
"left_wheel = world.create_dynamic_body(\n",
|
||||||
|
" position=(-3, 2),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=2), density=1),\n",
|
||||||
|
")\n",
|
||||||
|
"right_wheel = world.create_dynamic_body(\n",
|
||||||
|
" position=(3, 2),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=2), density=1),\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"chasis = world.create_dynamic_body(\n",
|
||||||
|
" position=(0, 2),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.polygon_shape(box=[3, 0.5]), density=1),\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"wheel_joint_def = dict(\n",
|
||||||
|
" stiffness=10,\n",
|
||||||
|
" enable_motor=True,\n",
|
||||||
|
" motor_speed=-100,\n",
|
||||||
|
" max_motor_torque=100,\n",
|
||||||
|
" collide_connected=False,\n",
|
||||||
|
" enable_limit=True,\n",
|
||||||
|
" lower_translation=-0.4,\n",
|
||||||
|
" upper_translation=0.4,\n",
|
||||||
|
" local_axis_a=(0, 1),\n",
|
||||||
|
")\n",
|
||||||
|
"world.create_wheel_joint(chasis, left_wheel, local_anchor_a=(-3, 0), **wheel_joint_def)\n",
|
||||||
|
"world.create_wheel_joint(chasis, right_wheel, local_anchor_a=(3, 0), **wheel_joint_def)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=15, bounding_box=((-10,-5),(20,5)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "d9a0fffc-ae40-47ec-b185-2a6fe0dde496",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Tutorial 3.6: Distance Joint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "3c121398-f08f-4ea0-a875-de141ba53508",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"\n",
|
||||||
|
"for i in range(10):\n",
|
||||||
|
"\n",
|
||||||
|
" # create static anchor (does not need shape/fixture)\n",
|
||||||
|
" anchor = world.create_static_body(position=(i, 0))\n",
|
||||||
|
"\n",
|
||||||
|
" # 5 below the anchor\n",
|
||||||
|
" body = world.create_dynamic_body(\n",
|
||||||
|
" position=(i, -10),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=0.4), density=0.5),\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # distance joints of various stiffness-es\n",
|
||||||
|
" world.create_distance_joint(anchor, body, length=10, stiffness=0.5 * (i + 1))\n",
|
||||||
|
"\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=10, bounding_box=((-2,-20),(10,0)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "fb6afaff-8236-4206-85c7-3ba2de466ba9",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Tutorial 4: Particles"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "8f5c3b83-51d9-47cb-9b73-d5f8b0e03a76",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"world = b2d.world(gravity=(0, -10))\n",
|
||||||
|
"pdef = b2d.particle_system_def(radius=0.1)\n",
|
||||||
|
"psystem = world.create_particle_system(pdef)\n",
|
||||||
|
"\n",
|
||||||
|
"emitter_pos = (0, 0)\n",
|
||||||
|
"emitter_def = b2d.RandomizedLinearEmitterDef()\n",
|
||||||
|
"emitter_def.emite_rate = 400\n",
|
||||||
|
"emitter_def.lifetime = 5.1\n",
|
||||||
|
"emitter_def.size = (2, 1)\n",
|
||||||
|
"emitter_def.velocity = (6, 20)\n",
|
||||||
|
"emitter = b2d.RandomizedLinearEmitter(psystem, emitter_def)\n",
|
||||||
|
"b2d.plot.animate_world(world, ppm=20, t=10, bounding_box=((-10,-20),(20,5)), pre_step=emitter.step)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "ea9d7882-d3a4-45bb-b59b-cb1c9cd33990",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
123
content/pyodide/pyb2d/color_mixing.ipynb
Normal file
123
content/pyodide/pyb2d/color_mixing.ipynb
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"import random\n",
|
||||||
|
"import numpy\n",
|
||||||
|
"import b2d\n",
|
||||||
|
"\n",
|
||||||
|
"class ColorMixing(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"ColorMixing\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(ColorMixing, self).__init__(settings=settings)\n",
|
||||||
|
" dimensions = [30, 30]\n",
|
||||||
|
"\n",
|
||||||
|
" # the outer box\n",
|
||||||
|
" box_shape = b2d.ChainShape()\n",
|
||||||
|
" box_shape.create_loop(\n",
|
||||||
|
" [\n",
|
||||||
|
" (0, 0),\n",
|
||||||
|
" (0, dimensions[1]),\n",
|
||||||
|
" (dimensions[0], dimensions[1]),\n",
|
||||||
|
" (dimensions[0], 0),\n",
|
||||||
|
" ]\n",
|
||||||
|
" )\n",
|
||||||
|
" box = self.world.create_static_body(position=(0, 0), shape=box_shape)\n",
|
||||||
|
"\n",
|
||||||
|
" fixtureA = b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.circle_shape(1), density=2.2, friction=0.2, restitution=0.5\n",
|
||||||
|
" )\n",
|
||||||
|
" body = self.world.create_dynamic_body(position=(13, 10), fixtures=fixtureA)\n",
|
||||||
|
"\n",
|
||||||
|
" pdef = b2d.particle_system_def(\n",
|
||||||
|
" viscous_strength=0.9,\n",
|
||||||
|
" spring_strength=0.0,\n",
|
||||||
|
" damping_strength=0.5,\n",
|
||||||
|
" pressure_strength=0.5,\n",
|
||||||
|
" color_mixing_strength=0.008,\n",
|
||||||
|
" density=2,\n",
|
||||||
|
" )\n",
|
||||||
|
" psystem = self.world.create_particle_system(pdef)\n",
|
||||||
|
" psystem.radius = 0.3\n",
|
||||||
|
" psystem.damping = 1.0\n",
|
||||||
|
"\n",
|
||||||
|
" colors = [\n",
|
||||||
|
" (255, 0, 0, 255),\n",
|
||||||
|
" (0, 255, 0, 255),\n",
|
||||||
|
" (0, 0, 255, 255),\n",
|
||||||
|
" (255, 255, 0, 255),\n",
|
||||||
|
" ]\n",
|
||||||
|
" posiitons = [(6, 10), (20, 10), (20, 20), (6, 20)]\n",
|
||||||
|
" for color, pos in zip(colors, posiitons):\n",
|
||||||
|
"\n",
|
||||||
|
" shape = b2d.polygon_shape(box=(5, 5), center=pos, angle=0)\n",
|
||||||
|
" pgDef = b2d.particle_group_def(\n",
|
||||||
|
" flags=b2d.ParticleFlag.waterParticle\n",
|
||||||
|
" | b2d.ParticleFlag.colorMixingParticle,\n",
|
||||||
|
" # group_flags=b2d.ParticleGroupFlag.solidParticleGroup,\n",
|
||||||
|
" shape=shape,\n",
|
||||||
|
" strength=1.0,\n",
|
||||||
|
" color=color,\n",
|
||||||
|
" )\n",
|
||||||
|
" group = psystem.create_particle_group(pgDef)\n",
|
||||||
|
"\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"\n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [1000,500]\n",
|
||||||
|
"s.scale = 8\n",
|
||||||
|
"s.fps = 40\n",
|
||||||
|
"\n",
|
||||||
|
"tb = b2d.testbed.run(ColorMixing, backend=JupyterAsyncGui, gui_settings=s)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
419
content/pyodide/pyb2d/games/angry_shapes.ipynb
Normal file
419
content/pyodide/pyb2d/games/angry_shapes.ipynb
Normal file
|
@ -0,0 +1,419 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "2859de40-f927-4790-b192-c5b0531058f7",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "8ac3e93b-3e9e-4cd7-a183-0214b0dcb513",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"import math\n",
|
||||||
|
"import numpy\n",
|
||||||
|
"import b2d\n",
|
||||||
|
"\n",
|
||||||
|
"class AngryShapes(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"AngryShapes\"\n",
|
||||||
|
"\n",
|
||||||
|
" class Settings(TestbedBase.Settings):\n",
|
||||||
|
" substeps: int = 2\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_segment(self, p1, p2, color, line_width=1):\n",
|
||||||
|
" screen_p1 = self._point(self.world_to_screen(p1))\n",
|
||||||
|
" screen_p2 = self._point(self.world_to_screen(p2))\n",
|
||||||
|
" screen_color = self._uint8_color(color)\n",
|
||||||
|
" screen_line_width = self._line_width(line_width)\n",
|
||||||
|
"\n",
|
||||||
|
" cv.line(self._image, screen_p1, screen_p2, screen_color, screen_line_width)\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_polygon(self, vertices, color, line_width=1):\n",
|
||||||
|
" # todo add C++ function for this\n",
|
||||||
|
" screen_vertices = numpy.array(\n",
|
||||||
|
" [self._point(self.world_to_screen(v)) for v in vertices], dtype=\"int32\"\n",
|
||||||
|
" )\n",
|
||||||
|
" screen_color = self._uint8_color(color)\n",
|
||||||
|
" screen_line_width = self._line_width(line_width)\n",
|
||||||
|
"\n",
|
||||||
|
" cv.polylines(\n",
|
||||||
|
" self._image, [screen_vertices], True, screen_color, screen_line_width, 8\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_solid_polygon(self, vertices, color):\n",
|
||||||
|
" # todo add C++ function for this\n",
|
||||||
|
" screen_vertices = numpy.array(\n",
|
||||||
|
" [self._point(self.world_to_screen(v)) for v in vertices], dtype=\"int32\"\n",
|
||||||
|
" )\n",
|
||||||
|
" screen_color = self._uint8_color(color)\n",
|
||||||
|
"\n",
|
||||||
|
" cv.fillPoly(self._image, [screen_vertices], screen_color, 8)\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(AngryShapes, self).__init__(settings=settings)\n",
|
||||||
|
"\n",
|
||||||
|
" self.targets = []\n",
|
||||||
|
" self.projectiles = []\n",
|
||||||
|
" self.marked_for_destruction = []\n",
|
||||||
|
" self.emitter = None\n",
|
||||||
|
"\n",
|
||||||
|
" # particle system\n",
|
||||||
|
" pdef = b2d.particle_system_def(\n",
|
||||||
|
" viscous_strength=0.9,\n",
|
||||||
|
" spring_strength=0.0,\n",
|
||||||
|
" damping_strength=100.5,\n",
|
||||||
|
" pressure_strength=1.0,\n",
|
||||||
|
" color_mixing_strength=0.05,\n",
|
||||||
|
" density=0.1,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.psystem = self.world.create_particle_system(pdef)\n",
|
||||||
|
" self.psystem.radius = 1\n",
|
||||||
|
" self.psystem.damping = 0.5\n",
|
||||||
|
"\n",
|
||||||
|
" self.build_outer_box()\n",
|
||||||
|
" self.build_castle()\n",
|
||||||
|
" self.build_launcher()\n",
|
||||||
|
" self.arm_launcher()\n",
|
||||||
|
" self.build_explosives()\n",
|
||||||
|
"\n",
|
||||||
|
" def build_outer_box(self):\n",
|
||||||
|
" # the outer box\n",
|
||||||
|
"\n",
|
||||||
|
" shape = b2d.edge_shape([(100, 0), (600, 0)])\n",
|
||||||
|
" box = self.world.create_static_body(\n",
|
||||||
|
" position=(0, 0), fixtures=b2d.fixture_def(shape=shape, friction=1)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def build_target(self, pos):\n",
|
||||||
|
" t = self.world.create_dynamic_body(\n",
|
||||||
|
" position=pos,\n",
|
||||||
|
" fixtures=[\n",
|
||||||
|
" b2d.fixture_def(shape=b2d.circle_shape(radius=4), density=1.0),\n",
|
||||||
|
" b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.circle_shape(radius=2, pos=(3, 3)), density=1.0\n",
|
||||||
|
" ),\n",
|
||||||
|
" b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.circle_shape(radius=2, pos=(-3, 3)), density=1.0\n",
|
||||||
|
" ),\n",
|
||||||
|
" ],\n",
|
||||||
|
" linear_damping=0,\n",
|
||||||
|
" angular_damping=0,\n",
|
||||||
|
" user_data=\"target\",\n",
|
||||||
|
" )\n",
|
||||||
|
" self.targets.append(t)\n",
|
||||||
|
"\n",
|
||||||
|
" def build_castle(self):\n",
|
||||||
|
" def build_pyramid(offset, bar_shape, n):\n",
|
||||||
|
" def build_brick(pos, size):\n",
|
||||||
|
" hsize = [s / 2 for s in size]\n",
|
||||||
|
" self.world.create_dynamic_body(\n",
|
||||||
|
" position=(\n",
|
||||||
|
" pos[0] + hsize[0] + offset[0],\n",
|
||||||
|
" pos[1] + hsize[1] + offset[1],\n",
|
||||||
|
" ),\n",
|
||||||
|
" fixtures=b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.polygon_shape(box=hsize), density=8\n",
|
||||||
|
" ),\n",
|
||||||
|
" user_data=\"brick\",\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" bar_length = bar_shape[0]\n",
|
||||||
|
" bar_width = bar_shape[1]\n",
|
||||||
|
"\n",
|
||||||
|
" nxm = n\n",
|
||||||
|
" for y in range(nxm):\n",
|
||||||
|
" py = y * (bar_length + bar_width)\n",
|
||||||
|
" nx = nxm - y\n",
|
||||||
|
" for x in range(nx):\n",
|
||||||
|
" px = x * bar_length + y * (bar_length) / 2.0\n",
|
||||||
|
" if y + 1 < nxm - 1:\n",
|
||||||
|
" if x == 0:\n",
|
||||||
|
" px += bar_width / 2\n",
|
||||||
|
" if x + 1 == nx:\n",
|
||||||
|
" px -= bar_width / 2\n",
|
||||||
|
"\n",
|
||||||
|
" build_brick((px, py), (bar_width, bar_length))\n",
|
||||||
|
" if x < nx - 1:\n",
|
||||||
|
" self.build_target(\n",
|
||||||
|
" pos=(\n",
|
||||||
|
" px + offset[0] + bar_length / 2,\n",
|
||||||
|
" py + offset[1] + bar_width,\n",
|
||||||
|
" )\n",
|
||||||
|
" )\n",
|
||||||
|
" build_brick(\n",
|
||||||
|
" (px + bar_width / 2, py + bar_length),\n",
|
||||||
|
" (bar_length, bar_width),\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" build_pyramid(offset=(100, 0), bar_shape=[40, 4], n=4)\n",
|
||||||
|
" build_pyramid(offset=(400, 0), bar_shape=[30, 3], n=4)\n",
|
||||||
|
"\n",
|
||||||
|
" def build_launcher(self):\n",
|
||||||
|
"\n",
|
||||||
|
" self.launcher_anchor_pos = (30, 0)\n",
|
||||||
|
" self.launcher_anchor = self.world.create_static_body(\n",
|
||||||
|
" position=self.launcher_anchor_pos\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def arm_launcher(self):\n",
|
||||||
|
" self.reload_time = None\n",
|
||||||
|
" self.is_armed = True\n",
|
||||||
|
" self.projectile_radius = 3\n",
|
||||||
|
" projectile_pos = (self.launcher_anchor_pos[0], self.launcher_anchor_pos[1] / 2)\n",
|
||||||
|
"\n",
|
||||||
|
" self.projectile = self.world.create_dynamic_body(\n",
|
||||||
|
" position=projectile_pos,\n",
|
||||||
|
" fixtures=b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.circle_shape(radius=self.projectile_radius), density=100.0\n",
|
||||||
|
" ),\n",
|
||||||
|
" linear_damping=0,\n",
|
||||||
|
" angular_damping=0,\n",
|
||||||
|
" user_data=\"projectile\",\n",
|
||||||
|
" )\n",
|
||||||
|
" self.projectiles.append(self.projectile)\n",
|
||||||
|
" self.projectile_joint = self.world.create_distance_joint(\n",
|
||||||
|
" self.launcher_anchor, self.projectile, length=1, stiffness=10000\n",
|
||||||
|
" )\n",
|
||||||
|
" self.mouse_joint = None\n",
|
||||||
|
"\n",
|
||||||
|
" def build_explosives(self):\n",
|
||||||
|
" self.explosives = []\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_down(self, p):\n",
|
||||||
|
" if self.is_armed:\n",
|
||||||
|
" body = self.world.find_body(pos=p)\n",
|
||||||
|
" if body is not None and body.user_data is not None:\n",
|
||||||
|
" print(\"got body\")\n",
|
||||||
|
" if body.user_data == \"projectile\":\n",
|
||||||
|
" print(\"got projectile\")\n",
|
||||||
|
" kwargs = dict(\n",
|
||||||
|
" body_a=self.groundbody,\n",
|
||||||
|
" body_b=body,\n",
|
||||||
|
" target=p,\n",
|
||||||
|
" max_force=50000.0 * body.mass,\n",
|
||||||
|
" stiffness=10000.0,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.mouse_joint = self.world.create_mouse_joint(**kwargs)\n",
|
||||||
|
" body.awake = True\n",
|
||||||
|
" return True\n",
|
||||||
|
"\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_move(self, p):\n",
|
||||||
|
" if self.is_armed:\n",
|
||||||
|
" if self.mouse_joint is not None:\n",
|
||||||
|
" self.mouse_joint.target = p\n",
|
||||||
|
" return True\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_up(self, p):\n",
|
||||||
|
" if self.is_armed:\n",
|
||||||
|
" if self.mouse_joint is not None:\n",
|
||||||
|
" self.world.destroy_joint(self.mouse_joint)\n",
|
||||||
|
" if self.projectile_joint is not None:\n",
|
||||||
|
" self.world.destroy_joint(self.projectile_joint)\n",
|
||||||
|
" self.projectile_joint = None\n",
|
||||||
|
" self.mouse_joint = None\n",
|
||||||
|
" delta = self.launcher_anchor.position - b2d.vec2(p)\n",
|
||||||
|
" scaled_delta = delta * 50000.0\n",
|
||||||
|
" print(scaled_delta)\n",
|
||||||
|
"\n",
|
||||||
|
" self.projectile.apply_linear_impulse_to_center(scaled_delta, True)\n",
|
||||||
|
" self.reload_time = self.elapsed_time + 1.0\n",
|
||||||
|
" self.is_armed = False\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def begin_contact(self, contact):\n",
|
||||||
|
" body_a = contact.body_a\n",
|
||||||
|
" body_b = contact.body_b\n",
|
||||||
|
" ud_a = body_a.user_data\n",
|
||||||
|
" ud_b = body_b.user_data\n",
|
||||||
|
" if ud_b == \"projectile\":\n",
|
||||||
|
" body_a, body_b = body_b, body_a\n",
|
||||||
|
" ud_a, ud_b = ud_b, ud_a\n",
|
||||||
|
" if ud_a == \"projectile\":\n",
|
||||||
|
"\n",
|
||||||
|
" if ud_b == \"target\" or ud_b == \"brick\":\n",
|
||||||
|
" self.marked_for_destruction.append(body_a)\n",
|
||||||
|
" emitter_def = b2d.RandomizedRadialEmitterDef()\n",
|
||||||
|
" emitter_def.emite_rate = 20000\n",
|
||||||
|
" emitter_def.lifetime = 0.7\n",
|
||||||
|
" emitter_def.enabled = True\n",
|
||||||
|
" emitter_def.inner_radius = 0.0\n",
|
||||||
|
" emitter_def.outer_radius = 1.0\n",
|
||||||
|
" emitter_def.velocity_magnitude = 1000.0\n",
|
||||||
|
" emitter_def.start_angle = 0\n",
|
||||||
|
" emitter_def.stop_angle = math.pi\n",
|
||||||
|
" emitter_def.transform = b2d.Transform(body_a.position, b2d.Rot(0))\n",
|
||||||
|
" self.emitter = b2d.RandomizedRadialEmitter(self.psystem, emitter_def)\n",
|
||||||
|
" self.emitter_die_time = self.elapsed_time + 0.02\n",
|
||||||
|
"\n",
|
||||||
|
" def pre_step(self, dt):\n",
|
||||||
|
"\n",
|
||||||
|
" if self.reload_time is not None:\n",
|
||||||
|
" if self.elapsed_time >= self.reload_time:\n",
|
||||||
|
" self.arm_launcher()\n",
|
||||||
|
"\n",
|
||||||
|
" # delete contact bodies\n",
|
||||||
|
" for body in self.marked_for_destruction:\n",
|
||||||
|
" if body in self.projectiles:\n",
|
||||||
|
" self.projectiles.remove(body)\n",
|
||||||
|
" self.world.destroy_body(body)\n",
|
||||||
|
" if body == self.projectile:\n",
|
||||||
|
" self.reload_time = self.elapsed_time + 1.0\n",
|
||||||
|
" self.marked_for_destruction = []\n",
|
||||||
|
"\n",
|
||||||
|
" # delete bodies which have fallen down\n",
|
||||||
|
" for body in self.world.bodies:\n",
|
||||||
|
" if body.position.y < -100:\n",
|
||||||
|
" if body.user_data == \"projectile\":\n",
|
||||||
|
" self.projectiles.remove(body)\n",
|
||||||
|
" if body.user_data == \"target\":\n",
|
||||||
|
" self.targets.remove(body)\n",
|
||||||
|
" self.world.destroy_body(body)\n",
|
||||||
|
"\n",
|
||||||
|
" # emmiter\n",
|
||||||
|
" if self.emitter is not None:\n",
|
||||||
|
" self.emitter.step(dt)\n",
|
||||||
|
" if self.elapsed_time >= self.emitter_die_time:\n",
|
||||||
|
" self.emitter = None\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_target(self, target):\n",
|
||||||
|
" center = target.position\n",
|
||||||
|
" center_l = target.get_world_point((-3, 3))\n",
|
||||||
|
" center_r = target.get_world_point((3, 3))\n",
|
||||||
|
" eye_left = target.get_world_point((-1, 1))\n",
|
||||||
|
" eye_right = target.get_world_point((1, 1))\n",
|
||||||
|
" pink = [c / 255 for c in (248, 24, 148)]\n",
|
||||||
|
"\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=center, radius=4, axis=None, color=pink\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=center_l, radius=2, axis=None, color=pink\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=center_r, radius=2, axis=None, color=pink\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # schnautze\n",
|
||||||
|
" nose_center = target.get_world_point((0, -1))\n",
|
||||||
|
" nose_center_l = target.get_world_point((-0.3, -1))\n",
|
||||||
|
" nose_center_r = target.get_world_point((0.3, -1))\n",
|
||||||
|
"\n",
|
||||||
|
" self.debug_draw.draw_circle(\n",
|
||||||
|
" center=nose_center,\n",
|
||||||
|
" radius=2,\n",
|
||||||
|
" # axis=None,\n",
|
||||||
|
" color=(1, 1, 1),\n",
|
||||||
|
" line_width=0.2,\n",
|
||||||
|
" )\n",
|
||||||
|
" # eyes\n",
|
||||||
|
" for nose_center in [nose_center_l, nose_center_r]:\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=nose_center, radius=0.6, axis=None, color=(1, 1, 1)\n",
|
||||||
|
" )\n",
|
||||||
|
" # eyes\n",
|
||||||
|
" for eye_center in [eye_left, eye_right]:\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=eye_center, radius=1, axis=None, color=(1, 1, 1)\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=eye_center, radius=0.7, axis=None, color=(0, 0, 0)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_projectile(self, projectile):\n",
|
||||||
|
"\n",
|
||||||
|
" center = projectile.position\n",
|
||||||
|
" # center_l = target.get_world_point((-3,3))\n",
|
||||||
|
" # center_r = target.get_world_point(( 3,3))\n",
|
||||||
|
" eye_left = projectile.get_world_point((-1, 1))\n",
|
||||||
|
" eye_right = projectile.get_world_point((1, 1))\n",
|
||||||
|
"\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=center,\n",
|
||||||
|
" radius=self.projectile_radius * 1.1,\n",
|
||||||
|
" axis=None,\n",
|
||||||
|
" color=(1, 0, 0),\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # eyes\n",
|
||||||
|
" for eye_center in [eye_left, eye_right]:\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=eye_center, radius=1, axis=None, color=(1, 1, 1)\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center=eye_center, radius=0.7, axis=None, color=(0, 0, 0)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def post_debug_draw(self):\n",
|
||||||
|
" for target in self.targets:\n",
|
||||||
|
" self.draw_target(target)\n",
|
||||||
|
"\n",
|
||||||
|
" for projectile in self.projectiles:\n",
|
||||||
|
" self.draw_projectile(projectile)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "6df7c8b9-216b-4fd2-8ee8-aeec294e149d",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Controlls\n",
|
||||||
|
"* To play this game, click and drag the red ball and release it to shot it.\n",
|
||||||
|
"* Use the mouse-wheel to zoom in/out, a\n",
|
||||||
|
"* Click and drag in the empty space to translate the view."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "df412e76-7a9a-4e1d-8bc7-c02e222e10dc",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [1000,500]\n",
|
||||||
|
"s.scale = 2\n",
|
||||||
|
"s.translate = [100,100]\n",
|
||||||
|
"tb = b2d.testbed.run(AngryShapes, backend=JupyterAsyncGui, gui_settings=s);"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
299
content/pyodide/pyb2d/games/billiard.ipynb
Normal file
299
content/pyodide/pyb2d/games/billiard.ipynb
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import numpy\n",
|
||||||
|
"import b2d\n",
|
||||||
|
"import math\n",
|
||||||
|
"import random\n",
|
||||||
|
"\n",
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"\n",
|
||||||
|
"class Billiard(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"Billiard\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(Billiard, self).__init__(gravity=(0, 0), settings=settings)\n",
|
||||||
|
" dimensions = [30, 50]\n",
|
||||||
|
" self.dimensions = dimensions\n",
|
||||||
|
"\n",
|
||||||
|
" # the outer box\n",
|
||||||
|
" box_shape = b2d.ChainShape()\n",
|
||||||
|
" box_shape.create_loop(\n",
|
||||||
|
" [\n",
|
||||||
|
" (0, 0),\n",
|
||||||
|
" (0, dimensions[1]),\n",
|
||||||
|
" (dimensions[0], dimensions[1]),\n",
|
||||||
|
" (dimensions[0], 0),\n",
|
||||||
|
" ]\n",
|
||||||
|
" )\n",
|
||||||
|
" self.ball_radius = 1\n",
|
||||||
|
" box = self.world.create_static_body(\n",
|
||||||
|
" position=(0, 0), fixtures=b2d.fixture_def(shape=box_shape, friction=0)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.place_balls()\n",
|
||||||
|
" self.place_pockets()\n",
|
||||||
|
"\n",
|
||||||
|
" # mouse interaction\n",
|
||||||
|
" self._selected_ball = None\n",
|
||||||
|
" self._selected_ball_pos = None\n",
|
||||||
|
" self._last_pos = None\n",
|
||||||
|
"\n",
|
||||||
|
" # balls to be destroyed in the next step\n",
|
||||||
|
" # since they are in the pocket\n",
|
||||||
|
" self._to_be_destroyed = []\n",
|
||||||
|
"\n",
|
||||||
|
" def place_pockets(self):\n",
|
||||||
|
" pocket_radius = 1\n",
|
||||||
|
" self.pockets = []\n",
|
||||||
|
"\n",
|
||||||
|
" def place_pocket(position):\n",
|
||||||
|
" pocket_shape = b2d.circle_shape(radius=pocket_radius / 3)\n",
|
||||||
|
" pocket = self.world.create_static_body(\n",
|
||||||
|
" position=position,\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=pocket_shape, is_sensor=True),\n",
|
||||||
|
" user_data=(\"pocket\", None),\n",
|
||||||
|
" )\n",
|
||||||
|
" self.pockets.append(pocket)\n",
|
||||||
|
"\n",
|
||||||
|
" d = pocket_radius / 2\n",
|
||||||
|
"\n",
|
||||||
|
" place_pocket(position=(0 + d, 0 + d))\n",
|
||||||
|
" place_pocket(position=(self.dimensions[0] - d, 0 + d))\n",
|
||||||
|
"\n",
|
||||||
|
" place_pocket(position=(0 + d, self.dimensions[1] / 2))\n",
|
||||||
|
" place_pocket(position=(self.dimensions[0] - d, self.dimensions[1] / 2))\n",
|
||||||
|
"\n",
|
||||||
|
" place_pocket(position=(0 + d, self.dimensions[1] - d))\n",
|
||||||
|
" place_pocket(position=(self.dimensions[0] - d, self.dimensions[1] - d))\n",
|
||||||
|
"\n",
|
||||||
|
" def place_balls(self):\n",
|
||||||
|
" self.balls = []\n",
|
||||||
|
"\n",
|
||||||
|
" base_colors = [\n",
|
||||||
|
" (1, 1, 0),\n",
|
||||||
|
" (0, 0, 1),\n",
|
||||||
|
" (1, 0, 0),\n",
|
||||||
|
" (1, 0, 1),\n",
|
||||||
|
" (1, 0.6, 0),\n",
|
||||||
|
" (0, 1, 0),\n",
|
||||||
|
" (0.7, 0.4, 0.4),\n",
|
||||||
|
" ]\n",
|
||||||
|
" colors = []\n",
|
||||||
|
" for color in base_colors:\n",
|
||||||
|
" # ``full`` ball\n",
|
||||||
|
" colors.append((color, color))\n",
|
||||||
|
" # ``half`` ball (half white)\n",
|
||||||
|
" colors.append((color, (1, 1, 1)))\n",
|
||||||
|
"\n",
|
||||||
|
" random.shuffle(colors)\n",
|
||||||
|
" colors.insert(4, ((0, 0, 0), (0, 0, 0))) # black\n",
|
||||||
|
"\n",
|
||||||
|
" n_y = 5\n",
|
||||||
|
" c_x = self.dimensions[0] / 2\n",
|
||||||
|
" diameter = (self.ball_radius * 2) * 1.01\n",
|
||||||
|
"\n",
|
||||||
|
" bi = 0\n",
|
||||||
|
" for y in range(n_y):\n",
|
||||||
|
"\n",
|
||||||
|
" py = y * diameter * 0.5 * math.sqrt(3)\n",
|
||||||
|
" n_x = y + 1\n",
|
||||||
|
" ox = diameter * (n_y - y) / 2\n",
|
||||||
|
" for x in range(y + 1):\n",
|
||||||
|
" position = (x * diameter + 10 + ox, py + 30)\n",
|
||||||
|
" self.create_billard_ball(position=position, color=colors[bi])\n",
|
||||||
|
" bi += 1\n",
|
||||||
|
"\n",
|
||||||
|
" self.create_billard_ball(position=(c_x, 10), color=((1, 1, 1), (1, 1, 1)))\n",
|
||||||
|
"\n",
|
||||||
|
" def create_billard_ball(self, position, color):\n",
|
||||||
|
"\n",
|
||||||
|
" ball = self.world.create_dynamic_body(\n",
|
||||||
|
" position=position,\n",
|
||||||
|
" fixtures=b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.circle_shape(radius=self.ball_radius),\n",
|
||||||
|
" density=1.0,\n",
|
||||||
|
" restitution=0.8,\n",
|
||||||
|
" ),\n",
|
||||||
|
" linear_damping=0.8,\n",
|
||||||
|
" user_data=(\"ball\", color),\n",
|
||||||
|
" fixed_rotation=True,\n",
|
||||||
|
" )\n",
|
||||||
|
" self.balls.append(ball)\n",
|
||||||
|
"\n",
|
||||||
|
" def begin_contact(self, contact):\n",
|
||||||
|
" body_a = contact.body_a\n",
|
||||||
|
" body_b = contact.body_b\n",
|
||||||
|
"\n",
|
||||||
|
" ud_a = body_a.user_data\n",
|
||||||
|
" ud_b = body_b.user_data\n",
|
||||||
|
" if ud_a is None or ud_b is None:\n",
|
||||||
|
" return\n",
|
||||||
|
"\n",
|
||||||
|
" if ud_b[0] == \"ball\":\n",
|
||||||
|
" body_a, body_b = body_b, body_a\n",
|
||||||
|
" ud_a, ud_b = ud_b, ud_a\n",
|
||||||
|
"\n",
|
||||||
|
" if ud_a[0] == \"ball\" and ud_b[0] == \"pocket\":\n",
|
||||||
|
" self._to_be_destroyed.append(body_a)\n",
|
||||||
|
"\n",
|
||||||
|
" def pre_step(self, dt):\n",
|
||||||
|
" for b in self._to_be_destroyed:\n",
|
||||||
|
" self.balls.remove(b)\n",
|
||||||
|
" self.world.destroy_body(b)\n",
|
||||||
|
" self._to_be_destroyed = []\n",
|
||||||
|
"\n",
|
||||||
|
" def ball_at_position(self, pos):\n",
|
||||||
|
" body = self.world.find_body(pos)\n",
|
||||||
|
" if body is not None:\n",
|
||||||
|
" user_data = body.user_data\n",
|
||||||
|
" if user_data is not None and user_data[0] == \"ball\":\n",
|
||||||
|
" return body\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_down(self, pos):\n",
|
||||||
|
" body = self.ball_at_position(pos)\n",
|
||||||
|
" if body is not None:\n",
|
||||||
|
" self._selected_ball = body\n",
|
||||||
|
" self._selected_ball_pos = pos\n",
|
||||||
|
" return True\n",
|
||||||
|
"\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_move(self, pos):\n",
|
||||||
|
" if self._selected_ball is not None:\n",
|
||||||
|
" self._last_pos = pos\n",
|
||||||
|
" return True\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_up(self, pos):\n",
|
||||||
|
" if self._selected_ball is not None:\n",
|
||||||
|
" self._last_pos = pos\n",
|
||||||
|
" # if the mouse is in the starting ball itself we do nothing\n",
|
||||||
|
" if self.ball_at_position(pos) != self._selected_ball:\n",
|
||||||
|
" delta = b2d.vec2(self._selected_ball_pos) - b2d.vec2(self._last_pos)\n",
|
||||||
|
" delta *= 100.0\n",
|
||||||
|
" self._selected_ball.apply_linear_impulse(\n",
|
||||||
|
" delta, self._selected_ball_pos, True\n",
|
||||||
|
" )\n",
|
||||||
|
" self._selected_ball = None\n",
|
||||||
|
" self._selected_ball_pos = None\n",
|
||||||
|
" self._last_pos = None\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def post_debug_draw(self):\n",
|
||||||
|
"\n",
|
||||||
|
" for pocket in self.pockets:\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" pocket.position, self.ball_radius, (1, 0), (1, 1, 1)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" for ball in self.balls:\n",
|
||||||
|
" _, (color0, color1) = ball.user_data\n",
|
||||||
|
"\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" ball.position, self.ball_radius, (1, 0), color0\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" ball.position, self.ball_radius / 2, (1, 0), color1\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_circle(\n",
|
||||||
|
" ball.position, self.ball_radius, (1, 1, 1), line_width=0.1\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" if self._selected_ball is not None:\n",
|
||||||
|
"\n",
|
||||||
|
" # draw circle around selected ball\n",
|
||||||
|
" self.debug_draw.draw_circle(\n",
|
||||||
|
" self._selected_ball.position,\n",
|
||||||
|
" self.ball_radius * 2,\n",
|
||||||
|
" (1, 1, 1),\n",
|
||||||
|
" line_width=0.2,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # mark position on selected ball with red dot\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" self._selected_ball_pos, self.ball_radius * 0.2, (1, 0), (1, 0, 0)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # draw the line between marked pos on ball and last pos\n",
|
||||||
|
" if self._last_pos is not None:\n",
|
||||||
|
" self.debug_draw.draw_segment(\n",
|
||||||
|
" self._selected_ball_pos, self._last_pos, (1, 1, 1), line_width=0.2\n",
|
||||||
|
" )"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Controlls\n",
|
||||||
|
"* To play this game, click and hold inside a billiard ball, move and release the mouse to shoot the ball.\n",
|
||||||
|
"* Use the mouse-wheel to zoom in/out, a\n",
|
||||||
|
"* Click and drag in the empty space to translate the view."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"backend = JupyterAsyncGui\n",
|
||||||
|
"s = backend.Settings()\n",
|
||||||
|
"s.resolution = [500,600]\n",
|
||||||
|
"s.scale = 8\n",
|
||||||
|
"s.fps = 40\n",
|
||||||
|
"s.translate = [125,100]\n",
|
||||||
|
"b2d.testbed.run(Billiard, backend=backend, gui_settings=s);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
575
content/pyodide/pyb2d/games/goo.ipynb
Normal file
575
content/pyodide/pyb2d/games/goo.ipynb
Normal file
|
@ -0,0 +1,575 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('networkx')\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import b2d\n",
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"import math\n",
|
||||||
|
"import random\n",
|
||||||
|
"import numpy\n",
|
||||||
|
"from functools import partial\n",
|
||||||
|
"import networkx\n",
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"\n",
|
||||||
|
"def best_pairwise_distance(data, f, distance):\n",
|
||||||
|
" n = len(data)\n",
|
||||||
|
" best = (None, None, float(\"inf\"))\n",
|
||||||
|
" for i in range(n - 1):\n",
|
||||||
|
" da = f(data[i])\n",
|
||||||
|
" for j in range(i + 1, n):\n",
|
||||||
|
" db = f(data[j])\n",
|
||||||
|
"\n",
|
||||||
|
" d = distance(da, db)\n",
|
||||||
|
" if d < best[2]:\n",
|
||||||
|
" best = (i, j, d)\n",
|
||||||
|
" return best\n",
|
||||||
|
"\n",
|
||||||
|
"class Level(object):\n",
|
||||||
|
" def __init__(self, testbed):\n",
|
||||||
|
" self.testbed = testbed\n",
|
||||||
|
" self.world = testbed.world\n",
|
||||||
|
"\n",
|
||||||
|
" self.gap_size = 15\n",
|
||||||
|
" self.kill_sensors_height = 0.5\n",
|
||||||
|
" self.usable_size = 20\n",
|
||||||
|
" self.h = 10\n",
|
||||||
|
" self.end_zone_height = 3\n",
|
||||||
|
"\n",
|
||||||
|
" self.outline_verts = [\n",
|
||||||
|
" (0, self.h),\n",
|
||||||
|
" (0, 2 * self.h),\n",
|
||||||
|
" (0, self.h),\n",
|
||||||
|
" (self.usable_size, self.h),\n",
|
||||||
|
" (self.usable_size, 0),\n",
|
||||||
|
" (self.usable_size + self.gap_size, 0),\n",
|
||||||
|
" (self.usable_size + self.gap_size, self.h),\n",
|
||||||
|
" (2 * self.usable_size + self.gap_size, self.h),\n",
|
||||||
|
" (2 * self.usable_size + self.gap_size, 2 * self.h),\n",
|
||||||
|
" ]\n",
|
||||||
|
"\n",
|
||||||
|
" # outline of the level\n",
|
||||||
|
" shape = b2d.chain_shape(vertices=numpy.flip(self.outline_verts, axis=0))\n",
|
||||||
|
" self.outline = self.world.create_static_body(position=(0, 0), shape=shape)\n",
|
||||||
|
"\n",
|
||||||
|
" # kill sensors\n",
|
||||||
|
" self.kill_sensor_pos = (\n",
|
||||||
|
" self.usable_size + self.gap_size / 2,\n",
|
||||||
|
" self.kill_sensors_height / 2,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" shape = b2d.polygon_shape(box=(self.gap_size / 2, self.kill_sensors_height / 2))\n",
|
||||||
|
" self._kill_sensor = self.world.create_static_body(\n",
|
||||||
|
" position=self.kill_sensor_pos,\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=shape, is_sensor=True),\n",
|
||||||
|
" )\n",
|
||||||
|
" self._kill_sensor.user_data = \"destroyer\"\n",
|
||||||
|
"\n",
|
||||||
|
" # end sensor\n",
|
||||||
|
" shape = b2d.polygon_shape(box=(self.usable_size / 2, self.end_zone_height / 2))\n",
|
||||||
|
" self._end_sensor = self.world.create_static_body(\n",
|
||||||
|
" position=(\n",
|
||||||
|
" 1.5 * self.usable_size + self.gap_size,\n",
|
||||||
|
" self.h + self.end_zone_height / 2,\n",
|
||||||
|
" ),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=shape, is_sensor=True),\n",
|
||||||
|
" )\n",
|
||||||
|
" self._end_sensor.user_data = \"goal\"\n",
|
||||||
|
"\n",
|
||||||
|
" goo_radius = 1\n",
|
||||||
|
" a = self.testbed.insert_goo(\n",
|
||||||
|
" pos=(self.usable_size / 3, self.h + goo_radius), static=True\n",
|
||||||
|
" )\n",
|
||||||
|
" b = self.testbed.insert_goo(\n",
|
||||||
|
" pos=(self.usable_size * 2 / 3, self.h + goo_radius), static=True\n",
|
||||||
|
" )\n",
|
||||||
|
" c = self.testbed.insert_goo(\n",
|
||||||
|
" pos=(self.usable_size * 1 / 2, self.h + goo_radius + 4), static=False\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.testbed.connect_goos(a, b)\n",
|
||||||
|
" self.testbed.connect_goos(a, c)\n",
|
||||||
|
" self.testbed.connect_goos(b, c)\n",
|
||||||
|
"\n",
|
||||||
|
" def draw(self, debug_draw):\n",
|
||||||
|
"\n",
|
||||||
|
" # draw outline\n",
|
||||||
|
" for i in range(len(self.outline_verts) - 1):\n",
|
||||||
|
" debug_draw.draw_segment(\n",
|
||||||
|
" self.outline_verts[i],\n",
|
||||||
|
" self.outline_verts[i + 1],\n",
|
||||||
|
" color=(1, 1, 0),\n",
|
||||||
|
" line_width=0.3,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" left = list(self.kill_sensor_pos)\n",
|
||||||
|
" left[0] -= self.gap_size / 2\n",
|
||||||
|
" left[1] += self.kill_sensors_height / 2\n",
|
||||||
|
"\n",
|
||||||
|
" right = list(self.kill_sensor_pos)\n",
|
||||||
|
" right[0] += self.gap_size / 2\n",
|
||||||
|
" right[1] += self.kill_sensors_height / 2\n",
|
||||||
|
" debug_draw.draw_segment(left, right, (1, 0, 0), line_width=0.4)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class FindGoos(b2d.QueryCallback):\n",
|
||||||
|
" def __init__(self):\n",
|
||||||
|
" super(FindGoos, self).__init__()\n",
|
||||||
|
" self.goos = []\n",
|
||||||
|
"\n",
|
||||||
|
" def report_fixture(self, fixture):\n",
|
||||||
|
" body = fixture.body\n",
|
||||||
|
" if body.user_data == \"goo\":\n",
|
||||||
|
" self.goos.append(body)\n",
|
||||||
|
" return True\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class Goo(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"Goo\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(Goo, self).__init__(settings=settings)\n",
|
||||||
|
"\n",
|
||||||
|
" self.goo_graph = networkx.Graph()\n",
|
||||||
|
" self.level = Level(testbed=self)\n",
|
||||||
|
"\n",
|
||||||
|
" # mouse related\n",
|
||||||
|
" self.last_mouse_pos = None\n",
|
||||||
|
" self.is_mouse_down = False\n",
|
||||||
|
" self.could_place_goo_when_mouse_was_down = False\n",
|
||||||
|
"\n",
|
||||||
|
" # callback to draw tentative placement\n",
|
||||||
|
" self.draw_callback = None\n",
|
||||||
|
"\n",
|
||||||
|
" # goos marked for destruction\n",
|
||||||
|
" self.goo_to_destroy = []\n",
|
||||||
|
"\n",
|
||||||
|
" # joints marked for destruction\n",
|
||||||
|
" self.joints_to_destroy = []\n",
|
||||||
|
" self.gamma = 0.003\n",
|
||||||
|
" self.break_threshold = 0.5\n",
|
||||||
|
"\n",
|
||||||
|
" # time point when goo can be inserted\n",
|
||||||
|
" self.insert_time_point = 0\n",
|
||||||
|
" self.insert_delay = 1.0\n",
|
||||||
|
"\n",
|
||||||
|
" # handle finishing of level\n",
|
||||||
|
" self.with_goal_contact = dict()\n",
|
||||||
|
"\n",
|
||||||
|
" # amount of seconds one has to be in the finishing zone\n",
|
||||||
|
" self.win_delay = 3.0\n",
|
||||||
|
"\n",
|
||||||
|
" # particle system will be defined an used on win!\n",
|
||||||
|
" # this is then used for some kind of fireworks\n",
|
||||||
|
" self.psystem = None\n",
|
||||||
|
" self.emitter = None\n",
|
||||||
|
" self.emitter_stop_time = None\n",
|
||||||
|
" self.emitter_start_time = None\n",
|
||||||
|
"\n",
|
||||||
|
" # trigger some fireworks on win\n",
|
||||||
|
" def on_win(self, win_body):\n",
|
||||||
|
"\n",
|
||||||
|
" if self.psystem is None:\n",
|
||||||
|
" # particle system\n",
|
||||||
|
" pdef = b2d.particle_system_def(\n",
|
||||||
|
" viscous_strength=0.9,\n",
|
||||||
|
" spring_strength=0.0,\n",
|
||||||
|
" damping_strength=100.5,\n",
|
||||||
|
" pressure_strength=1.0,\n",
|
||||||
|
" color_mixing_strength=0.05,\n",
|
||||||
|
" density=0.1,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.psystem = self.world.create_particle_system(pdef)\n",
|
||||||
|
" self.psystem.radius = 0.1\n",
|
||||||
|
" self.psystem.damping = 0.5\n",
|
||||||
|
"\n",
|
||||||
|
" emitter_def = b2d.RandomizedRadialEmitterDef()\n",
|
||||||
|
" emitter_def.emite_rate = 2000\n",
|
||||||
|
" emitter_def.lifetime = 0.9\n",
|
||||||
|
" emitter_def.enabled = True\n",
|
||||||
|
" emitter_def.inner_radius = 0.0\n",
|
||||||
|
" emitter_def.outer_radius = 0.1\n",
|
||||||
|
" emitter_def.velocity_magnitude = 1000.0\n",
|
||||||
|
" emitter_def.start_angle = 0\n",
|
||||||
|
" emitter_def.stop_angle = 2 * math.pi\n",
|
||||||
|
" emitter_def.transform = b2d.Transform(\n",
|
||||||
|
" win_body.position + b2d.vec2(0, 20), b2d.Rot(0)\n",
|
||||||
|
" )\n",
|
||||||
|
" self.emitter = b2d.RandomizedRadialEmitter(self.psystem, emitter_def)\n",
|
||||||
|
" self.emitter_stop_time = self.elapsed_time + 0.2\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_goo(self, pos, angle, body=None):\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(pos, 1, axis=None, color=(1, 0, 1))\n",
|
||||||
|
" self.debug_draw.draw_circle(pos, 1.1, (1, 1, 1), line_width=0.1)\n",
|
||||||
|
"\n",
|
||||||
|
" if body is not None:\n",
|
||||||
|
" centers = [\n",
|
||||||
|
" body.get_world_point((-0.3, 0.2)),\n",
|
||||||
|
" body.get_world_point((0.3, 0.2)),\n",
|
||||||
|
" ]\n",
|
||||||
|
" for center in centers:\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center, 0.4, axis=None, color=(1, 1, 1)\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" center, 0.2, axis=None, color=(0, 0, 0)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_edge(self, pos_a, pos_b, stress):\n",
|
||||||
|
" no_stress = numpy.array([1, 1, 1])\n",
|
||||||
|
" has_stress = numpy.array([1, 0, 0])\n",
|
||||||
|
" color = (1.0 - stress) * no_stress + stress * has_stress\n",
|
||||||
|
" color = tuple([float(c) for c in color])\n",
|
||||||
|
" self.debug_draw.draw_segment(pos_a, pos_b, color=color, line_width=0.4)\n",
|
||||||
|
"\n",
|
||||||
|
" def insert_goo(self, pos, static=False):\n",
|
||||||
|
" if static:\n",
|
||||||
|
" f = self.world.create_static_body\n",
|
||||||
|
" else:\n",
|
||||||
|
" f = self.world.create_dynamic_body\n",
|
||||||
|
"\n",
|
||||||
|
" goo = f(\n",
|
||||||
|
" position=pos,\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=1), density=1),\n",
|
||||||
|
" user_data=\"goo\",\n",
|
||||||
|
" )\n",
|
||||||
|
" self.goo_graph.add_node(goo)\n",
|
||||||
|
" return goo\n",
|
||||||
|
"\n",
|
||||||
|
" def connect_goos(self, goo_a, goo_b):\n",
|
||||||
|
" length = (goo_a.position - goo_b.position).length\n",
|
||||||
|
" joint = self.world.create_distance_joint(\n",
|
||||||
|
" goo_a,\n",
|
||||||
|
" goo_b,\n",
|
||||||
|
" stiffness=500,\n",
|
||||||
|
" damping=0.1,\n",
|
||||||
|
" length=length,\n",
|
||||||
|
" user_data=dict(length=length, stress=0),\n",
|
||||||
|
" )\n",
|
||||||
|
" self.goo_graph.add_edge(goo_a, goo_b, joint=joint)\n",
|
||||||
|
"\n",
|
||||||
|
" def query_placement(self, pos):\n",
|
||||||
|
"\n",
|
||||||
|
" radius = 8\n",
|
||||||
|
"\n",
|
||||||
|
" # find all goos in around pos\n",
|
||||||
|
" pos = b2d.vec2(pos)\n",
|
||||||
|
" box = b2d.aabb(\n",
|
||||||
|
" lower_bound=pos - b2d.vec2(radius, radius),\n",
|
||||||
|
" upper_bound=pos + b2d.vec2(radius, radius),\n",
|
||||||
|
" )\n",
|
||||||
|
" query = FindGoos()\n",
|
||||||
|
" self.world.query_aabb(query, box)\n",
|
||||||
|
" goos = query.goos\n",
|
||||||
|
" n_goos = len(goos)\n",
|
||||||
|
"\n",
|
||||||
|
" if n_goos >= 2:\n",
|
||||||
|
"\n",
|
||||||
|
" # try to insert to goo as edge between\n",
|
||||||
|
" # 2 existing goos\n",
|
||||||
|
" def distance(a, b, p):\n",
|
||||||
|
" if self.goo_graph.has_edge(a[0], b[0]):\n",
|
||||||
|
" return float(\"inf\")\n",
|
||||||
|
" return numpy.linalg.norm((a[1] + b[1]) / 2 - p)\n",
|
||||||
|
"\n",
|
||||||
|
" i, j, best_dist = best_pairwise_distance(\n",
|
||||||
|
" goos,\n",
|
||||||
|
" f=lambda goo: (goo, numpy.array(goo.position)),\n",
|
||||||
|
" distance=partial(distance, p=pos),\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" if best_dist < 0.8:\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_callback():\n",
|
||||||
|
" self.draw_edge(goos[i].position, goos[j].position, stress=0)\n",
|
||||||
|
"\n",
|
||||||
|
" def insert_callack():\n",
|
||||||
|
" self.connect_goos(goos[i], goos[j])\n",
|
||||||
|
"\n",
|
||||||
|
" return True, draw_callback, insert_callack\n",
|
||||||
|
"\n",
|
||||||
|
" # try to insert the goo as brand new\n",
|
||||||
|
" # goo and connect it with 2 existing goos\n",
|
||||||
|
" f = lambda goo: (goo, (goo.position - b2d.vec2(pos)).length)\n",
|
||||||
|
"\n",
|
||||||
|
" def distance(a, b):\n",
|
||||||
|
" if not self.goo_graph.has_edge(a[0], b[0]):\n",
|
||||||
|
" return float(\"inf\")\n",
|
||||||
|
" return a[1] + b[1]\n",
|
||||||
|
"\n",
|
||||||
|
" i, j, best_dist = best_pairwise_distance(goos, f=f, distance=distance)\n",
|
||||||
|
" if best_dist < float(\"inf\"):\n",
|
||||||
|
"\n",
|
||||||
|
" def draw_callback():\n",
|
||||||
|
"\n",
|
||||||
|
" self.draw_edge(pos, goos[i].position, stress=0)\n",
|
||||||
|
" self.draw_edge(pos, goos[j].position, stress=0)\n",
|
||||||
|
" self.draw_goo(pos, angle=None)\n",
|
||||||
|
"\n",
|
||||||
|
" def insert_callack():\n",
|
||||||
|
" goo = self.insert_goo(pos=pos)\n",
|
||||||
|
" self.connect_goos(goo, goos[i])\n",
|
||||||
|
" self.connect_goos(goo, goos[j])\n",
|
||||||
|
"\n",
|
||||||
|
" return True, draw_callback, insert_callack\n",
|
||||||
|
"\n",
|
||||||
|
" return False, None, None\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_down(self, pos):\n",
|
||||||
|
" self.last_mouse_pos = pos\n",
|
||||||
|
" self.is_mouse_down = True\n",
|
||||||
|
" can_be_placed, draw_callback, insert_callback = self.query_placement(pos)\n",
|
||||||
|
" self.could_place_goo_when_mouse_was_down = can_be_placed\n",
|
||||||
|
" if can_be_placed:\n",
|
||||||
|
" if self.elapsed_time < self.insert_time_point:\n",
|
||||||
|
" return True\n",
|
||||||
|
" self.draw_callback = draw_callback\n",
|
||||||
|
" return True\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_move(self, pos):\n",
|
||||||
|
" self.last_mouse_pos = pos\n",
|
||||||
|
" if self.is_mouse_down:\n",
|
||||||
|
" can_be_placed, draw_callback, insert_callback = self.query_placement(pos)\n",
|
||||||
|
" if can_be_placed:\n",
|
||||||
|
" if self.elapsed_time < self.insert_time_point:\n",
|
||||||
|
" return True\n",
|
||||||
|
" self.draw_callback = draw_callback\n",
|
||||||
|
" return True\n",
|
||||||
|
" else:\n",
|
||||||
|
" self.draw_callback = None\n",
|
||||||
|
" return self.could_place_goo_when_mouse_was_down\n",
|
||||||
|
"\n",
|
||||||
|
" def on_mouse_up(self, pos):\n",
|
||||||
|
" self.last_mouse_pos = pos\n",
|
||||||
|
" self.is_mouse_down = False\n",
|
||||||
|
" self.draw_callback = None\n",
|
||||||
|
" can_be_placed, draw_callback, insert_callback = self.query_placement(pos)\n",
|
||||||
|
" if can_be_placed:\n",
|
||||||
|
" if self.elapsed_time < self.insert_time_point:\n",
|
||||||
|
" return True\n",
|
||||||
|
" # self.draw_callback = draw_callback\n",
|
||||||
|
" insert_callback()\n",
|
||||||
|
" self.insert_time_point = self.elapsed_time + self.insert_delay\n",
|
||||||
|
" return True\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def begin_contact(self, contact):\n",
|
||||||
|
" body_a = contact.body_a\n",
|
||||||
|
" body_b = contact.body_b\n",
|
||||||
|
" if body_b.user_data == \"goo\":\n",
|
||||||
|
" body_a, body_b = body_b, body_a\n",
|
||||||
|
"\n",
|
||||||
|
" user_data_a = body_a.user_data\n",
|
||||||
|
" user_data_b = body_b.user_data\n",
|
||||||
|
" if body_a.user_data == \"goo\":\n",
|
||||||
|
" if user_data_b == \"destroyer\":\n",
|
||||||
|
" self.goo_to_destroy.append(body_a)\n",
|
||||||
|
" elif user_data_b == \"goal\":\n",
|
||||||
|
" self.with_goal_contact[body_a] = self.elapsed_time + self.win_delay\n",
|
||||||
|
"\n",
|
||||||
|
" def end_contact(self, contact):\n",
|
||||||
|
" body_a = contact.body_a\n",
|
||||||
|
" body_b = contact.body_b\n",
|
||||||
|
" if body_b.user_data == \"goo\":\n",
|
||||||
|
" body_a, body_b = body_b, body_a\n",
|
||||||
|
"\n",
|
||||||
|
" user_data_a = body_a.user_data\n",
|
||||||
|
" user_data_b = body_b.user_data\n",
|
||||||
|
" if body_a.user_data == \"goo\":\n",
|
||||||
|
" if user_data_b == \"goal\":\n",
|
||||||
|
" if body_a in self.with_goal_contact:\n",
|
||||||
|
" del self.with_goal_contact[body_a]\n",
|
||||||
|
"\n",
|
||||||
|
" def pre_step(self, dt):\n",
|
||||||
|
"\n",
|
||||||
|
" # query if goo can be inserted\n",
|
||||||
|
" if (\n",
|
||||||
|
" self.is_mouse_down\n",
|
||||||
|
" and self.last_mouse_pos is not None\n",
|
||||||
|
" and self.draw_callback is None\n",
|
||||||
|
" ):\n",
|
||||||
|
" can_be_placed, draw_callback, insert_callback = self.query_placement(\n",
|
||||||
|
" self.last_mouse_pos\n",
|
||||||
|
" )\n",
|
||||||
|
" if can_be_placed and self.elapsed_time >= self.insert_time_point:\n",
|
||||||
|
" self.draw_callback = draw_callback\n",
|
||||||
|
"\n",
|
||||||
|
" # compute joint stress\n",
|
||||||
|
" for goo_a, goo_b, joint in self.goo_graph.edges(data=\"joint\"):\n",
|
||||||
|
" jd = joint.user_data\n",
|
||||||
|
"\n",
|
||||||
|
" # distance based stress\n",
|
||||||
|
" insert_length = jd[\"length\"]\n",
|
||||||
|
" length = (goo_a.position - goo_b.position).length\n",
|
||||||
|
"\n",
|
||||||
|
" d = length - insert_length\n",
|
||||||
|
" if d > 0:\n",
|
||||||
|
"\n",
|
||||||
|
" # reaction force based stress\n",
|
||||||
|
" rf = joint.get_reaction_force(30).length\n",
|
||||||
|
"\n",
|
||||||
|
" normalized_rf = 1.0 - math.exp(-rf * self.gamma)\n",
|
||||||
|
"\n",
|
||||||
|
" jd[\"stress\"] = normalized_rf / self.break_threshold\n",
|
||||||
|
" if normalized_rf > self.break_threshold:\n",
|
||||||
|
" self.joints_to_destroy.append((goo_a, goo_b, joint))\n",
|
||||||
|
"\n",
|
||||||
|
" else:\n",
|
||||||
|
" jd[\"stress\"] = 0\n",
|
||||||
|
"\n",
|
||||||
|
" for goo_a, goo_b, joint in self.joints_to_destroy:\n",
|
||||||
|
" self.goo_graph.remove_edge(u=goo_a, v=goo_b)\n",
|
||||||
|
" self.world.destroy_joint(joint)\n",
|
||||||
|
" self.joints_to_destroy = []\n",
|
||||||
|
"\n",
|
||||||
|
" # destroy goos\n",
|
||||||
|
" for goo in self.goo_to_destroy:\n",
|
||||||
|
" self.goo_graph.remove_node(goo)\n",
|
||||||
|
" self.world.destroy_body(goo)\n",
|
||||||
|
"\n",
|
||||||
|
" # destroy all with wrong degree\n",
|
||||||
|
" while True:\n",
|
||||||
|
" destroyed_any = False\n",
|
||||||
|
" to_remove = []\n",
|
||||||
|
" for goo in self.goo_graph.nodes:\n",
|
||||||
|
" if self.goo_graph.degree(goo) < 2:\n",
|
||||||
|
" destroyed_any = True\n",
|
||||||
|
" to_remove.append(goo)\n",
|
||||||
|
" if not destroyed_any:\n",
|
||||||
|
" break\n",
|
||||||
|
" for goo in to_remove:\n",
|
||||||
|
" self.goo_graph.remove_node(goo)\n",
|
||||||
|
" self.world.destroy_body(goo)\n",
|
||||||
|
" self.goo_to_destroy = []\n",
|
||||||
|
"\n",
|
||||||
|
" # check if we are done\n",
|
||||||
|
" for goo, finish_time in self.with_goal_contact.items():\n",
|
||||||
|
" if finish_time <= self.elapsed_time:\n",
|
||||||
|
" self.on_win(goo)\n",
|
||||||
|
"\n",
|
||||||
|
" if self.emitter is not None:\n",
|
||||||
|
" if self.emitter_stop_time is not None:\n",
|
||||||
|
" if self.elapsed_time > self.emitter_stop_time:\n",
|
||||||
|
" self.emitter.enabled = False\n",
|
||||||
|
" self.emitter_start_time = self.elapsed_time + 0.4\n",
|
||||||
|
" self.emitter_stop_time = None\n",
|
||||||
|
" p = list(self.emitter.position)\n",
|
||||||
|
" p[0] += (random.random() - 0.5) * 10.0\n",
|
||||||
|
" p[1] += (random.random() - 0.5) * 2.0\n",
|
||||||
|
" self.emitter.position = p\n",
|
||||||
|
" if self.emitter_start_time is not None:\n",
|
||||||
|
" if self.elapsed_time > self.emitter_start_time:\n",
|
||||||
|
" self.emitter.enabled = True\n",
|
||||||
|
" self.emitter_start_time = None\n",
|
||||||
|
" self.emitter_stop_time = self.elapsed_time + 0.2\n",
|
||||||
|
" self.emitter.step(dt)\n",
|
||||||
|
"\n",
|
||||||
|
" def post_debug_draw(self):\n",
|
||||||
|
"\n",
|
||||||
|
" self.level.draw(self.debug_draw)\n",
|
||||||
|
"\n",
|
||||||
|
" # draw mouse when mouse is down\n",
|
||||||
|
" if (\n",
|
||||||
|
" self.is_mouse_down\n",
|
||||||
|
" and self.last_mouse_pos is not None\n",
|
||||||
|
" and self.draw_callback is None\n",
|
||||||
|
" ):\n",
|
||||||
|
" d = (self.insert_time_point - self.elapsed_time) / self.insert_delay\n",
|
||||||
|
" if d > 0:\n",
|
||||||
|
" d = d * math.pi * 2\n",
|
||||||
|
" x = math.sin(d)\n",
|
||||||
|
" y = math.cos(d)\n",
|
||||||
|
" p = self.last_mouse_pos[0] + x, self.last_mouse_pos[1] + y\n",
|
||||||
|
" self.debug_draw.draw_segment(\n",
|
||||||
|
" p, self.last_mouse_pos, color=(1, 0, 0), line_width=0.2\n",
|
||||||
|
" )\n",
|
||||||
|
" self.debug_draw.draw_circle(\n",
|
||||||
|
" self.last_mouse_pos, 1, (1, 0, 0), line_width=0.2\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # draw the tentative placement\n",
|
||||||
|
" if self.draw_callback is not None:\n",
|
||||||
|
" self.draw_callback()\n",
|
||||||
|
"\n",
|
||||||
|
" for goo_a, goo_b, joint in self.goo_graph.edges(data=\"joint\"):\n",
|
||||||
|
" self.draw_edge(\n",
|
||||||
|
" goo_a.position, goo_b.position, stress=joint.user_data[\"stress\"]\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" for goo in self.goo_graph:\n",
|
||||||
|
" self.draw_goo(goo.position, goo.angle, body=goo)\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Controlls\n",
|
||||||
|
"* To play this game, click and drag next to the existing \"goos\"\n",
|
||||||
|
"* try to bridge the tiny gap\n",
|
||||||
|
"* Use the mouse-wheel to zoom in/out, a\n",
|
||||||
|
"* Click and drag in the empty space to translate the view."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"\n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [1000,500]\n",
|
||||||
|
"s.scale = 8\n",
|
||||||
|
"tb = b2d.testbed.run(Goo, backend=JupyterAsyncGui, gui_settings=s);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
282
content/pyodide/pyb2d/games/rocket.ipynb
Normal file
282
content/pyodide/pyb2d/games/rocket.ipynb
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "f7b8452d-61fe-4356-8084-cac603096fef",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "0bfa61e4-9817-4bea-aa66-6a660a423ae6",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"import random\n",
|
||||||
|
"import numpy\n",
|
||||||
|
"import b2d\n",
|
||||||
|
"import math\n",
|
||||||
|
"\n",
|
||||||
|
"class Rocket(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"Rocket\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(Rocket, self).__init__(gravity=(0, 0), settings=settings)\n",
|
||||||
|
"\n",
|
||||||
|
" # gravitational constant\n",
|
||||||
|
" self.gravitational_constant = 6.0\n",
|
||||||
|
"\n",
|
||||||
|
" self.planets = {}\n",
|
||||||
|
"\n",
|
||||||
|
" # home planet\n",
|
||||||
|
" home_planet = self.world.create_kinematic_body(\n",
|
||||||
|
" position=(10, 0),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=20)),\n",
|
||||||
|
" user_data=\"home_planet\",\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # target planet\n",
|
||||||
|
" target_planet = self.world.create_kinematic_body(\n",
|
||||||
|
" position=(100, 100),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=10)),\n",
|
||||||
|
" user_data=\"target_planet\",\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # black hole\n",
|
||||||
|
" black_hole = self.world.create_kinematic_body(\n",
|
||||||
|
" position=(0, 400),\n",
|
||||||
|
" fixtures=b2d.fixture_def(shape=b2d.circle_shape(radius=1)),\n",
|
||||||
|
" user_data=\"black_hole\",\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.planets = {\n",
|
||||||
|
" home_planet: dict(radius=20, density=1, color=(0, 0.2, 1)),\n",
|
||||||
|
" target_planet: dict(radius=10, density=1, color=(0.7, 0.7, 0.7)),\n",
|
||||||
|
" black_hole: dict(radius=1, density=10000, color=(0.1, 0.1, 0.1)),\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" # a tiny rocket\n",
|
||||||
|
" self.rocket = self.world.create_dynamic_body(\n",
|
||||||
|
" position=(10, 10),\n",
|
||||||
|
" fixtures=[\n",
|
||||||
|
" b2d.fixture_def(shape=b2d.polygon_shape(box=[1, 1]), density=1),\n",
|
||||||
|
" b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.polygon_shape(vertices=[(-1, 1), (0, 4), (1, 1)]),\n",
|
||||||
|
" density=1,\n",
|
||||||
|
" ),\n",
|
||||||
|
" ],\n",
|
||||||
|
" angular_damping=0.5,\n",
|
||||||
|
" linear_damping=0.2,\n",
|
||||||
|
" user_data=\"rocket\",\n",
|
||||||
|
" )\n",
|
||||||
|
" # check if the rocket is gone\n",
|
||||||
|
" self.touched_black_hole = False\n",
|
||||||
|
"\n",
|
||||||
|
" # particle system\n",
|
||||||
|
" pdef = b2d.particle_system_def(\n",
|
||||||
|
" viscous_strength=0.9,\n",
|
||||||
|
" spring_strength=0.0,\n",
|
||||||
|
" damping_strength=100.5,\n",
|
||||||
|
" pressure_strength=1.0,\n",
|
||||||
|
" color_mixing_strength=0.05,\n",
|
||||||
|
" density=0.1,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" psystem = self.world.create_particle_system(pdef)\n",
|
||||||
|
" psystem.radius = 0.1\n",
|
||||||
|
" psystem.damping = 0.5\n",
|
||||||
|
"\n",
|
||||||
|
" self.emitters = []\n",
|
||||||
|
" self.key_map = {\"w\": 0, \"a\": 1, \"d\": 2}\n",
|
||||||
|
"\n",
|
||||||
|
" angle_width = (math.pi * 2) / 16\n",
|
||||||
|
" emitter_def = b2d.RandomizedRadialEmitterDef()\n",
|
||||||
|
" emitter_def.emite_rate = 2000\n",
|
||||||
|
" emitter_def.lifetime = 1.0\n",
|
||||||
|
" emitter_def.enabled = False\n",
|
||||||
|
" emitter_def.inner_radius = 1\n",
|
||||||
|
" emitter_def.outer_radius = 1\n",
|
||||||
|
" emitter_def.velocity_magnitude = 10.0\n",
|
||||||
|
" emitter_def.start_angle = math.pi / 2 - angle_width / 2.0\n",
|
||||||
|
" emitter_def.stop_angle = math.pi / 2 + angle_width / 2.0\n",
|
||||||
|
" emitter_def.body = self.rocket\n",
|
||||||
|
"\n",
|
||||||
|
" delta = 0.2\n",
|
||||||
|
" self.emitter_local_anchors = [\n",
|
||||||
|
" (0, -delta), # main\n",
|
||||||
|
" (-delta, -0.5), # left,\n",
|
||||||
|
" (delta, -0.5), # right\n",
|
||||||
|
" ]\n",
|
||||||
|
" self.emitter_local_rot = [math.pi, math.pi / 2, -math.pi / 2] # main\n",
|
||||||
|
"\n",
|
||||||
|
" # main trust\n",
|
||||||
|
" emitter_def.emite_rate = 2000\n",
|
||||||
|
" world_anchor = self.rocket.get_world_point(self.emitter_local_anchors[0])\n",
|
||||||
|
" emitter_def.transform = b2d.Transform(\n",
|
||||||
|
" world_anchor, b2d.Rot(self.emitter_local_rot[0])\n",
|
||||||
|
" )\n",
|
||||||
|
" emitter = b2d.RandomizedRadialEmitter(psystem, emitter_def)\n",
|
||||||
|
" self.emitters.append(emitter)\n",
|
||||||
|
"\n",
|
||||||
|
" # left\n",
|
||||||
|
" emitter_def.emite_rate = 200\n",
|
||||||
|
" world_anchor = self.rocket.get_world_point(self.emitter_local_anchors[1])\n",
|
||||||
|
" emitter_def.transform = b2d.Transform(\n",
|
||||||
|
" world_anchor, b2d.Rot(self.emitter_local_rot[1])\n",
|
||||||
|
" )\n",
|
||||||
|
" emitter = b2d.RandomizedRadialEmitter(psystem, emitter_def)\n",
|
||||||
|
" self.emitters.append(emitter)\n",
|
||||||
|
"\n",
|
||||||
|
" # right\n",
|
||||||
|
" emitter_def.emite_rate = 200\n",
|
||||||
|
" world_anchor = self.rocket.get_world_point(self.emitter_local_anchors[1])\n",
|
||||||
|
" emitter_def.transform = b2d.Transform(\n",
|
||||||
|
" world_anchor, b2d.Rot(self.emitter_local_rot[1])\n",
|
||||||
|
" )\n",
|
||||||
|
" emitter = b2d.RandomizedRadialEmitter(psystem, emitter_def)\n",
|
||||||
|
" self.emitters.append(emitter)\n",
|
||||||
|
"\n",
|
||||||
|
" def pre_step(self, dt):\n",
|
||||||
|
"\n",
|
||||||
|
" # check if the rocket has died\n",
|
||||||
|
" if self.touched_black_hole:\n",
|
||||||
|
" if self.rocket is not None:\n",
|
||||||
|
" self.world.destroy_body(self.rocket)\n",
|
||||||
|
" self.rocket = None\n",
|
||||||
|
" else:\n",
|
||||||
|
" rocket_center = self.rocket.world_center\n",
|
||||||
|
" rocket_mass = self.rocket.mass\n",
|
||||||
|
" # compute gravitational forces\n",
|
||||||
|
" net_force = numpy.zeros([2])\n",
|
||||||
|
" for planet, planet_def in self.planets.items():\n",
|
||||||
|
" radius = planet_def[\"radius\"]\n",
|
||||||
|
" planet_center = planet.position\n",
|
||||||
|
" planet_mass = planet_def[\"density\"] * radius ** 2 * math.pi\n",
|
||||||
|
" delta = rocket_center - planet_center\n",
|
||||||
|
" distance = delta.normalize()\n",
|
||||||
|
" f = (\n",
|
||||||
|
" -self.gravitational_constant\n",
|
||||||
|
" * rocket_mass\n",
|
||||||
|
" * planet_mass\n",
|
||||||
|
" / (distance * distance)\n",
|
||||||
|
" )\n",
|
||||||
|
" net_force += delta * f\n",
|
||||||
|
" f = float(net_force[0]), float(net_force[1])\n",
|
||||||
|
" self.rocket.apply_force_to_center(f)\n",
|
||||||
|
"\n",
|
||||||
|
" # run the rockets engines\n",
|
||||||
|
" for emitter, local_anchor, local_rotation in zip(\n",
|
||||||
|
" self.emitters, self.emitter_local_anchors, self.emitter_local_rot\n",
|
||||||
|
" ):\n",
|
||||||
|
" world_anchor = self.rocket.get_world_point(local_anchor)\n",
|
||||||
|
" emitter.position = world_anchor\n",
|
||||||
|
" emitter.angle = self.rocket.angle + local_rotation\n",
|
||||||
|
" emitter.step(dt)\n",
|
||||||
|
"\n",
|
||||||
|
" def begin_contact(self, contact):\n",
|
||||||
|
" body_a = contact.body_a\n",
|
||||||
|
" body_b = contact.body_b\n",
|
||||||
|
" if body_b.user_data == \"rocket\":\n",
|
||||||
|
" body_a, body_b = body_b, body_a\n",
|
||||||
|
"\n",
|
||||||
|
" user_data_a = body_a.user_data\n",
|
||||||
|
" user_data_b = body_b.user_data\n",
|
||||||
|
" if body_a.user_data == \"rocket\":\n",
|
||||||
|
" if user_data_b == \"black_hole\":\n",
|
||||||
|
" self.touched_black_hole = True\n",
|
||||||
|
"\n",
|
||||||
|
" def on_keyboard_down(self, key):\n",
|
||||||
|
" if key in self.key_map:\n",
|
||||||
|
" self.emitters[self.key_map[key]].enabled = True\n",
|
||||||
|
" return True\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def on_keyboard_up(self, key):\n",
|
||||||
|
" if key in self.key_map:\n",
|
||||||
|
" self.emitters[self.key_map[key]].enabled = False\n",
|
||||||
|
" return False\n",
|
||||||
|
" return False\n",
|
||||||
|
"\n",
|
||||||
|
" def pre_debug_draw(self):\n",
|
||||||
|
" pass\n",
|
||||||
|
"\n",
|
||||||
|
" def post_debug_draw(self):\n",
|
||||||
|
" for planet, planet_def in self.planets.items():\n",
|
||||||
|
" pos = planet.position\n",
|
||||||
|
" self.debug_draw.draw_solid_circle(\n",
|
||||||
|
" pos, planet_def[\"radius\"] + 0.1, axis=None, color=planet_def[\"color\"]\n",
|
||||||
|
" )\n",
|
||||||
|
" if planet.user_data == \"black_hole\":\n",
|
||||||
|
" self.debug_draw.draw_circle(\n",
|
||||||
|
" pos, planet_def[\"radius\"] * 5, color=(1, 1, 1), line_width=0.1\n",
|
||||||
|
" )"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "357866b3-876e-421f-8d2a-77d6697551d3",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Controlls\n",
|
||||||
|
"* To play this game, use 'w','a','s','d' on your keyboard to steer the rocket\n",
|
||||||
|
"* try to land on the other planet\n",
|
||||||
|
"* avoid the black hole\n",
|
||||||
|
"* Use the mouse-wheel to zoom in/out, a\n",
|
||||||
|
"* Click and drag in the empty space to translate the view."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "7bab75b7-cec1-4348-b95d-9ffd282ded5c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [1000,1000]\n",
|
||||||
|
"s.scale = 3\n",
|
||||||
|
"tb = b2d.testbed.run(Rocket, backend=JupyterAsyncGui, gui_settings=s);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "674c57c8-b5b1-45a9-b75e-5ddc487f7d9b",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
128
content/pyodide/pyb2d/gauss_machine.ipynb
Normal file
128
content/pyodide/pyb2d/gauss_machine.ipynb
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "39a80aae-a990-4ed8-b880-3db2e7f70f16",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.2')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "9d9f8d68-0f3b-49c1-9512-e3e8344e7342",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"import random\n",
|
||||||
|
"import numpy\n",
|
||||||
|
"import b2d\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class GaussMachine(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"Gauss Machine\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(GaussMachine, self).__init__(settings=settings)\n",
|
||||||
|
"\n",
|
||||||
|
" self.box_shape = 30, 20\n",
|
||||||
|
" box_shape = self.box_shape\n",
|
||||||
|
"\n",
|
||||||
|
" # outer box\n",
|
||||||
|
" verts = numpy.array(\n",
|
||||||
|
" [(0, box_shape[1]), (0, 0), (box_shape[0], 0), (box_shape[0], box_shape[1])]\n",
|
||||||
|
" )\n",
|
||||||
|
" shape = b2d.chain_shape(vertices=numpy.flip(verts, axis=0))\n",
|
||||||
|
" box = self.world.create_static_body(position=(0, 0), shape=shape)\n",
|
||||||
|
"\n",
|
||||||
|
" # \"bins\"\n",
|
||||||
|
" bin_height = box_shape[1] / 3\n",
|
||||||
|
" bin_width = 1\n",
|
||||||
|
" for x in range(0, box_shape[0], bin_width):\n",
|
||||||
|
" box = self.world.create_static_body(\n",
|
||||||
|
" position=(0, 0), shape=b2d.two_sided_edge_shape((x, 0), (x, bin_height))\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # reflectors\n",
|
||||||
|
" ref_start_y = int(bin_height + box_shape[1] / 10.0)\n",
|
||||||
|
" ref_stop_y = int(box_shape[1] * 0.9)\n",
|
||||||
|
" for x in range(0, box_shape[0] + 1):\n",
|
||||||
|
"\n",
|
||||||
|
" for y in range(ref_start_y, ref_stop_y):\n",
|
||||||
|
" s = [0.5, 0][y % 2 == 0]\n",
|
||||||
|
" shape = b2d.circle_shape(radius=0.3)\n",
|
||||||
|
" box = self.world.create_static_body(position=(x + s, y), shape=shape)\n",
|
||||||
|
"\n",
|
||||||
|
" # particle system\n",
|
||||||
|
" pdef = b2d.particle_system_def(\n",
|
||||||
|
" viscous_strength=0.9,\n",
|
||||||
|
" spring_strength=0.0,\n",
|
||||||
|
" damping_strength=100.5,\n",
|
||||||
|
" pressure_strength=1.0,\n",
|
||||||
|
" color_mixing_strength=0.05,\n",
|
||||||
|
" density=2,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" psystem = self.world.create_particle_system(pdef)\n",
|
||||||
|
" psystem.radius = 0.1\n",
|
||||||
|
" psystem.damping = 0.5\n",
|
||||||
|
"\n",
|
||||||
|
" # linear emitter\n",
|
||||||
|
" emitter_pos = (self.box_shape[0] / 2, self.box_shape[1] + 10)\n",
|
||||||
|
" emitter_def = b2d.RandomizedLinearEmitterDef()\n",
|
||||||
|
" emitter_def.emite_rate = 400\n",
|
||||||
|
" emitter_def.lifetime = 25\n",
|
||||||
|
" emitter_def.size = (10, 1)\n",
|
||||||
|
" emitter_def.transform = b2d.Transform(emitter_pos, b2d.Rot(0))\n",
|
||||||
|
"\n",
|
||||||
|
" self.emitter = b2d.RandomizedLinearEmitter(psystem, emitter_def)\n",
|
||||||
|
"\n",
|
||||||
|
" def pre_step(self, dt):\n",
|
||||||
|
" self.emitter.step(dt)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "51e5df1b-f5e6-486a-a6c0-173597198e5d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [350,400]\n",
|
||||||
|
"s.scale = 11\n",
|
||||||
|
"tb = b2d.testbed.run(GaussMachine, backend=JupyterAsyncGui, gui_settings=s);"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
130
content/pyodide/pyb2d/newtons_cradle.ipynb
Normal file
130
content/pyodide/pyb2d/newtons_cradle.ipynb
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"id": "82ae535a-a041-40f0-8c40-e689b894b0bc",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"if \"pyodide\" in sys.modules:\n",
|
||||||
|
" import piplite\n",
|
||||||
|
" await piplite.install('pyb2d-jupyterlite-backend>=0.4.0')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"id": "7381ff66-7924-4216-b141-8f7b15ed038a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from b2d.testbed import TestbedBase\n",
|
||||||
|
"import b2d\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class NewtonsCradle(TestbedBase):\n",
|
||||||
|
"\n",
|
||||||
|
" name = \"newton's cradle\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(self, settings=None):\n",
|
||||||
|
" super(NewtonsCradle, self).__init__(settings=settings)\n",
|
||||||
|
"\n",
|
||||||
|
" # radius of the circles\n",
|
||||||
|
" r = 1.0\n",
|
||||||
|
" # length of the rope\n",
|
||||||
|
" l = 10.0\n",
|
||||||
|
" # how many balls\n",
|
||||||
|
" n = 10\n",
|
||||||
|
"\n",
|
||||||
|
" offset = (l + r, 2 * r)\n",
|
||||||
|
" dynamic_circles = []\n",
|
||||||
|
" static_bodies = []\n",
|
||||||
|
" for i in range(n):\n",
|
||||||
|
" if i + 1 == n:\n",
|
||||||
|
" position = (offset[0] + i * 2 * r + l, offset[1] + l)\n",
|
||||||
|
" else:\n",
|
||||||
|
" position = (offset[0] + i * 2 * r, offset[1])\n",
|
||||||
|
"\n",
|
||||||
|
" circle = self.world.create_dynamic_body(\n",
|
||||||
|
" position=position,\n",
|
||||||
|
" fixtures=b2d.fixture_def(\n",
|
||||||
|
" shape=b2d.circle_shape(radius=r * 0.90),\n",
|
||||||
|
" density=1.0,\n",
|
||||||
|
" restitution=1.0,\n",
|
||||||
|
" friction=0.0,\n",
|
||||||
|
" ),\n",
|
||||||
|
" linear_damping=0.01,\n",
|
||||||
|
" angular_damping=1.0,\n",
|
||||||
|
" fixed_rotation=True,\n",
|
||||||
|
" )\n",
|
||||||
|
" dynamic_circles.append(circle)\n",
|
||||||
|
"\n",
|
||||||
|
" static_body = self.world.create_static_body(\n",
|
||||||
|
" position=(offset[0] + i * 2 * r, offset[1] + l)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" self.world.create_distance_joint(\n",
|
||||||
|
" static_body,\n",
|
||||||
|
" circle,\n",
|
||||||
|
" local_anchor_a=(0, 0),\n",
|
||||||
|
" local_anchor_b=(0, 0),\n",
|
||||||
|
" max_length=l,\n",
|
||||||
|
" stiffness=0,\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" static_bodies.append(static_body)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"id": "6f694d32-8b23-40cf-91c3-0edd6abb658d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"application/vnd.jupyter.widget-view+json": {
|
||||||
|
"model_id": "b24ad88f6cfd4db19fc3145000e79635",
|
||||||
|
"version_major": 2,
|
||||||
|
"version_minor": 0
|
||||||
|
},
|
||||||
|
"text/plain": [
|
||||||
|
"Output()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from pyb2d_jupyterlite_backend.async_jupyter_gui import JupyterAsyncGui\n",
|
||||||
|
"s = JupyterAsyncGui.Settings()\n",
|
||||||
|
"s.resolution = [1000,300]\n",
|
||||||
|
"b2d.testbed.run(NewtonsCradle, backend=JupyterAsyncGui, gui_settings=s);"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
1
content/pyodide/renderers.ipynb
Normal file
1
content/pyodide/renderers.ipynb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"metadata":{"language_info":{"codemirror_mode":{"name":"python","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.8"},"kernelspec":{"name":"python","display_name":"Pyolite","language":"python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# JupyterLab Renderers","metadata":{}},{"cell_type":"markdown","source":"## FASTA","metadata":{}},{"cell_type":"code","source":"def Fasta(data=''):\n bundle = {}\n bundle['application/vnd.fasta.fasta'] = data\n bundle['text/plain'] = data\n display(bundle, raw=True)\n\nFasta(\"\"\">SEQUENCE_1\nMTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG\nLVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK\nIPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL\nMGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGLEKKTEDFAAEVAAQL\n>SEQUENCE_2\nSATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQI\nATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICMH\"\"\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## GeoJSON","metadata":{}},{"cell_type":"code","source":"def GeoJSON(data):\n bundle = {}\n bundle['application/geo+json'] = data\n bundle['text/plain'] = data\n display(bundle, raw=True)\n \nGeoJSON({\n \"type\": \"Feature\",\n \"geometry\": {\n \"type\": \"Point\",\n \"coordinates\": [125.6, 10.1]\n },\n \"properties\": {\n \"name\": \"Dinagat Islands\"\n }\n})","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}
|
721
content/python.ipynb
Normal file
721
content/python.ipynb
Normal file
|
@ -0,0 +1,721 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"attachments": {},
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"# A Python kernel backed by Pyodide\n",
|
||||||
|
"\n",
|
||||||
|
"![](https://raw.githubusercontent.com/pyodide/pyodide/master/docs/_static/img/pyodide-logo.png)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import pyodide_kernel\n",
|
||||||
|
"pyodide_kernel.__version__"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Simple code execution"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"a = 3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"b = 89\n",
|
||||||
|
"\n",
|
||||||
|
"def sq(x):\n",
|
||||||
|
" return x * x\n",
|
||||||
|
"\n",
|
||||||
|
"sq(b)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"# Redirected streams"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import sys\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Error !!\", file=sys.stderr)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Error handling"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"scrolled": true,
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"\"Hello\"\n",
|
||||||
|
"\n",
|
||||||
|
"def dummy_function():\n",
|
||||||
|
" import missing_module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"dummy_function()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Code completion"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### press `tab` to see what is available in `sys` module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from sys import "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Code inspection"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### using the question mark"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"?print"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### by pressing `shift+tab`"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print("
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Input support"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"name = await input('Enter your name: ')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"'Hello, ' + name"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Rich representation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import display, Markdown, HTML, JSON, Latex"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"## HTML"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print('Before display')\n",
|
||||||
|
"\n",
|
||||||
|
"s = '<h1>HTML Title</h1>'\n",
|
||||||
|
"display(HTML(s))\n",
|
||||||
|
"\n",
|
||||||
|
"print('After display')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Markdown"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"Markdown('''\n",
|
||||||
|
"# Title\n",
|
||||||
|
"\n",
|
||||||
|
"**in bold**\n",
|
||||||
|
"\n",
|
||||||
|
"~~Strikthrough~~\n",
|
||||||
|
"''')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Pandas DataFrame"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"from string import ascii_uppercase as letters\n",
|
||||||
|
"from IPython.display import display\n",
|
||||||
|
"\n",
|
||||||
|
"df = pd.DataFrame(np.random.randint(0, 100, size=(100, len(letters))), columns=list(letters))\n",
|
||||||
|
"df"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Show the same DataFrame "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"df"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## IPython.display module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import clear_output, display, update_display\n",
|
||||||
|
"from asyncio import sleep"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Update display"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"class Square:\n",
|
||||||
|
" color = 'PeachPuff'\n",
|
||||||
|
" def _repr_html_(self):\n",
|
||||||
|
" return '''\n",
|
||||||
|
" <div style=\"background: %s; width: 200px; height: 100px; border-radius: 10px;\">\n",
|
||||||
|
" </div>''' % self.color\n",
|
||||||
|
"square = Square()\n",
|
||||||
|
"\n",
|
||||||
|
"display(square, display_id='some-square')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"square.color = 'OliveDrab'\n",
|
||||||
|
"update_display(square, display_id='some-square')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Clear output"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print(\"hello\")\n",
|
||||||
|
"await sleep(3)\n",
|
||||||
|
"clear_output() # will flicker when replacing \"hello\" with \"goodbye\"\n",
|
||||||
|
"print(\"goodbye\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print(\"hello\")\n",
|
||||||
|
"await sleep(3)\n",
|
||||||
|
"clear_output(wait=True) # prevents flickering\n",
|
||||||
|
"print(\"goodbye\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Display classes"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import HTML\n",
|
||||||
|
"HTML('''\n",
|
||||||
|
" <div style=\"background: aliceblue; width: 200px; height: 100px; border-radius: 10px;\">\n",
|
||||||
|
" </div>''')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import Math\n",
|
||||||
|
"Math(r'F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import Latex\n",
|
||||||
|
"Latex(r\"\"\"\\begin{eqnarray}\n",
|
||||||
|
"\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\\n",
|
||||||
|
"\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n",
|
||||||
|
"\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n",
|
||||||
|
"\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \n",
|
||||||
|
"\\end{eqnarray}\"\"\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import ProgressBar\n",
|
||||||
|
"\n",
|
||||||
|
"for i in ProgressBar(10):\n",
|
||||||
|
" await sleep(0.1)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import JSON\n",
|
||||||
|
"JSON(['foo', {'bar': ('baz', None, 1.0, 2)}], metadata={}, expanded=True, root='test')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from IPython.display import GeoJSON\n",
|
||||||
|
"GeoJSON(\n",
|
||||||
|
" data={\n",
|
||||||
|
" \"type\": \"Feature\",\n",
|
||||||
|
" \"geometry\": {\n",
|
||||||
|
" \"type\": \"Point\",\n",
|
||||||
|
" \"coordinates\": [11.8, -45.04]\n",
|
||||||
|
" }\n",
|
||||||
|
" }, url_template=\"http://s3-eu-west-1.amazonaws.com/whereonmars.cartodb.net/{basemap_id}/{z}/{x}/{y}.png\",\n",
|
||||||
|
" layer_options={\n",
|
||||||
|
" \"basemap_id\": \"celestia_mars-shaded-16k_global\",\n",
|
||||||
|
" \"attribution\" : \"Celestia/praesepe\",\n",
|
||||||
|
" \"tms\": True,\n",
|
||||||
|
" \"minZoom\" : 0,\n",
|
||||||
|
" \"maxZoom\" : 5\n",
|
||||||
|
" }\n",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Network requests and JSON"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import json\n",
|
||||||
|
"from js import fetch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"res = await fetch('https://httpbin.org/get')\n",
|
||||||
|
"text = await res.text()\n",
|
||||||
|
"obj = json.loads(text) \n",
|
||||||
|
"JSON(obj)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Sympy"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from sympy import Integral, sqrt, symbols, init_printing\n",
|
||||||
|
"\n",
|
||||||
|
"init_printing()\n",
|
||||||
|
"\n",
|
||||||
|
"x = symbols('x')\n",
|
||||||
|
"\n",
|
||||||
|
"Integral(sqrt(1 / x), x)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Magics"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import os\n",
|
||||||
|
"os.listdir()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%cd /home"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%pwd"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"current_path = %pwd\n",
|
||||||
|
"print(current_path)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%writefile test.txt\n",
|
||||||
|
"\n",
|
||||||
|
"This will create a new file. \n",
|
||||||
|
"With the text that you see here."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%history"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import time"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%timeit \n",
|
||||||
|
"\n",
|
||||||
|
"time.sleep(0.1)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python (Pyodide)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "python",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.8"
|
||||||
|
},
|
||||||
|
"orig_nbformat": 4
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 4
|
||||||
|
}
|
29
content/xeus-lua/canvas.ipynb
Normal file
29
content/xeus-lua/canvas.ipynb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"orig_nbformat": 4,
|
||||||
|
"language_info": {
|
||||||
|
"file_extension": ".lua",
|
||||||
|
"mimetype": "text/x-luasrc",
|
||||||
|
"name": "lua",
|
||||||
|
"version": "14.0.0"
|
||||||
|
},
|
||||||
|
"kernelspec": {
|
||||||
|
"name": "Lua",
|
||||||
|
"display_name": "Lua",
|
||||||
|
"language": "lua"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat_minor": 4,
|
||||||
|
"nbformat": 4,
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"source": "canvas = ilua.canvas.canvas()\nilua.display.display(canvas)\ncanvas:cache()\nfor var=1,100 do\n canvas:begin_path()\n canvas:move_to(canvas:rand_coord())\n for s=1,10 do\n canvas:line_to(canvas:rand_coord())\n end\n canvas.fill_style = canvas:rand_color()\n canvas:fill()\nend\ncanvas:flush()",
|
||||||
|
"metadata": {
|
||||||
|
"trusted": true
|
||||||
|
},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
92
content/xeus-lua/game-of-life.ipynb
Normal file
92
content/xeus-lua/game-of-life.ipynb
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
{
|
||||||
|
"metadata":{
|
||||||
|
"orig_nbformat":4,
|
||||||
|
"kernelspec":{
|
||||||
|
"name":"Lua",
|
||||||
|
"display_name":"Lua",
|
||||||
|
"language":"lua"
|
||||||
|
},
|
||||||
|
"language_info":{
|
||||||
|
"file_extension":".lua",
|
||||||
|
"mimetype":"text/x-luasrc",
|
||||||
|
"name":"lua",
|
||||||
|
"version":"14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat_minor":5,
|
||||||
|
"nbformat":4,
|
||||||
|
"cells":[
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"math = require(\"math\")\n\n-- the game of life class itself\nGameOfLife = {}\nGameOfLife.__index = GameOfLife\nfunction GameOfLife:Create(grid_size)\n local this =\n {\n grid_size = grid_size or {10,10},\n grid = {}\n }\n setmetatable(this, GameOfLife)\n this.size = this.grid_size[1] * this.grid_size[2]\n for i=1,this.size do\n this.grid[i] = 0\n end\n return this\nend",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"id":"61dc1d13-5546-477d-a162-e18ec564e3ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"-- member function to initalize with some random values\nfunction GameOfLife:init_random(p)\n for i=1,self.size do\n self.grid[i] = (math.random() < p) and 1 or 0\n end\nend",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"id":"72da5a15-dd9d-4a62-bfa3-5a3ec457c5f4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"-- helper function to convert a coordinate {x,y} into a \n-- scalar offset\nfunction GameOfLife:to_offset(coord)\n return (coord[1]-1) * self.grid_size[2] + (coord[2] -1) + 1\nend\n-- helper function to access the value of the grid at a coordinate {x,y}\nfunction GameOfLife:at(coord)\n return self.grid[self:to_offset(coord)]\nend",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"id":"0b341677-64f2-4ef3-8ea4-a8e2eb275df2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"-- the function to do a step\nfunction GameOfLife:step()\n new_grid = {}\n \n for x=1,self.grid_size[1] do\n for y=1, self.grid_size[2] do\n \n local c = 0\n for xx=-1,1 do\n for yy=-1,1 do\n nx = x + xx\n ny = y + yy\n if nx >=1 and ny>=1 and nx <=self.grid_size[1] and ny <=self.grid_size[2] and not (xx==0 and yy ==0) then\n c = c + self:at({nx,ny})\n end\n end\n end\n \n local offset = self:to_offset({x,y})\n local current_state = self:at({x,y})\n \n new_grid[offset] = 0\n if current_state == 0 then\n if c == 3 then\n new_grid[offset] = 1\n end\n else\n if c==2 or c==3 then\n new_grid[offset] = 1\n else\n new_grid[offset] = 0\n end\n end\n-- \n end\n end\n self.grid = new_grid\nend",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"id":"7958dd53-006c-480d-a4ad-9f04b147fd29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"-- helper function to draw the grid as string\nfunction GameOfLife:__tostring()\n s = \"*\"\n for y=1, self.grid_size[2] do\n s = s .. \"--\"\n end\n s = s .. \"*\\n\"\n for x=1,self.grid_size[1] do\n s = s .. \"|\"\n for y=1, self.grid_size[2] do\n local state = self:at({x,y})\n if state == 0 then\n ss = \" \"\n else\n ss = \"O\"\n end\n s = s .. ss .. \" \"\n end\n s = s .. \"|\\n\"\n end\n s = s .. \"*\"\n for y=1, self.grid_size[2] do\n s = s .. \"--\"\n end\n s = s .. \"*\\n\"\n return s\nend",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"id":"884414f6-8bc9-4719-9671-ef3be310356b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type":"code",
|
||||||
|
"source":"-- initalize the game of life\ngrid_size = {20,20}\ngame_of_life = GameOfLife:Create(grid_size)\ngame_of_life:init_random(0.5)\n\n-- a tiny gui\nfunction speed_to_interval(speed)\n return 1.0 / speed\nend\n\nspeed = 0.001\n\nhbox = ilua.widgets.hbox()\n\nplay = ilua.widgets.play({interval=speed_to_interval(speed), max=1000000})\noutput = ilua.widgets.output()\nstep_label = ilua.widgets.label({value=\"Step: \"..tostring(play.value)})\nspeed_label = ilua.widgets.label({value=\"Speed: \"..tostring(speed)})\nspeed_slider = ilua.widgets.slider({min=0.001, max=0.5, step=0.01})\n\nhbox:add(play,step_label,speed_label)\n\nspeed_slider:register_observer(function(value)\n output:captured(function()\n speed = value\n play.interval = speed_to_interval(speed)\n speed_label.value = \"Speed: \" .. tostring(speed)\n end)\nend)\n\nplay:register_observer(function(value)\n if value <= 0.1 then\n game_of_life:init_random(0.24)\n end\n -- use output widget to caputre prints \n output:captured(function()\n ilua.display.clear_output(false)\n step_label.value = \"STEP \"..tostring(play.value)\n game_of_life:step()\n print(tostring(game_of_life))\n end)\nend)\nilua.display.display(hbox,speed_slider, output)",
|
||||||
|
"metadata":{
|
||||||
|
"trusted":true
|
||||||
|
},
|
||||||
|
"execution_count":null,
|
||||||
|
"outputs":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"id":"40cabf23-7eef-4501-badd-99c1a68c5ced"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
632
content/xeus-lua/widgets.ipynb
Normal file
632
content/xeus-lua/widgets.ipynb
Normal file
|
@ -0,0 +1,632 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "6d755081-7f9f-4c6a-93e5-a28c8627a0ec",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Button\n",
|
||||||
|
"======="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "be69e205-0c56-44b7-926b-5482d5300a38",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"button = ilua.widgets.button({description=\"hello\"})\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"ilua.display.display(button,output)\n",
|
||||||
|
"button:on_click(function()\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"clicked\")\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "d11b0def-5115-4369-9972-4766802c846f",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"Box Layout\n",
|
||||||
|
"=========="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "5d044224-ac2e-4722-b3fb-6d75b13ec366",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider_a = ilua.widgets.slider({min=1, max=2, step=0.1})\n",
|
||||||
|
"slider_b = ilua.widgets.slider({min=10, max=20, step=1})\n",
|
||||||
|
"hbox = ilua.widgets.hbox()\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"hbox:add(slider_a, slider_b)\n",
|
||||||
|
"ilua.display.display(hbox,output)\n",
|
||||||
|
"\n",
|
||||||
|
"slider_a:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" io.write(\"f(x) = x**2; f(\", value ,\")=\", value*value,\"\\n\")\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"slider_b:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" io.write(\"f(x) = x**3; f(\", value ,\")=\", value*value*value,\"\\n\")\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "98e79948-9aeb-4c31-a7b9-3c6bce6c026f",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Accordion\n",
|
||||||
|
"================"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "b755c37d-602a-4b46-97ee-8e044f2f2314",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"button = ilua.widgets.button({description=\"a button\"})\n",
|
||||||
|
"button:on_click(function() \n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"clicked button\")\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"slider = ilua.widgets.slider()\n",
|
||||||
|
"color_picker = ilua.widgets.color_picker()\n",
|
||||||
|
"audio = ilua.widgets.audio()\n",
|
||||||
|
"accordion = ilua.widgets.accordion()\n",
|
||||||
|
"accordion:add(slider,button,color_picker,audio)\n",
|
||||||
|
"accordion:set_title(1,\"the slider\")\n",
|
||||||
|
"accordion:set_title(2,\"the button\")\n",
|
||||||
|
"accordion:set_title(3,\"the color_picker\")\n",
|
||||||
|
"accordion:set_title(4,\"the audio\")\n",
|
||||||
|
"ilua.display.display(accordion, output)\n",
|
||||||
|
"\n",
|
||||||
|
"slider:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"slider value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"color_picker:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"color_picker value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "097d19f7-a0c9-48a9-8eff-6e3e06780c88",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"Dropdown\n",
|
||||||
|
"========="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "95e12c50-4e77-457c-b2c2-6d20421a3bea",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"labels = {\"aaa\", \"bb\",\"cc\"}\n",
|
||||||
|
"dropdown = ilua.widgets.dropdown({_options_labels= labels})\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"dropdown:register_observer(function(index)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(labels[index])\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(dropdown, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "ca362331-bd0c-4203-9a6f-dc937d309297",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Html\n",
|
||||||
|
"======="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "abc66753-53ba-4361-96a6-48cd9460c8e3",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"src = [[\n",
|
||||||
|
"<!DOCTYPE html>\n",
|
||||||
|
"<html>\n",
|
||||||
|
" <head>\n",
|
||||||
|
" </head>\n",
|
||||||
|
" <body>\n",
|
||||||
|
" <h1>My First Page</h1>\n",
|
||||||
|
" <p>This is my first page.</p>\n",
|
||||||
|
" <h2>A secondary header.</h2>\n",
|
||||||
|
" <p>Some more text.</p>\n",
|
||||||
|
" </body>\n",
|
||||||
|
"</html>\n",
|
||||||
|
"]]\n",
|
||||||
|
"html = ilua.widgets.html({value=src})\n",
|
||||||
|
"ilua.display.display(html)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "e8eeacfe-350a-4ecb-81a9-c8091af3c22e",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"numeral\n",
|
||||||
|
"========"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "9c177cfe-2613-43a3-a217-d93bc257420e",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"numeral = ilua.widgets.numeral()\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"numeral:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"ilua.display.display(numeral, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "9fede355-2e4f-48c9-b39b-1886e060ce8b",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"password\n",
|
||||||
|
"========"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "455996cf-9b63-4d50-869a-0f479ab3daf4",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"password = ilua.widgets.password()\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"password:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(password, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "6306ce8e-37d3-4dbc-a8cf-955b2dfe684c",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"play\n",
|
||||||
|
"====="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "986147ab-c9de-4ad9-b8be-f65260dd815d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"play = ilua.widgets.play({interval=1000})\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"play:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(play, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "4e03ccf2-3a10-40d6-8273-168a91f3d9a7",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"progress\n",
|
||||||
|
"========="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "a4f194ee-0995-44f3-8636-b629bd5b65ba",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"progress = ilua.widgets.progress({min=10, max=20})\n",
|
||||||
|
"play = ilua.widgets.play({min=10, max=20, interval=100})\n",
|
||||||
|
"play:register_observer(function(value)\n",
|
||||||
|
" progress.value = value\n",
|
||||||
|
"end)\n",
|
||||||
|
"ilua.display.display(play, progress)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "39714034-99f4-4f36-b50f-33aa3f71d2a6",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Selection Slider\n",
|
||||||
|
"================="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "7f6aab9e-b3ce-4df9-83a6-94eb725aceb0",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"labels = {\"aaa\", \"bb\",\"cc\"}\n",
|
||||||
|
"selectionslider = ilua.widgets.selectionslider({_options_labels = labels})\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"selectionslider:register_observer(function(index)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(labels[index])\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(selectionslider, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "45d72396-3fcc-421e-865e-487d93b333b8",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Tab\n",
|
||||||
|
"======"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "6d0684e8-62a2-4483-995a-70d7cc2783ac",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"slider_a = ilua.widgets.slider()\n",
|
||||||
|
"slider_b = ilua.widgets.slider()\n",
|
||||||
|
"\n",
|
||||||
|
"titles = {\"aaa\", \"bb\",\"cc\"}\n",
|
||||||
|
"tab = ilua.widgets.tab({_titles = titles})\n",
|
||||||
|
"tab:add(slider_a,slider_b)\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"\n",
|
||||||
|
"tab:register_observer(function(index)\n",
|
||||||
|
" -- use output widget to caputre prints \n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(titles[index])\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(tab,output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "7f9f85de-a5b8-4e60-9eff-33b25d819ec9",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Text\n",
|
||||||
|
"====="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "893e92ad-eff2-4adb-ba82-71a9ed2cfe9e",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"text = ilua.widgets.text()\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"text:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"text:on_submit(function()\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"on_submit\")\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(text, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "94572d62-12ea-4026-a531-d0e7bc5b20b9",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"TextArea\n",
|
||||||
|
"========="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "1e76b56f-f087-49f8-a50e-eb794060c63c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"textarea = ilua.widgets.textarea({continuous_update=false})\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"textarea:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"ilua.display.display(textarea, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "68011d67-ac8c-43ff-bae9-4caf95273f98",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Toggle Button\n",
|
||||||
|
"========="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "cf780275-b2de-48d4-bb2e-3f38e8c45bcd",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"togglebutton = ilua.widgets.togglebutton({\n",
|
||||||
|
" icon=\"plus\",\n",
|
||||||
|
" button_style=\"\"\n",
|
||||||
|
"})\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"togglebutton:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(togglebutton, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "1bc5c504-cf9c-432f-a91c-2497910d787b",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"ToggleButtons\n",
|
||||||
|
"========="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "f764f285-d71f-4c93-92b4-923484846b0c",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"togglebuttons = ilua.widgets.togglebuttons()\n",
|
||||||
|
"togglebuttons._options_labels = {\"1\", \"2\",\"3\"}\n",
|
||||||
|
"output = ilua.widgets.output()\n",
|
||||||
|
"togglebuttons:register_observer(function(value)\n",
|
||||||
|
" output:captured(function()\n",
|
||||||
|
" print(\"value\", value)\n",
|
||||||
|
" end)\n",
|
||||||
|
"end)\n",
|
||||||
|
"\n",
|
||||||
|
"ilua.display.display(togglebuttons, output)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "55447db2-bab0-4282-9a89-f6b9f8fd9e30",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Image\n",
|
||||||
|
"========"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d21c5e4b-1d27-44e9-9966-0da4ef55f651",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"io = require(\"io\")\n",
|
||||||
|
"file = io.open(\"marie.png\", \"r\")\n",
|
||||||
|
"content = file:read(\"*all\")\n",
|
||||||
|
"io.close(file)\n",
|
||||||
|
"\n",
|
||||||
|
"image = ilua.widgets.image()\n",
|
||||||
|
"image.value = content\n",
|
||||||
|
"ilua.display.display(image)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "ee4e079c-0101-49a9-94f6-2d7e73ad3f59",
|
||||||
|
"metadata": {
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"Video\n",
|
||||||
|
"========"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "654c050a-3cff-48d2-b7a1-d8f6acfe042a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"io = require(\"io\")\n",
|
||||||
|
"file = io.open(\"Big.Buck.Bunny.mp4\", \"r\")\n",
|
||||||
|
"content = file:read(\"*all\")\n",
|
||||||
|
"io.close(file)\n",
|
||||||
|
"\n",
|
||||||
|
"video = ilua.widgets.video({loop=false})\n",
|
||||||
|
"video.value = content\n",
|
||||||
|
"ilua.display.display(video)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "829cf76c-238d-456f-a5b9-51f3a526f45c",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Audio\n",
|
||||||
|
"======"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "43922e68-ee53-40bd-bf2c-8dcc810bdb6a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"io = require(\"io\")\n",
|
||||||
|
"file = io.open(\"hehe.flac\", \"r\")\n",
|
||||||
|
"content = file:read(\"*all\")\n",
|
||||||
|
"io.close(file)\n",
|
||||||
|
"\n",
|
||||||
|
"audio = ilua.widgets.audio({loop=false})\n",
|
||||||
|
"audio.value = content\n",
|
||||||
|
"ilua.display.display(audio)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "2aee848b-a3e6-4ce3-9d2d-8650871bb225",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Valid\n",
|
||||||
|
"======"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "ef2ae714-2077-4767-9c24-af821fbc2c9d",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"valid = ilua.widgets.valid()\n",
|
||||||
|
"valid.value = false\n",
|
||||||
|
"ilua.display.display(valid)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "96b64ffe-ac69-4b0e-9299-0a54842a77c1",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Link Widgets\n",
|
||||||
|
"============"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "191675ca-c53e-4c83-a0cf-8dcd78b02fae",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider = ilua.widgets.slider()\n",
|
||||||
|
"numeral = ilua.widgets.numeral()\n",
|
||||||
|
"\n",
|
||||||
|
"link = ilua.widgets.link(slider, \"value\", numeral, \"value\")\n",
|
||||||
|
"ilua.display.display(link, slider, numeral)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "3d54b0cc-7f2f-4ad7-92a8-9f61abe989f9",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Directional Link\n",
|
||||||
|
"==================="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "21499154-6da9-4a4a-a6ce-7637916d26c6",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"slider = ilua.widgets.slider()\n",
|
||||||
|
"numeral = ilua.widgets.numeral()\n",
|
||||||
|
"\n",
|
||||||
|
"link = ilua.widgets.directional_link(slider, \"value\", numeral, \"value\")\n",
|
||||||
|
"ilua.display.display(link, slider, numeral)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Lua 0.2 (XLua)",
|
||||||
|
"language": "lua",
|
||||||
|
"name": "xlua"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"file_extension": ".lua",
|
||||||
|
"mimetype": "text/x-luasrc",
|
||||||
|
"name": "lua",
|
||||||
|
"version": "14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
392
content/xeus-sqlite/simple-operations.ipynb
Normal file
392
content/xeus-sqlite/simple-operations.ipynb
Normal file
File diff suppressed because one or more lines are too long
11
repl/jupyter-lite.json
Normal file
11
repl/jupyter-lite.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"jupyter-lite-schema-version": 0,
|
||||||
|
"jupyter-config-data": {
|
||||||
|
"disabledExtensions": [
|
||||||
|
"@jupyterlab/drawio-extension",
|
||||||
|
"jupyterlab-kernel-spy",
|
||||||
|
"jupyterlab-tour"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
requirements.txt
Normal file
46
requirements.txt
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Core modules (mandatory)
|
||||||
|
jupyterlite-core==0.1.0
|
||||||
|
jupyterlab~=3.5.1
|
||||||
|
|
||||||
|
# Python kernel (optional)
|
||||||
|
jupyterlite-pyodide-kernel==0.0.6
|
||||||
|
|
||||||
|
# JavaScript kernel (optional)
|
||||||
|
jupyterlite-javascript-kernel==0.1.0b21
|
||||||
|
|
||||||
|
# Language support (optional)
|
||||||
|
jupyterlab-language-pack-fr-FR
|
||||||
|
jupyterlab-language-pack-zh-CN
|
||||||
|
|
||||||
|
# SQLite kernel (optional)
|
||||||
|
jupyterlite-xeus-sqlite==0.2.1
|
||||||
|
# P5 kernel (optional)
|
||||||
|
jupyterlite-p5-kernel==0.1.0
|
||||||
|
# Lua kernel (optional)
|
||||||
|
jupyterlite-xeus-lua==0.3.1
|
||||||
|
|
||||||
|
# JupyterLab: Fasta file renderer (optional)
|
||||||
|
jupyterlab-fasta>=3,<4
|
||||||
|
# JupyterLab: Geojson file renderer (optional)
|
||||||
|
jupyterlab-geojson>=3,<4
|
||||||
|
# JupyterLab: guided tour (optional)
|
||||||
|
jupyterlab-tour
|
||||||
|
# JupyterLab: dark theme
|
||||||
|
jupyterlab-night
|
||||||
|
# JupyterLab: Miami nights theme (optional)
|
||||||
|
jupyterlab_miami_nights
|
||||||
|
|
||||||
|
# Python: ipywidget library for Jupyter notebooks (optional)
|
||||||
|
ipywidgets>=8.0.0,<9
|
||||||
|
# Python: ipyevents library for Jupyter notebooks (optional)
|
||||||
|
ipyevents>=2.0.1
|
||||||
|
# Python: interative Matplotlib library for Jupyter notebooks (optional)
|
||||||
|
ipympl>=0.8.2
|
||||||
|
# Python: ipycanvas library for Jupyter notebooks (optional)
|
||||||
|
ipycanvas>=0.9.1
|
||||||
|
# Python: ipyleaflet library for Jupyter notebooks (optional)
|
||||||
|
ipyleaflet
|
||||||
|
|
||||||
|
# Python: plotting libraries (optional)
|
||||||
|
plotly>=5,<6
|
||||||
|
bqplot
|
Loading…
Reference in New Issue
Block a user