Compare commits
No commits in common. "7b237246da925a92c600cdc25d1e446f3db4feec" and "ef0265c86d8f339089dd156929e3e019579615d6" have entirely different histories.
7b237246da
...
ef0265c86d
1
justfile
1
justfile
@ -68,7 +68,6 @@ _generate-models path name:
|
|||||||
--encoding "UTF-8" \
|
--encoding "UTF-8" \
|
||||||
--disable-timestamp \
|
--disable-timestamp \
|
||||||
--use-schema-description \
|
--use-schema-description \
|
||||||
--set-default-enum-member \
|
|
||||||
--allow-population-by-field-name \
|
--allow-population-by-field-name \
|
||||||
--snake-case-field \
|
--snake-case-field \
|
||||||
--strict-nullable \
|
--strict-nullable \
|
||||||
|
67
notebooks/week-0.ipynb
Normal file
67
notebooks/week-0.ipynb
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Woche 0 - 10.-16. Oktober 2022 #\n",
|
||||||
|
"\n",
|
||||||
|
"Herzlich willkommen zur 0. Woche!"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import os;\n",
|
||||||
|
"import sys;\n",
|
||||||
|
"\n",
|
||||||
|
"# NOTE: need this to force jupyter to reload imports:\n",
|
||||||
|
"for key in list(sys.modules.keys()):\n",
|
||||||
|
" if key.startswith('src.'):\n",
|
||||||
|
" del sys.modules[key];\n",
|
||||||
|
"\n",
|
||||||
|
"os.chdir(os.path.dirname(_dh[0]));\n",
|
||||||
|
"sys.path.insert(0, os.getcwd());\n",
|
||||||
|
"\n",
|
||||||
|
"from src.thirdparty.maths import *;\n",
|
||||||
|
"from src.thirdparty.render import *;\n",
|
||||||
|
"\n",
|
||||||
|
"np.random.seed(8007253); # zur Wiederholbarkeit"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"A = np.random.randint(-100, 100, size=(4, 7));\n",
|
||||||
|
"display(array_to_latex(A, precision=3));"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3.10.6 64-bit",
|
||||||
|
"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.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
@ -1,100 +0,0 @@
|
|||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Woche 2 - 17.-23. Oktober 2022 #\n",
|
|
||||||
"\n",
|
|
||||||
"Herzlich willkommen zur 2. Woche!"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import os;\n",
|
|
||||||
"import sys;\n",
|
|
||||||
"\n",
|
|
||||||
"# NOTE: need this to force jupyter to reload imports:\n",
|
|
||||||
"for key in list(sys.modules.keys()):\n",
|
|
||||||
" if key.startswith('src.'):\n",
|
|
||||||
" del sys.modules[key];\n",
|
|
||||||
"\n",
|
|
||||||
"os.chdir(os.path.dirname(_dh[0]));\n",
|
|
||||||
"sys.path.insert(0, os.getcwd());\n",
|
|
||||||
"\n",
|
|
||||||
"from src.thirdparty.maths import *;\n",
|
|
||||||
"from src.thirdparty.render import *;\n",
|
|
||||||
"\n",
|
|
||||||
"from src.maths.diagrams import *;\n",
|
|
||||||
"from src.maths.sets import *;\n",
|
|
||||||
"\n",
|
|
||||||
"np.random.seed(8007253); # zur Wiederholbarkeit"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"A = np.random.randint(-100, 100, size=(4, 7));\n",
|
|
||||||
"\n",
|
|
||||||
"X = ['a', 'b', 'c', 'd', 'e'];\n",
|
|
||||||
"Y = [2, 3, 5, 7, 11, 13, 17];\n",
|
|
||||||
"Z = ['α', 'β', 'γ', 'δ'];\n",
|
|
||||||
"f = [('a', 5), ('b', 5), ('c', 17), ('d', 2)]\n",
|
|
||||||
"g = [(2, 'γ'), (3, 'α'), (5, 'β'), (7, 'δ'), (11, 'β'), (13, 'γ'), (17, 'β')];\n",
|
|
||||||
"comp = Functions(\n",
|
|
||||||
" Function(name=('$f$', 'X', 'Y'), domain=X, codomain=Y, fct=f),\n",
|
|
||||||
" Function(name=('$g$', 'Y', 'Z'), domain=Y, codomain=Z, fct=g),\n",
|
|
||||||
");\n",
|
|
||||||
"comp.draw(show_labels=True);"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"A = np.random.randint(-100, 100, size=(4, 7));\n",
|
|
||||||
"\n",
|
|
||||||
"X = randomset_alphabet(low=2, high=5);\n",
|
|
||||||
"Y = randomset_integers(low=2, high=5);\n",
|
|
||||||
"Z = randomset_greek(low=2, high=5);\n",
|
|
||||||
"f = random_function(X, Y);\n",
|
|
||||||
"g = random_function(Y, Z);\n",
|
|
||||||
"comp = Functions(\n",
|
|
||||||
" Function(name=('$f$', 'X', 'Y'), domain=X, codomain=Y, fct=f),\n",
|
|
||||||
" Function(name=('$g$', 'Y', 'Z'), domain=Y, codomain=Z, fct=g),\n",
|
|
||||||
");\n",
|
|
||||||
"comp.draw(show_labels=False);"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3.10.8 64-bit",
|
|
||||||
"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.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 2
|
|
||||||
}
|
|
@ -40,7 +40,7 @@ datamodel-code-generator>=0.12.0
|
|||||||
# maths
|
# maths
|
||||||
fraction>=2.2.0
|
fraction>=2.2.0
|
||||||
numpy>=1.22.4
|
numpy>=1.22.4
|
||||||
matplotlib>=3.6.1
|
matplotlib>=3.5.1
|
||||||
|
|
||||||
# tables, data frames
|
# tables, data frames
|
||||||
pandas>=1.4.2
|
pandas>=1.4.2
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.maths.diagrams.sets import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'Function',
|
|
||||||
'Functions',
|
|
||||||
];
|
|
@ -1,205 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from __future__ import annotations;
|
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
|
||||||
from src.thirdparty.types import *;
|
|
||||||
from src.thirdparty.maths import *;
|
|
||||||
from src.thirdparty.plots import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'Function',
|
|
||||||
'Functions',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# CONSTANTS / VARIABLES
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
T1 = TypeVar('T1');
|
|
||||||
T2 = TypeVar('T2');
|
|
||||||
|
|
||||||
SCALE = (1., 4.);
|
|
||||||
OFFSET = (3., 0.);
|
|
||||||
MARGIN = 0.1;
|
|
||||||
N_RESOLUTION = 100;
|
|
||||||
ANNOTATE_OFFSET = (0, 10);
|
|
||||||
FONTSIZE_PTS = 10;
|
|
||||||
FONTSIZE_FCT = 14;
|
|
||||||
FONTSIZE_SETS = 14;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# Classes
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Function(Generic[T1,T2]):
|
|
||||||
name: tuple[str, str, str] = field();
|
|
||||||
domain: list[T1] = field();
|
|
||||||
codomain: list[T2] = field();
|
|
||||||
fct: list[tuple[T1,T2]] = field();
|
|
||||||
|
|
||||||
@property
|
|
||||||
def range(self) -> list[T2]:
|
|
||||||
return [y for x, y in self.fct];
|
|
||||||
|
|
||||||
@property
|
|
||||||
def indexes(self) -> list[tuple[int, int]]:
|
|
||||||
# prevent repeated computation:
|
|
||||||
if not hasattr(self, '_indexes'):
|
|
||||||
self._indexes = [
|
|
||||||
(self.domain.index(x), self.codomain.index(y))
|
|
||||||
for x, y in self.fct
|
|
||||||
];
|
|
||||||
return getattr(self, '_indexes');
|
|
||||||
|
|
||||||
def draw(self) -> Figure:
|
|
||||||
return Functions(self).draw();
|
|
||||||
|
|
||||||
class Functions:
|
|
||||||
fcts: list[Function];
|
|
||||||
|
|
||||||
def __init__(self, *f: Function):
|
|
||||||
self.fcts = list(f);
|
|
||||||
|
|
||||||
def draw(self, show_labels: bool = True) -> Figure:
|
|
||||||
N = len(self.fcts);
|
|
||||||
obj = mplot.subplots(1, 1, constrained_layout=True);
|
|
||||||
fig: Figure = obj[0];
|
|
||||||
axs: Axes = obj[1];
|
|
||||||
axs.tick_params(axis='both', which='both', left=False, right=False, top=False, bottom=False, labelbottom=False, labelleft=False);
|
|
||||||
mplot.title('');
|
|
||||||
mplot.xlabel('');
|
|
||||||
mplot.ylabel('');
|
|
||||||
mplot.margins(x=MARGIN, y=MARGIN);
|
|
||||||
|
|
||||||
origin = np.asarray((0., 0.));
|
|
||||||
offset = np.asarray(OFFSET);
|
|
||||||
|
|
||||||
p_set = oval(nr_points=N_RESOLUTION, scale=SCALE, centre=origin);
|
|
||||||
for k in range(N+1):
|
|
||||||
axs.plot(p_set[:, 0] + k*offset[0], p_set[:, 1] + k*offset[1], label='', color='blue');
|
|
||||||
|
|
||||||
p_domain = [];
|
|
||||||
p_codomain = [];
|
|
||||||
comp_range = [];
|
|
||||||
|
|
||||||
anchors = [
|
|
||||||
[
|
|
||||||
# function name
|
|
||||||
origin + (k + 0.5)*offset + (0, -1.1*SCALE[1]),
|
|
||||||
# sets
|
|
||||||
origin + k * offset + (0, 1.1 * SCALE[1]),
|
|
||||||
origin + (k + 1) * offset + (0, 1.1 * SCALE[1]),
|
|
||||||
# arrow start -> end
|
|
||||||
origin + (k + 0.05) * offset + (0, -1.1 * SCALE[1]),
|
|
||||||
origin + (k + 1 - 0.05) * offset + (0, -1.1 * SCALE[1]),
|
|
||||||
|
|
||||||
]
|
|
||||||
for k in range(N)
|
|
||||||
];
|
|
||||||
|
|
||||||
for k, f in enumerate(self.fcts):
|
|
||||||
if k == 0:
|
|
||||||
comp_range = f.domain;
|
|
||||||
p_domain = random_points(nr_points=len(f.domain), scale=SCALE, centre=origin + k*offset);
|
|
||||||
else:
|
|
||||||
p_domain = p_codomain;
|
|
||||||
p_codomain = random_points(nr_points=len(f.codomain), scale=SCALE, centre=origin + (k+1)*offset);
|
|
||||||
# range of composition so far:
|
|
||||||
comp_range_next = [y for x, y in f.fct if x in comp_range];
|
|
||||||
|
|
||||||
if k == 0:
|
|
||||||
axs.scatter(p_domain[:, 0], p_domain[:, 1], label='', color='black', marker='o');
|
|
||||||
if show_labels:
|
|
||||||
for i, p in enumerate(p_domain):
|
|
||||||
x_name = f.domain[i];
|
|
||||||
axs.annotate(text=f'{x_name}', xy = p, textcoords='offset points', xytext=ANNOTATE_OFFSET, ha='center', size=FONTSIZE_PTS);
|
|
||||||
|
|
||||||
for j, p in enumerate(p_codomain):
|
|
||||||
y = f.codomain[j];
|
|
||||||
marker = 'o' if (y in comp_range_next) else 'x';
|
|
||||||
axs.scatter([p[0]], [p[1]], label='', color='black', marker=marker);
|
|
||||||
y_name = f.codomain[j];
|
|
||||||
if show_labels:
|
|
||||||
axs.annotate(text=f'{y_name}', xy=p, textcoords='offset points', xytext=ANNOTATE_OFFSET, ha='center', size=FONTSIZE_PTS);
|
|
||||||
|
|
||||||
for i, j in f.indexes:
|
|
||||||
p = p_domain[i];
|
|
||||||
q = p_codomain[j];
|
|
||||||
x = f.domain[i];
|
|
||||||
if k == 0 or (x in comp_range):
|
|
||||||
axs.plot([p[0], q[0]], [p[1], q[1]], label='', color='g', linewidth=2);
|
|
||||||
else:
|
|
||||||
axs.plot([p[0], q[0]], [p[1], q[1]], label='', color='g', linestyle='--', linewidth=1);
|
|
||||||
|
|
||||||
anchor = anchors[k];
|
|
||||||
fct_name, X_name, Y_name = f.name;
|
|
||||||
axs.annotate(text=f'{fct_name}', xy=anchor[0], ha='center', size=FONTSIZE_FCT);
|
|
||||||
if k == 0:
|
|
||||||
axs.annotate(text=f'{X_name}', xy=anchor[1], ha='center', size=FONTSIZE_FCT);
|
|
||||||
axs.annotate(text=f'{Y_name}', xy=anchor[2], ha='center', size=FONTSIZE_FCT);
|
|
||||||
axs.add_patch(FancyArrowPatch(
|
|
||||||
anchor[3], anchor[4],
|
|
||||||
connectionstyle = 'arc3,rad=0.5',
|
|
||||||
arrowstyle = 'Simple, tail_width=0.5, head_width=4, head_length=8',
|
|
||||||
color = 'black',
|
|
||||||
));
|
|
||||||
|
|
||||||
# update range of composition:
|
|
||||||
comp_range = comp_range_next;
|
|
||||||
|
|
||||||
return fig;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# AUXILIARY
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def oval(
|
|
||||||
nr_points: int,
|
|
||||||
scale: tuple[float, float] = (1., 1.),
|
|
||||||
centre: tuple[float, float] = (0., 0.),
|
|
||||||
) -> NDArray[Shape['*, 2'], Float]:
|
|
||||||
theta = np.linspace(start=0, stop=2*np.pi, num=nr_points, endpoint=True);
|
|
||||||
P = np.zeros(shape=(nr_points, 2), dtype=float);
|
|
||||||
P[:, 0] = centre[0] + scale[0] * np.cos(theta);
|
|
||||||
P[:, 1] = centre[1] + scale[1] * np.sin(theta);
|
|
||||||
P[-1, :] = P[0, :];
|
|
||||||
return P;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def random_points(
|
|
||||||
nr_points: int,
|
|
||||||
scale: tuple[float, float] = (1., 1.),
|
|
||||||
centre: tuple[float, float] = (0., 0.),
|
|
||||||
force: bool = False,
|
|
||||||
tol: float = 0.2,
|
|
||||||
) -> NDArray[Shape['*, 2'], Float]:
|
|
||||||
theta = np.linspace(start=0, stop=2*np.pi, num=nr_points, endpoint=False);
|
|
||||||
r_min = 0.25;
|
|
||||||
r_max = 1;
|
|
||||||
while True:
|
|
||||||
u = np.random.random(size=(nr_points,));
|
|
||||||
u_max = max(u);
|
|
||||||
if u_max == 0.:
|
|
||||||
continue;
|
|
||||||
if force:
|
|
||||||
u = np.minimum((1 + tol) * u / u_max, 1);
|
|
||||||
else:
|
|
||||||
u = (1 - tol) * u / u_max;
|
|
||||||
break;
|
|
||||||
r = r_min + (r_max - r_min) * u;
|
|
||||||
P = np.zeros(shape=(nr_points, 2), dtype=float);
|
|
||||||
P[:, 0] = centre[0] + scale[0] * r * np.cos(theta);
|
|
||||||
P[:, 1] = centre[1] + scale[1] * r * np.sin(theta);
|
|
||||||
return P;
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.maths.sets.random import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'random_function',
|
|
||||||
'randomset_alphabet',
|
|
||||||
'randomset_greek',
|
|
||||||
'randomset_integers',
|
|
||||||
];
|
|
@ -1,62 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from __future__ import annotations;
|
|
||||||
|
|
||||||
from src.thirdparty.types import *;
|
|
||||||
from src.thirdparty.maths import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'randomset_integers',
|
|
||||||
'randomset_alphabet',
|
|
||||||
'randomset_greek',
|
|
||||||
'random_function',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# CONSTANTS / VARIABLES
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
ALPHA = 'abcdefghijklmnopqrstuvwxyz';
|
|
||||||
GREEK = 'αβγδεζηθικλμνξοπρςτυφχψω';
|
|
||||||
T1 = TypeVar('T1');
|
|
||||||
T2 = TypeVar('T2');
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# METHODS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def randomset_integers(low: int, high: int) -> list[int]:
|
|
||||||
N = random.randint(low, high);
|
|
||||||
return list(range(1, N+1));
|
|
||||||
|
|
||||||
def randomset_alphabet(low: int, high: int) -> list[int]:
|
|
||||||
N = random.randint(low, high);
|
|
||||||
return list([a for k, a in enumerate(ALPHA) if k < N]);
|
|
||||||
|
|
||||||
def randomset_greek(low: int, high: int) -> list[int]:
|
|
||||||
N = random.randint(low, high);
|
|
||||||
return list([a for k, a in enumerate(GREEK) if k < N]);
|
|
||||||
|
|
||||||
def random_function(
|
|
||||||
X: list[T1],
|
|
||||||
Y: list[T2],
|
|
||||||
injective: Optional[bool] = None,
|
|
||||||
surjective: Optional[bool] = None,
|
|
||||||
) -> list[tuple[T1, T2]]:
|
|
||||||
# TODO: add feature to force injectivity/surjectivity, if possible.
|
|
||||||
# m = len(X);
|
|
||||||
# n = len(Y);
|
|
||||||
# if m > n:
|
|
||||||
# injective = False;
|
|
||||||
# if m < n:
|
|
||||||
# surjective = False;
|
|
||||||
return [ (x, random.choice(Y)) for x in X ];
|
|
55
src/thirdparty/misc.py
vendored
55
src/thirdparty/misc.py
vendored
@ -7,62 +7,9 @@
|
|||||||
|
|
||||||
from datetime import datetime;
|
from datetime import datetime;
|
||||||
from datetime import timedelta;
|
from datetime import timedelta;
|
||||||
from functools import wraps;
|
|
||||||
import lorem;
|
import lorem;
|
||||||
import re;
|
import re;
|
||||||
from textwrap import dedent as textwrap_dedent;
|
from textwrap import dedent;
|
||||||
from typing import Callable;
|
|
||||||
from typing import TypeVar;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# MODIFICATIONS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def prestrip(first: bool = True, last: bool = True, all: bool = False):
|
|
||||||
'''
|
|
||||||
Returns a decorator that modifies string -> string methods
|
|
||||||
'''
|
|
||||||
T = TypeVar('T');
|
|
||||||
def dec(method: Callable[[str], T]) -> Callable[[str], T]:
|
|
||||||
'''
|
|
||||||
Performs method but first strips initial/final (empty) lines.
|
|
||||||
'''
|
|
||||||
@wraps(method)
|
|
||||||
def wrapped_method(text: str) -> T:
|
|
||||||
lines = re.split(pattern=r'\n', string=text);
|
|
||||||
if all:
|
|
||||||
if first:
|
|
||||||
while len(lines) > 0 and lines[0].strip() == '':
|
|
||||||
lines = lines[1:];
|
|
||||||
if last:
|
|
||||||
while len(lines) > 0 and lines[-1].strip() == '':
|
|
||||||
lines = lines[:-1];
|
|
||||||
else:
|
|
||||||
if first:
|
|
||||||
lines = lines[1:];
|
|
||||||
if last:
|
|
||||||
lines = lines[:-1];
|
|
||||||
text = '\n'.join(lines);
|
|
||||||
return method(text);
|
|
||||||
return wrapped_method;
|
|
||||||
return dec;
|
|
||||||
|
|
||||||
@prestrip(all=False)
|
|
||||||
def dedent(text: str) -> str:
|
|
||||||
'''
|
|
||||||
Remove any common leading whitespace from every line in `text`.
|
|
||||||
|
|
||||||
This can be used to make triple-quoted strings line up with the left
|
|
||||||
edge of the display, while still presenting them in the source code
|
|
||||||
in indented form.
|
|
||||||
|
|
||||||
Note that tabs and spaces are both treated as whitespace, but they
|
|
||||||
are not equal: the lines " hello" and "\\thello" are
|
|
||||||
considered to have no common leading whitespace.
|
|
||||||
|
|
||||||
Entirely blank lines are normalized to a newline character.
|
|
||||||
'''
|
|
||||||
return textwrap_dedent(text);
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# EXPORTS
|
# EXPORTS
|
||||||
|
24
src/thirdparty/plots.py
vendored
24
src/thirdparty/plots.py
vendored
@ -1,24 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from matplotlib import pyplot as mplot;
|
|
||||||
from matplotlib import colors as mcolours;
|
|
||||||
from matplotlib.figure import Figure;
|
|
||||||
from matplotlib.axes import Axes;
|
|
||||||
from matplotlib.patches import FancyArrowPatch;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'mplot',
|
|
||||||
'mcolours',
|
|
||||||
'Figure',
|
|
||||||
'Axes',
|
|
||||||
'FancyArrowPatch',
|
|
||||||
];
|
|
Loading…
x
Reference in New Issue
Block a user