add config file for pre-commit (#235)

* add config file

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add isort

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Peter W
2022-05-05 15:12:25 -05:00
committed by GitHub
parent d89e8fbb6d
commit 6f6efa4525
11 changed files with 458 additions and 201 deletions

View File

@@ -1,4 +1,11 @@
# This is the configuration for pre-commit, a local framework for managing pre-commit hooks default_stages: [commit]
# Check out the docs at: https://pre-commit.com/ repos:
- repo: https://github.com/psf/black
repos: [] rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 5.10.1
hooks:
- id: isort
name: isort (python)

View File

@@ -1,18 +1,23 @@
import random import random
import sys import sys
from js import document, DOMParser, setInterval from js import DOMParser, document, setInterval
from pyodide import create_proxy from pyodide import create_proxy
from pyodide.http import open_url from pyodide.http import open_url
class Antigravity():
url = './antigravity.svg' class Antigravity:
url = "./antigravity.svg"
def __init__(self, target=None, interval=10, append=True, fly=False): def __init__(self, target=None, interval=10, append=True, fly=False):
target = target or sys.stdout._out target = target or sys.stdout._out
self.target = document.getElementById(target) if isinstance(target, str) else target self.target = (
doc = DOMParser.new().parseFromString(open_url(self.url).read(), "image/svg+xml") document.getElementById(target) if isinstance(target, str) else target
)
doc = DOMParser.new().parseFromString(
open_url(self.url).read(), "image/svg+xml"
)
self.node = doc.documentElement self.node = doc.documentElement
if append: if append:
self.target.append(self.node) self.target.append(self.node)
@@ -27,13 +32,14 @@ class Antigravity():
setInterval(create_proxy(self.move), self.interval) setInterval(create_proxy(self.move), self.interval)
def move(self): def move(self):
char = self.node.getElementsByTagName('g')[1] char = self.node.getElementsByTagName("g")[1]
char.setAttribute('transform', f'translate({self.xoffset}, {-self.yoffset})') char.setAttribute("transform", f"translate({self.xoffset}, {-self.yoffset})")
self.xoffset += random.normalvariate(0, 1)/20 self.xoffset += random.normalvariate(0, 1) / 20
if self.yoffset < 50: if self.yoffset < 50:
self.yoffset += 0.1 self.yoffset += 0.1
else: else:
self.yoffset += random.normalvariate(0, 1)/20 self.yoffset += random.normalvariate(0, 1) / 20
_auto = Antigravity(append=True) _auto = Antigravity(append=True)
fly = _auto.fly fly = _auto.fly

View File

@@ -1,21 +1,30 @@
from typing import Tuple from typing import Tuple
import numpy as np import numpy as np
from numpy.polynomial import Polynomial from numpy.polynomial import Polynomial
def mandelbrot(width: int, height: int, *,
x: float = -0.5, y: float = 0, zoom: int = 1, max_iterations: int = 100) -> np.array: def mandelbrot(
width: int,
height: int,
*,
x: float = -0.5,
y: float = 0,
zoom: int = 1,
max_iterations: int = 100
) -> np.array:
""" """
From https://www.learnpythonwithrune.org/numpy-compute-mandelbrot-set-by-vectorization/. From https://www.learnpythonwithrune.org/numpy-compute-mandelbrot-set-by-vectorization/.
""" """
# To make navigation easier we calculate these values # To make navigation easier we calculate these values
x_width, y_height = 1.5, 1.5*height/width x_width, y_height = 1.5, 1.5 * height / width
x_from, x_to = x - x_width/zoom, x + x_width/zoom x_from, x_to = x - x_width / zoom, x + x_width / zoom
y_from, y_to = y - y_height/zoom, y + y_height/zoom y_from, y_to = y - y_height / zoom, y + y_height / zoom
# Here the actual algorithm starts # Here the actual algorithm starts
x = np.linspace(x_from, x_to, width).reshape((1, width)) x = np.linspace(x_from, x_to, width).reshape((1, width))
y = np.linspace(y_from, y_to, height).reshape((height, 1)) y = np.linspace(y_from, y_to, height).reshape((height, 1))
c = x + 1j*y c = x + 1j * y
# Initialize z to all zero # Initialize z to all zero
z = np.zeros(c.shape, dtype=np.complex128) z = np.zeros(c.shape, dtype=np.complex128)
@@ -26,27 +35,38 @@ def mandelbrot(width: int, height: int, *,
# To keep track on which points did not converge so far # To keep track on which points did not converge so far
m = np.full(c.shape, True, dtype=bool) m = np.full(c.shape, True, dtype=bool)
for i in range(max_iterations): for i in range(max_iterations):
z[m] = z[m]**2 + c[m] z[m] = z[m] ** 2 + c[m]
diverged = np.greater(np.abs(z), 2, out=np.full(c.shape, False), where=m) # Find diverging diverged = np.greater(
np.abs(z), 2, out=np.full(c.shape, False), where=m
) # Find diverging
div_time[diverged] = i # set the value of the diverged iteration number div_time[diverged] = i # set the value of the diverged iteration number
m[np.abs(z) > 2] = False # to remember which have diverged m[np.abs(z) > 2] = False # to remember which have diverged
return div_time return div_time
def julia(width: int, height: int, *,
c: complex = -0.4 + 0.6j, x: float = 0, y: float = 0, zoom: int = 1, max_iterations: int = 100) -> np.array: def julia(
width: int,
height: int,
*,
c: complex = -0.4 + 0.6j,
x: float = 0,
y: float = 0,
zoom: int = 1,
max_iterations: int = 100
) -> np.array:
""" """
From https://www.learnpythonwithrune.org/numpy-calculate-the-julia-set-with-vectorization/. From https://www.learnpythonwithrune.org/numpy-calculate-the-julia-set-with-vectorization/.
""" """
# To make navigation easier we calculate these values # To make navigation easier we calculate these values
x_width, y_height = 1.5, 1.5*height/width x_width, y_height = 1.5, 1.5 * height / width
x_from, x_to = x - x_width/zoom, x + x_width/zoom x_from, x_to = x - x_width / zoom, x + x_width / zoom
y_from, y_to = y - y_height/zoom, y + y_height/zoom y_from, y_to = y - y_height / zoom, y + y_height / zoom
# Here the actual algorithm starts # Here the actual algorithm starts
x = np.linspace(x_from, x_to, width).reshape((1, width)) x = np.linspace(x_from, x_to, width).reshape((1, width))
y = np.linspace(y_from, y_to, height).reshape((height, 1)) y = np.linspace(y_from, y_to, height).reshape((height, 1))
z = x + 1j*y z = x + 1j * y
# Initialize z to all zero # Initialize z to all zero
c = np.full(z.shape, c) c = np.full(z.shape, c)
@@ -57,16 +77,26 @@ def julia(width: int, height: int, *,
# To keep track on which points did not converge so far # To keep track on which points did not converge so far
m = np.full(c.shape, True, dtype=bool) m = np.full(c.shape, True, dtype=bool)
for i in range(max_iterations): for i in range(max_iterations):
z[m] = z[m]**2 + c[m] z[m] = z[m] ** 2 + c[m]
m[np.abs(z) > 2] = False m[np.abs(z) > 2] = False
div_time[m] = i div_time[m] = i
return div_time return div_time
Range = Tuple[float, float] Range = Tuple[float, float]
def newton(width: int, height: int, *,
p: Polynomial, a: complex, xr: Range = (-2.5, 1), yr: Range = (-1, 1), max_iterations: int = 100) -> (np.array, np.array): def newton(
width: int,
height: int,
*,
p: Polynomial,
a: complex,
xr: Range = (-2.5, 1),
yr: Range = (-1, 1),
max_iterations: int = 100
) -> (np.array, np.array):
""" """ """ """
# To make navigation easier we calculate these values # To make navigation easier we calculate these values
x_from, x_to = xr x_from, x_to = xr
@@ -75,7 +105,7 @@ def newton(width: int, height: int, *,
# Here the actual algorithm starts # Here the actual algorithm starts
x = np.linspace(x_from, x_to, width).reshape((1, width)) x = np.linspace(x_from, x_to, width).reshape((1, width))
y = np.linspace(y_from, y_to, height).reshape((height, 1)) y = np.linspace(y_from, y_to, height).reshape((height, 1))
z = x + 1j*y z = x + 1j * y
# Compute the derivative # Compute the derivative
dp = p.deriv() dp = p.deriv()
@@ -97,10 +127,12 @@ def newton(width: int, height: int, *,
r = np.full(a.shape, 0, dtype=int) r = np.full(a.shape, 0, dtype=int)
for i in range(max_iterations): for i in range(max_iterations):
z[m] = z[m] - a[m]*p(z[m])/dp(z[m]) z[m] = z[m] - a[m] * p(z[m]) / dp(z[m])
for j, root in enumerate(roots): for j, root in enumerate(roots):
converged = (np.abs(z.real - root.real) < epsilon) & (np.abs(z.imag - root.imag) < epsilon) converged = (np.abs(z.real - root.real) < epsilon) & (
np.abs(z.imag - root.imag) < epsilon
)
m[converged] = False m[converged] = False
r[converged] = j + 1 r[converged] = j + 1

View File

@@ -1,68 +1,263 @@
import numpy as np import numpy as np
Magma256 = np.array([ Magma256 = np.array(
[0x00, 0x00, 0x03], [0x00, 0x00, 0x04], [0x00, 0x00, 0x06], [0x01, 0x00, 0x07], [
[0x01, 0x01, 0x09], [0x01, 0x01, 0x0b], [0x02, 0x02, 0x0d], [0x02, 0x02, 0x0f], [0x00, 0x00, 0x03],
[0x03, 0x03, 0x11], [0x04, 0x03, 0x13], [0x04, 0x04, 0x15], [0x05, 0x04, 0x17], [0x00, 0x00, 0x04],
[0x06, 0x05, 0x19], [0x07, 0x05, 0x1b], [0x08, 0x06, 0x1d], [0x09, 0x07, 0x1f], [0x00, 0x00, 0x06],
[0x0a, 0x07, 0x22], [0x0b, 0x08, 0x24], [0x0c, 0x09, 0x26], [0x0d, 0x0a, 0x28], [0x01, 0x00, 0x07],
[0x0e, 0x0a, 0x2a], [0x0f, 0x0b, 0x2c], [0x10, 0x0c, 0x2f], [0x11, 0x0c, 0x31], [0x01, 0x01, 0x09],
[0x12, 0x0d, 0x33], [0x14, 0x0d, 0x35], [0x15, 0x0e, 0x38], [0x16, 0x0e, 0x3a], [0x01, 0x01, 0x0B],
[0x17, 0x0f, 0x3c], [0x18, 0x0f, 0x3f], [0x1a, 0x10, 0x41], [0x1b, 0x10, 0x44], [0x02, 0x02, 0x0D],
[0x1c, 0x10, 0x46], [0x1e, 0x10, 0x49], [0x1f, 0x11, 0x4b], [0x20, 0x11, 0x4d], [0x02, 0x02, 0x0F],
[0x22, 0x11, 0x50], [0x23, 0x11, 0x52], [0x25, 0x11, 0x55], [0x26, 0x11, 0x57], [0x03, 0x03, 0x11],
[0x28, 0x11, 0x59], [0x2a, 0x11, 0x5c], [0x2b, 0x11, 0x5e], [0x2d, 0x10, 0x60], [0x04, 0x03, 0x13],
[0x2f, 0x10, 0x62], [0x30, 0x10, 0x65], [0x32, 0x10, 0x67], [0x34, 0x10, 0x68], [0x04, 0x04, 0x15],
[0x35, 0x0f, 0x6a], [0x37, 0x0f, 0x6c], [0x39, 0x0f, 0x6e], [0x3b, 0x0f, 0x6f], [0x05, 0x04, 0x17],
[0x3c, 0x0f, 0x71], [0x3e, 0x0f, 0x72], [0x40, 0x0f, 0x73], [0x42, 0x0f, 0x74], [0x06, 0x05, 0x19],
[0x43, 0x0f, 0x75], [0x45, 0x0f, 0x76], [0x47, 0x0f, 0x77], [0x48, 0x10, 0x78], [0x07, 0x05, 0x1B],
[0x4a, 0x10, 0x79], [0x4b, 0x10, 0x79], [0x4d, 0x11, 0x7a], [0x4f, 0x11, 0x7b], [0x08, 0x06, 0x1D],
[0x50, 0x12, 0x7b], [0x52, 0x12, 0x7c], [0x53, 0x13, 0x7c], [0x55, 0x13, 0x7d], [0x09, 0x07, 0x1F],
[0x57, 0x14, 0x7d], [0x58, 0x15, 0x7e], [0x5a, 0x15, 0x7e], [0x5b, 0x16, 0x7e], [0x0A, 0x07, 0x22],
[0x5d, 0x17, 0x7e], [0x5e, 0x17, 0x7f], [0x60, 0x18, 0x7f], [0x61, 0x18, 0x7f], [0x0B, 0x08, 0x24],
[0x63, 0x19, 0x7f], [0x65, 0x1a, 0x80], [0x66, 0x1a, 0x80], [0x68, 0x1b, 0x80], [0x0C, 0x09, 0x26],
[0x69, 0x1c, 0x80], [0x6b, 0x1c, 0x80], [0x6c, 0x1d, 0x80], [0x6e, 0x1e, 0x81], [0x0D, 0x0A, 0x28],
[0x6f, 0x1e, 0x81], [0x71, 0x1f, 0x81], [0x73, 0x1f, 0x81], [0x74, 0x20, 0x81], [0x0E, 0x0A, 0x2A],
[0x76, 0x21, 0x81], [0x77, 0x21, 0x81], [0x79, 0x22, 0x81], [0x7a, 0x22, 0x81], [0x0F, 0x0B, 0x2C],
[0x7c, 0x23, 0x81], [0x7e, 0x24, 0x81], [0x7f, 0x24, 0x81], [0x81, 0x25, 0x81], [0x10, 0x0C, 0x2F],
[0x82, 0x25, 0x81], [0x84, 0x26, 0x81], [0x85, 0x26, 0x81], [0x87, 0x27, 0x81], [0x11, 0x0C, 0x31],
[0x89, 0x28, 0x81], [0x8a, 0x28, 0x81], [0x8c, 0x29, 0x80], [0x8d, 0x29, 0x80], [0x12, 0x0D, 0x33],
[0x8f, 0x2a, 0x80], [0x91, 0x2a, 0x80], [0x92, 0x2b, 0x80], [0x94, 0x2b, 0x80], [0x14, 0x0D, 0x35],
[0x95, 0x2c, 0x80], [0x97, 0x2c, 0x7f], [0x99, 0x2d, 0x7f], [0x9a, 0x2d, 0x7f], [0x15, 0x0E, 0x38],
[0x9c, 0x2e, 0x7f], [0x9e, 0x2e, 0x7e], [0x9f, 0x2f, 0x7e], [0xa1, 0x2f, 0x7e], [0x16, 0x0E, 0x3A],
[0xa3, 0x30, 0x7e], [0xa4, 0x30, 0x7d], [0xa6, 0x31, 0x7d], [0xa7, 0x31, 0x7d], [0x17, 0x0F, 0x3C],
[0xa9, 0x32, 0x7c], [0xab, 0x33, 0x7c], [0xac, 0x33, 0x7b], [0xae, 0x34, 0x7b], [0x18, 0x0F, 0x3F],
[0xb0, 0x34, 0x7b], [0xb1, 0x35, 0x7a], [0xb3, 0x35, 0x7a], [0xb5, 0x36, 0x79], [0x1A, 0x10, 0x41],
[0xb6, 0x36, 0x79], [0xb8, 0x37, 0x78], [0xb9, 0x37, 0x78], [0xbb, 0x38, 0x77], [0x1B, 0x10, 0x44],
[0xbd, 0x39, 0x77], [0xbe, 0x39, 0x76], [0xc0, 0x3a, 0x75], [0xc2, 0x3a, 0x75], [0x1C, 0x10, 0x46],
[0xc3, 0x3b, 0x74], [0xc5, 0x3c, 0x74], [0xc6, 0x3c, 0x73], [0xc8, 0x3d, 0x72], [0x1E, 0x10, 0x49],
[0xca, 0x3e, 0x72], [0xcb, 0x3e, 0x71], [0xcd, 0x3f, 0x70], [0xce, 0x40, 0x70], [0x1F, 0x11, 0x4B],
[0xd0, 0x41, 0x6f], [0xd1, 0x42, 0x6e], [0xd3, 0x42, 0x6d], [0xd4, 0x43, 0x6d], [0x20, 0x11, 0x4D],
[0xd6, 0x44, 0x6c], [0xd7, 0x45, 0x6b], [0xd9, 0x46, 0x6a], [0xda, 0x47, 0x69], [0x22, 0x11, 0x50],
[0xdc, 0x48, 0x69], [0xdd, 0x49, 0x68], [0xde, 0x4a, 0x67], [0xe0, 0x4b, 0x66], [0x23, 0x11, 0x52],
[0xe1, 0x4c, 0x66], [0xe2, 0x4d, 0x65], [0xe4, 0x4e, 0x64], [0xe5, 0x50, 0x63], [0x25, 0x11, 0x55],
[0xe6, 0x51, 0x62], [0xe7, 0x52, 0x62], [0xe8, 0x54, 0x61], [0xea, 0x55, 0x60], [0x26, 0x11, 0x57],
[0xeb, 0x56, 0x60], [0xec, 0x58, 0x5f], [0xed, 0x59, 0x5f], [0xee, 0x5b, 0x5e], [0x28, 0x11, 0x59],
[0xee, 0x5d, 0x5d], [0xef, 0x5e, 0x5d], [0xf0, 0x60, 0x5d], [0xf1, 0x61, 0x5c], [0x2A, 0x11, 0x5C],
[0xf2, 0x63, 0x5c], [0xf3, 0x65, 0x5c], [0xf3, 0x67, 0x5b], [0xf4, 0x68, 0x5b], [0x2B, 0x11, 0x5E],
[0xf5, 0x6a, 0x5b], [0xf5, 0x6c, 0x5b], [0xf6, 0x6e, 0x5b], [0xf6, 0x70, 0x5b], [0x2D, 0x10, 0x60],
[0xf7, 0x71, 0x5b], [0xf7, 0x73, 0x5c], [0xf8, 0x75, 0x5c], [0xf8, 0x77, 0x5c], [0x2F, 0x10, 0x62],
[0xf9, 0x79, 0x5c], [0xf9, 0x7b, 0x5d], [0xf9, 0x7d, 0x5d], [0xfa, 0x7f, 0x5e], [0x30, 0x10, 0x65],
[0xfa, 0x80, 0x5e], [0xfa, 0x82, 0x5f], [0xfb, 0x84, 0x60], [0xfb, 0x86, 0x60], [0x32, 0x10, 0x67],
[0xfb, 0x88, 0x61], [0xfb, 0x8a, 0x62], [0xfc, 0x8c, 0x63], [0xfc, 0x8e, 0x63], [0x34, 0x10, 0x68],
[0xfc, 0x90, 0x64], [0xfc, 0x92, 0x65], [0xfc, 0x93, 0x66], [0xfd, 0x95, 0x67], [0x35, 0x0F, 0x6A],
[0xfd, 0x97, 0x68], [0xfd, 0x99, 0x69], [0xfd, 0x9b, 0x6a], [0xfd, 0x9d, 0x6b], [0x37, 0x0F, 0x6C],
[0xfd, 0x9f, 0x6c], [0xfd, 0xa1, 0x6e], [0xfd, 0xa2, 0x6f], [0xfd, 0xa4, 0x70], [0x39, 0x0F, 0x6E],
[0xfe, 0xa6, 0x71], [0xfe, 0xa8, 0x73], [0xfe, 0xaa, 0x74], [0xfe, 0xac, 0x75], [0x3B, 0x0F, 0x6F],
[0xfe, 0xae, 0x76], [0xfe, 0xaf, 0x78], [0xfe, 0xb1, 0x79], [0xfe, 0xb3, 0x7b], [0x3C, 0x0F, 0x71],
[0xfe, 0xb5, 0x7c], [0xfe, 0xb7, 0x7d], [0xfe, 0xb9, 0x7f], [0xfe, 0xbb, 0x80], [0x3E, 0x0F, 0x72],
[0xfe, 0xbc, 0x82], [0xfe, 0xbe, 0x83], [0xfe, 0xc0, 0x85], [0xfe, 0xc2, 0x86], [0x40, 0x0F, 0x73],
[0xfe, 0xc4, 0x88], [0xfe, 0xc6, 0x89], [0xfe, 0xc7, 0x8b], [0xfe, 0xc9, 0x8d], [0x42, 0x0F, 0x74],
[0xfe, 0xcb, 0x8e], [0xfd, 0xcd, 0x90], [0xfd, 0xcf, 0x92], [0xfd, 0xd1, 0x93], [0x43, 0x0F, 0x75],
[0xfd, 0xd2, 0x95], [0xfd, 0xd4, 0x97], [0xfd, 0xd6, 0x98], [0xfd, 0xd8, 0x9a], [0x45, 0x0F, 0x76],
[0xfd, 0xda, 0x9c], [0xfd, 0xdc, 0x9d], [0xfd, 0xdd, 0x9f], [0xfd, 0xdf, 0xa1], [0x47, 0x0F, 0x77],
[0xfd, 0xe1, 0xa3], [0xfc, 0xe3, 0xa5], [0xfc, 0xe5, 0xa6], [0xfc, 0xe6, 0xa8], [0x48, 0x10, 0x78],
[0xfc, 0xe8, 0xaa], [0xfc, 0xea, 0xac], [0xfc, 0xec, 0xae], [0xfc, 0xee, 0xb0], [0x4A, 0x10, 0x79],
[0xfc, 0xf0, 0xb1], [0xfc, 0xf1, 0xb3], [0xfc, 0xf3, 0xb5], [0xfc, 0xf5, 0xb7], [0x4B, 0x10, 0x79],
[0xfb, 0xf7, 0xb9], [0xfb, 0xf9, 0xbb], [0xfb, 0xfa, 0xbd], [0xfb, 0xfc, 0xbf], [0x4D, 0x11, 0x7A],
], dtype="uint8") [0x4F, 0x11, 0x7B],
[0x50, 0x12, 0x7B],
[0x52, 0x12, 0x7C],
[0x53, 0x13, 0x7C],
[0x55, 0x13, 0x7D],
[0x57, 0x14, 0x7D],
[0x58, 0x15, 0x7E],
[0x5A, 0x15, 0x7E],
[0x5B, 0x16, 0x7E],
[0x5D, 0x17, 0x7E],
[0x5E, 0x17, 0x7F],
[0x60, 0x18, 0x7F],
[0x61, 0x18, 0x7F],
[0x63, 0x19, 0x7F],
[0x65, 0x1A, 0x80],
[0x66, 0x1A, 0x80],
[0x68, 0x1B, 0x80],
[0x69, 0x1C, 0x80],
[0x6B, 0x1C, 0x80],
[0x6C, 0x1D, 0x80],
[0x6E, 0x1E, 0x81],
[0x6F, 0x1E, 0x81],
[0x71, 0x1F, 0x81],
[0x73, 0x1F, 0x81],
[0x74, 0x20, 0x81],
[0x76, 0x21, 0x81],
[0x77, 0x21, 0x81],
[0x79, 0x22, 0x81],
[0x7A, 0x22, 0x81],
[0x7C, 0x23, 0x81],
[0x7E, 0x24, 0x81],
[0x7F, 0x24, 0x81],
[0x81, 0x25, 0x81],
[0x82, 0x25, 0x81],
[0x84, 0x26, 0x81],
[0x85, 0x26, 0x81],
[0x87, 0x27, 0x81],
[0x89, 0x28, 0x81],
[0x8A, 0x28, 0x81],
[0x8C, 0x29, 0x80],
[0x8D, 0x29, 0x80],
[0x8F, 0x2A, 0x80],
[0x91, 0x2A, 0x80],
[0x92, 0x2B, 0x80],
[0x94, 0x2B, 0x80],
[0x95, 0x2C, 0x80],
[0x97, 0x2C, 0x7F],
[0x99, 0x2D, 0x7F],
[0x9A, 0x2D, 0x7F],
[0x9C, 0x2E, 0x7F],
[0x9E, 0x2E, 0x7E],
[0x9F, 0x2F, 0x7E],
[0xA1, 0x2F, 0x7E],
[0xA3, 0x30, 0x7E],
[0xA4, 0x30, 0x7D],
[0xA6, 0x31, 0x7D],
[0xA7, 0x31, 0x7D],
[0xA9, 0x32, 0x7C],
[0xAB, 0x33, 0x7C],
[0xAC, 0x33, 0x7B],
[0xAE, 0x34, 0x7B],
[0xB0, 0x34, 0x7B],
[0xB1, 0x35, 0x7A],
[0xB3, 0x35, 0x7A],
[0xB5, 0x36, 0x79],
[0xB6, 0x36, 0x79],
[0xB8, 0x37, 0x78],
[0xB9, 0x37, 0x78],
[0xBB, 0x38, 0x77],
[0xBD, 0x39, 0x77],
[0xBE, 0x39, 0x76],
[0xC0, 0x3A, 0x75],
[0xC2, 0x3A, 0x75],
[0xC3, 0x3B, 0x74],
[0xC5, 0x3C, 0x74],
[0xC6, 0x3C, 0x73],
[0xC8, 0x3D, 0x72],
[0xCA, 0x3E, 0x72],
[0xCB, 0x3E, 0x71],
[0xCD, 0x3F, 0x70],
[0xCE, 0x40, 0x70],
[0xD0, 0x41, 0x6F],
[0xD1, 0x42, 0x6E],
[0xD3, 0x42, 0x6D],
[0xD4, 0x43, 0x6D],
[0xD6, 0x44, 0x6C],
[0xD7, 0x45, 0x6B],
[0xD9, 0x46, 0x6A],
[0xDA, 0x47, 0x69],
[0xDC, 0x48, 0x69],
[0xDD, 0x49, 0x68],
[0xDE, 0x4A, 0x67],
[0xE0, 0x4B, 0x66],
[0xE1, 0x4C, 0x66],
[0xE2, 0x4D, 0x65],
[0xE4, 0x4E, 0x64],
[0xE5, 0x50, 0x63],
[0xE6, 0x51, 0x62],
[0xE7, 0x52, 0x62],
[0xE8, 0x54, 0x61],
[0xEA, 0x55, 0x60],
[0xEB, 0x56, 0x60],
[0xEC, 0x58, 0x5F],
[0xED, 0x59, 0x5F],
[0xEE, 0x5B, 0x5E],
[0xEE, 0x5D, 0x5D],
[0xEF, 0x5E, 0x5D],
[0xF0, 0x60, 0x5D],
[0xF1, 0x61, 0x5C],
[0xF2, 0x63, 0x5C],
[0xF3, 0x65, 0x5C],
[0xF3, 0x67, 0x5B],
[0xF4, 0x68, 0x5B],
[0xF5, 0x6A, 0x5B],
[0xF5, 0x6C, 0x5B],
[0xF6, 0x6E, 0x5B],
[0xF6, 0x70, 0x5B],
[0xF7, 0x71, 0x5B],
[0xF7, 0x73, 0x5C],
[0xF8, 0x75, 0x5C],
[0xF8, 0x77, 0x5C],
[0xF9, 0x79, 0x5C],
[0xF9, 0x7B, 0x5D],
[0xF9, 0x7D, 0x5D],
[0xFA, 0x7F, 0x5E],
[0xFA, 0x80, 0x5E],
[0xFA, 0x82, 0x5F],
[0xFB, 0x84, 0x60],
[0xFB, 0x86, 0x60],
[0xFB, 0x88, 0x61],
[0xFB, 0x8A, 0x62],
[0xFC, 0x8C, 0x63],
[0xFC, 0x8E, 0x63],
[0xFC, 0x90, 0x64],
[0xFC, 0x92, 0x65],
[0xFC, 0x93, 0x66],
[0xFD, 0x95, 0x67],
[0xFD, 0x97, 0x68],
[0xFD, 0x99, 0x69],
[0xFD, 0x9B, 0x6A],
[0xFD, 0x9D, 0x6B],
[0xFD, 0x9F, 0x6C],
[0xFD, 0xA1, 0x6E],
[0xFD, 0xA2, 0x6F],
[0xFD, 0xA4, 0x70],
[0xFE, 0xA6, 0x71],
[0xFE, 0xA8, 0x73],
[0xFE, 0xAA, 0x74],
[0xFE, 0xAC, 0x75],
[0xFE, 0xAE, 0x76],
[0xFE, 0xAF, 0x78],
[0xFE, 0xB1, 0x79],
[0xFE, 0xB3, 0x7B],
[0xFE, 0xB5, 0x7C],
[0xFE, 0xB7, 0x7D],
[0xFE, 0xB9, 0x7F],
[0xFE, 0xBB, 0x80],
[0xFE, 0xBC, 0x82],
[0xFE, 0xBE, 0x83],
[0xFE, 0xC0, 0x85],
[0xFE, 0xC2, 0x86],
[0xFE, 0xC4, 0x88],
[0xFE, 0xC6, 0x89],
[0xFE, 0xC7, 0x8B],
[0xFE, 0xC9, 0x8D],
[0xFE, 0xCB, 0x8E],
[0xFD, 0xCD, 0x90],
[0xFD, 0xCF, 0x92],
[0xFD, 0xD1, 0x93],
[0xFD, 0xD2, 0x95],
[0xFD, 0xD4, 0x97],
[0xFD, 0xD6, 0x98],
[0xFD, 0xD8, 0x9A],
[0xFD, 0xDA, 0x9C],
[0xFD, 0xDC, 0x9D],
[0xFD, 0xDD, 0x9F],
[0xFD, 0xDF, 0xA1],
[0xFD, 0xE1, 0xA3],
[0xFC, 0xE3, 0xA5],
[0xFC, 0xE5, 0xA6],
[0xFC, 0xE6, 0xA8],
[0xFC, 0xE8, 0xAA],
[0xFC, 0xEA, 0xAC],
[0xFC, 0xEC, 0xAE],
[0xFC, 0xEE, 0xB0],
[0xFC, 0xF0, 0xB1],
[0xFC, 0xF1, 0xB3],
[0xFC, 0xF3, 0xB5],
[0xFC, 0xF5, 0xB7],
[0xFB, 0xF7, 0xB9],
[0xFB, 0xF9, 0xBB],
[0xFB, 0xFA, 0xBD],
[0xFB, 0xFC, 0xBF],
],
dtype="uint8",
)

View File

@@ -1,17 +1,19 @@
from datetime import datetime as dt from datetime import datetime as dt
class PyItem(PyItemTemplate): class PyItem(PyItemTemplate):
def on_click(self, evt=None): def on_click(self, evt=None):
self.data['done'] = not self.data['done'] self.data["done"] = not self.data["done"]
self.strike(self.data['done']) self.strike(self.data["done"])
self.select("input").element.checked = self.data["done"]
self.select('input').element.checked = self.data['done']
class PyList(PyListTemplate): class PyList(PyListTemplate):
item_class = PyItem item_class = PyItem
def add(self, item): def add(self, item):
if isinstance(item, str): if isinstance(item, str):
item = { "content": item, "done": False, "created_at": dt.now() } item = {"content": item, "done": False, "created_at": dt.now()}
super().add(item, labels=['content'], state_key="done") super().add(item, labels=["content"], state_key="done")

View File

@@ -1,31 +1,38 @@
from datetime import datetime as dt from datetime import datetime as dt
from utils import add_class, remove_class
from js import console from js import console
from utils import add_class, remove_class
tasks = [] tasks = []
# define the task template that will be use to render new templates to the page # define the task template that will be use to render new templates to the page
task_template = Element("task-template").select('.task', from_content=True) task_template = Element("task-template").select(".task", from_content=True)
task_list = Element("list-tasks-container") task_list = Element("list-tasks-container")
new_task_content = Element("new-task-content") new_task_content = Element("new-task-content")
def add_task(*ags, **kws): def add_task(*ags, **kws):
# create task # create task
task_id = f"task-{len(tasks)}" task_id = f"task-{len(tasks)}"
task = {"id": task_id, "content": new_task_content.element.value, "done": False, "created_at": dt.now()} task = {
"id": task_id,
"content": new_task_content.element.value,
"done": False,
"created_at": dt.now(),
}
tasks.append(task) tasks.append(task)
# add the task element to the page as new node in the list by cloning from a template # add the task element to the page as new node in the list by cloning from a template
taskHtml = task_template.clone(task_id, to=task_list) taskHtml = task_template.clone(task_id, to=task_list)
taskHtmlContent = taskHtml.select('p') taskHtmlContent = taskHtml.select("p")
taskHtmlContent.element.innerText = task['content'] taskHtmlContent.element.innerText = task["content"]
taskHtmlCheck = taskHtml.select('input') taskHtmlCheck = taskHtml.select("input")
task_list.element.appendChild(taskHtml.element) task_list.element.appendChild(taskHtml.element)
def check_task(evt=None): def check_task(evt=None):
task['done'] = not task['done'] task["done"] = not task["done"]
if task['done']: if task["done"]:
add_class(taskHtmlContent, "line-through") add_class(taskHtmlContent, "line-through")
else: else:
remove_class(taskHtmlContent, "line-through") remove_class(taskHtmlContent, "line-through")
@@ -33,6 +40,7 @@ def add_task(*ags, **kws):
new_task_content.clear() new_task_content.clear()
taskHtmlCheck.element.onclick = check_task taskHtmlCheck.element.onclick = check_task
def add_task_event(e): def add_task_event(e):
if (e.key == "Enter"): if e.key == "Enter":
add_task() add_task()

View File

@@ -2,5 +2,5 @@ from freedom.app import main
print("IN FREEDOM", main) print("IN FREEDOM", main)
if __name__ == '__main__': if __name__ == "__main__":
main().main_loop() main().main_loop()

View File

@@ -1,6 +1,5 @@
import toga import toga
from toga.style.pack import LEFT, RIGHT, COLUMN, ROW, Pack from toga.style.pack import COLUMN, LEFT, RIGHT, ROW, Pack
class FreedomApp(toga.App): class FreedomApp(toga.App):
@@ -8,7 +7,7 @@ class FreedomApp(toga.App):
try: try:
self.c_input.value = (float(self.f_input.value) - 32.0) * 5.0 / 9.0 self.c_input.value = (float(self.f_input.value) - 32.0) * 5.0 / 9.0
except ValueError: except ValueError:
self.c_input.value = '???' self.c_input.value = "???"
def startup(self): def startup(self):
self.main_window = toga.MainWindow(title=self.name) self.main_window = toga.MainWindow(title=self.name)
@@ -20,11 +19,11 @@ class FreedomApp(toga.App):
self.c_input = toga.TextInput(id="c_input", readonly=True) self.c_input = toga.TextInput(id="c_input", readonly=True)
self.f_input = toga.TextInput(id="f_input") self.f_input = toga.TextInput(id="f_input")
c_label = toga.Label('Celsius', style=Pack(text_align=LEFT)) c_label = toga.Label("Celsius", style=Pack(text_align=LEFT))
f_label = toga.Label('Fahrenheit', style=Pack(text_align=LEFT)) f_label = toga.Label("Fahrenheit", style=Pack(text_align=LEFT))
join_label = toga.Label('is equivalent to', style=Pack(text_align=RIGHT)) join_label = toga.Label("is equivalent to", style=Pack(text_align=RIGHT))
button = toga.Button('Calculate', id="calculate", on_press=self.calculate) button = toga.Button("Calculate", id="calculate", on_press=self.calculate)
f_box.add(self.f_input) f_box.add(self.f_input)
f_box.add(f_label) f_box.add(f_label)
@@ -54,8 +53,8 @@ class FreedomApp(toga.App):
def main(): def main():
return FreedomApp('Freedom Units', 'org.beeware.freedom', version='0.0.1') return FreedomApp("Freedom Units", "org.beeware.freedom", version="0.0.1")
if __name__ == '__main__': if __name__ == "__main__":
main().main_loop() main().main_loop()

View File

@@ -1,13 +1,11 @@
from flask import Flask from flask import Flask
from freedom import app as freedom
from toga_flask import TogaApp from toga_flask import TogaApp
from freedom import app as freedom app = Flask(__name__, static_folder="../static")
app = Flask(__name__, static_folder='../static') app.add_url_rule("/", view_func=TogaApp.as_view("foo", app_module=freedom))
app.add_url_rule('/', view_func=TogaApp.as_view("foo", app_module=freedom))
if __name__ == '__main__': if __name__ == "__main__":
app.run(port=8081, debug=True) app.run(port=8081, debug=True)

View File

@@ -1,13 +1,17 @@
from datetime import datetime as dt from datetime import datetime as dt
def format_date(dt_, fmt = "%m/%d/%Y, %H:%M:%S"):
def format_date(dt_, fmt="%m/%d/%Y, %H:%M:%S"):
return dt_.strftime(fmt) return dt_.strftime(fmt)
def now(fmt = "%m/%d/%Y, %H:%M:%S"):
def now(fmt="%m/%d/%Y, %H:%M:%S"):
return format_date(dt.now(), fmt) return format_date(dt.now(), fmt)
def remove_class(element, className): def remove_class(element, className):
element.element.classList.remove(className) element.element.classList.remove(className)
def add_class(element, className): def add_class(element, className):
element.element.classList.add(className) element.element.classList.add(className)

View File

@@ -1,40 +1,44 @@
from js import document, console
import asyncio import asyncio
import io, base64 import base64
import io
from js import console, document
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
MIME_METHODS = { MIME_METHODS = {
'__repr__': 'text/plain', "__repr__": "text/plain",
'_repr_html_': 'text/html', "_repr_html_": "text/html",
'_repr_markdown_': 'text/markdown', "_repr_markdown_": "text/markdown",
'_repr_svg_': 'image/svg+xml', "_repr_svg_": "image/svg+xml",
'_repr_png_': 'image/png', "_repr_png_": "image/png",
'_repr_pdf_': 'application/pdf', "_repr_pdf_": "application/pdf",
'_repr_jpeg_': 'image/jpeg', "_repr_jpeg_": "image/jpeg",
'_repr_latex': 'text/latex', "_repr_latex": "text/latex",
'_repr_json_': 'application/json', "_repr_json_": "application/json",
'_repr_javascript_': 'application/javascript', "_repr_javascript_": "application/javascript",
'savefig': 'image/png' "savefig": "image/png",
} }
def render_image(mime, value, meta): def render_image(mime, value, meta):
data = f'data:{mime};charset=utf-8;base64,{value}' data = f"data:{mime};charset=utf-8;base64,{value}"
attrs = ' '.join(['{k}="{v}"' for k, v in meta.items()]) attrs = " ".join(['{k}="{v}"' for k, v in meta.items()])
return f'<img src="{data}" {attrs}</img>' return f'<img src="{data}" {attrs}</img>'
def identity(value, meta): def identity(value, meta):
return value return value
MIME_RENDERERS = { MIME_RENDERERS = {
'text/plain': identity, "text/plain": identity,
'text/html' : identity, "text/html": identity,
'image/png' : lambda value, meta: render_image('image/png', value, meta), "image/png": lambda value, meta: render_image("image/png", value, meta),
'image/jpeg': lambda value, meta: render_image('image/jpeg', value, meta), "image/jpeg": lambda value, meta: render_image("image/jpeg", value, meta),
'image/svg+xml': identity, "image/svg+xml": identity,
'application/json': identity, "application/json": identity,
'application/javascript': lambda value, meta: f'<script>{value}</script>' "application/javascript": lambda value, meta: f"<script>{value}</script>",
} }
@@ -42,16 +46,16 @@ def eval_formatter(obj, print_method):
""" """
Evaluates a formatter method. Evaluates a formatter method.
""" """
if print_method == '__repr__': if print_method == "__repr__":
return repr(obj) return repr(obj)
elif hasattr(obj, print_method): elif hasattr(obj, print_method):
if print_method == 'savefig': if print_method == "savefig":
buf = io.BytesIO() buf = io.BytesIO()
obj.savefig(buf, format='png') obj.savefig(buf, format="png")
buf.seek(0) buf.seek(0)
return base64.b64encode(buf.read()).decode('utf-8') return base64.b64encode(buf.read()).decode("utf-8")
return getattr(obj, print_method)() return getattr(obj, print_method)()
elif print_method == '_repr_mimebundle_': elif print_method == "_repr_mimebundle_":
return {}, {} return {}, {}
return None return None
@@ -61,9 +65,9 @@ def format_mime(obj):
Formats object using _repr_x_ methods. Formats object using _repr_x_ methods.
""" """
if isinstance(obj, str): if isinstance(obj, str):
return obj, 'text/plain' return obj, "text/plain"
mimebundle = eval_formatter(obj, '_repr_mimebundle_') mimebundle = eval_formatter(obj, "_repr_mimebundle_")
if isinstance(mimebundle, tuple): if isinstance(mimebundle, tuple):
format_dict, md_dict = mimebundle format_dict, md_dict = mimebundle
else: else:
@@ -85,9 +89,11 @@ def format_mime(obj):
break break
if output is None: if output is None:
if not_available: if not_available:
console.warning(f'Rendered object requested unavailable MIME renderers: {not_available}') console.warning(
f"Rendered object requested unavailable MIME renderers: {not_available}"
)
output = repr(output) output = repr(output)
mime_type = 'text/plain' mime_type = "text/plain"
elif isinstance(output, tuple): elif isinstance(output, tuple):
output, meta = output output, meta = output
else: else:
@@ -103,17 +109,17 @@ class PyScript:
"""Writes value to the element with id "element_id""" """Writes value to the element with id "element_id"""
console.log(f"APPENDING: {append} ==> {element_id} --> {value}") console.log(f"APPENDING: {append} ==> {element_id} --> {value}")
if append: if append:
child = document.createElement('div'); child = document.createElement("div")
element = document.querySelector(f'#{element_id}'); element = document.querySelector(f"#{element_id}")
if not element: if not element:
return return
exec_id = exec_id or element.childElementCount + 1 exec_id = exec_id or element.childElementCount + 1
element_id = child.id = f"{element_id}-{exec_id}"; element_id = child.id = f"{element_id}-{exec_id}"
element.appendChild(child); element.appendChild(child)
element = document.getElementById(element_id) element = document.getElementById(element_id)
html, mime_type = format_mime(value) html, mime_type = format_mime(value)
if mime_type in ('application/javascript', 'text/html'): if mime_type in ("application/javascript", "text/html"):
scriptEl = document.createRange().createContextualFragment(html) scriptEl = document.createRange().createContextualFragment(html)
element.appendChild(scriptEl) element.appendChild(scriptEl)
else: else:
@@ -133,7 +139,7 @@ class Element:
def element(self): def element(self):
"""Return the dom element""" """Return the dom element"""
if not self._element: if not self._element:
self._element = document.querySelector(f'#{self._id}'); self._element = document.querySelector(f"#{self._id}")
return self._element return self._element
def write(self, value, append=False): def write(self, value, append=False):
@@ -143,8 +149,8 @@ class Element:
pyscript.write(self._id, value, append=append) pyscript.write(self._id, value, append=append)
def clear(self): def clear(self):
if hasattr(self.element, 'value'): if hasattr(self.element, "value"):
self.element.value = '' self.element.value = ""
else: else:
self.write("", append=False) self.write("", append=False)
@@ -163,13 +169,13 @@ class Element:
if new_id is None: if new_id is None:
new_id = self.element.id new_id = self.element.id
clone = self.element.cloneNode(True); clone = self.element.cloneNode(True)
clone.id = new_id; clone.id = new_id
if to: if to:
to.element.appendChild(clone) to.element.appendChild(clone)
# Inject it into the DOM # Inject it into the DOM
self.element.after(clone); self.element.after(clone)
return Element(clone.id, clone) return Element(clone.id, clone)