master > master: src - widgets
This commit is contained in:
parent
f9186f0464
commit
6f24f4f635
@ -63,7 +63,7 @@ class Function(Generic[T1,T2]):
|
||||
];
|
||||
return getattr(self, '_indexes');
|
||||
|
||||
def draw(self) -> Figure:
|
||||
def draw(self) -> tuple[Figure, Axes]:
|
||||
return Functions(self).draw();
|
||||
|
||||
class Functions:
|
||||
@ -74,7 +74,7 @@ class Functions:
|
||||
self.fcts = list(f);
|
||||
self.name = r' \circ '.join([ fct.name[0] for fct in self.fcts ][::-1]);
|
||||
|
||||
def draw(self, show_labels: bool = True) -> Figure:
|
||||
def draw(self, show_labels: bool = True) -> tuple[Figure, Axes]:
|
||||
N = len(self.fcts);
|
||||
obj = mplot.subplots(1, 1, constrained_layout=True);
|
||||
fig: Figure = obj[0];
|
||||
@ -165,8 +165,7 @@ class Functions:
|
||||
|
||||
# update range of composition:
|
||||
comp_range = comp_range_next;
|
||||
|
||||
return fig;
|
||||
return fig, axs;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# AUXILIARY
|
||||
|
@ -54,6 +54,7 @@ def random_function(
|
||||
Y: list[T2],
|
||||
injective: Optional[bool] = None,
|
||||
surjective: Optional[bool] = None,
|
||||
force: bool = False,
|
||||
) -> list[tuple[T1, T2]]:
|
||||
m = len(X);
|
||||
n = len(Y);
|
||||
@ -61,6 +62,15 @@ def random_function(
|
||||
return [];
|
||||
if n == 0:
|
||||
raise Exception(f'Impossible to create a function with {m} elements in the domain and {n} in the codomain.');
|
||||
if not force:
|
||||
if injective and m > n:
|
||||
injective = None;
|
||||
if surjective and m < n:
|
||||
surjective = None;
|
||||
if not injective and m == 1:
|
||||
injective = None;
|
||||
if not surjective and n == 1:
|
||||
surjective = None;
|
||||
match (injective, surjective):
|
||||
case (True, _):
|
||||
assert m <= n, f'Impossible to create an injective function with {m} elements in the domain and {n} in the codomain.';
|
||||
|
12
src/thirdparty/render.py
vendored
12
src/thirdparty/render.py
vendored
@ -10,6 +10,7 @@ from IPython.display import display_latex;
|
||||
from IPython.display import display_png;
|
||||
from IPython.display import display_markdown;
|
||||
from IPython.display import display;
|
||||
import ipywidgets as widgets;
|
||||
# from array_to_latex import to_ltx as array_to_latex; # <- has issues
|
||||
from qiskit.visualization import array_to_latex;
|
||||
|
||||
@ -18,10 +19,11 @@ from qiskit.visualization import array_to_latex;
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
__all__ = [
|
||||
'Latex',
|
||||
'display',
|
||||
'display_latex',
|
||||
'display_png',
|
||||
'display_markdown',
|
||||
'array_to_latex',
|
||||
'display_latex',
|
||||
'display_markdown',
|
||||
'display_png',
|
||||
'display',
|
||||
'Latex',
|
||||
'widgets',
|
||||
];
|
||||
|
16
src/widgets/__init__.py
Normal file
16
src/widgets/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.widgets.function_diagrams import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
__all__ = [
|
||||
'FunctionDiagramWidget',
|
||||
];
|
154
src/widgets/function_diagrams.py
Normal file
154
src/widgets/function_diagrams.py
Normal file
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from __future__ import annotations;
|
||||
|
||||
from src.thirdparty.types import *;
|
||||
from src.thirdparty.plots import *;
|
||||
from src.thirdparty.render import *;
|
||||
|
||||
from src.maths.diagrams import *;
|
||||
from src.maths.sets import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
__all__ = [
|
||||
'FunctionDiagramWidget',
|
||||
];
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# Class
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class FunctionDiagramWidget():
|
||||
state: Optional[widgets.Output];
|
||||
N: Optional[int];
|
||||
N_max: int;
|
||||
fnames: list[str];
|
||||
setnames: list[str];
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
fnames: list[str],
|
||||
setnames: list[str],
|
||||
N: Optional[int] = None,
|
||||
):
|
||||
self.state = None;
|
||||
self.N = N;
|
||||
self.N_max = len(fnames);
|
||||
assert len(setnames) == len(fnames) + 1, f'The number of sets must be {self.N_max+1}.';
|
||||
self.fnames = fnames;
|
||||
self.setnames = setnames;
|
||||
|
||||
def run(self):
|
||||
if self.N is None:
|
||||
control_nr = widgets.IntSlider(description=f'# Funktionen', min=1, max=self.N_max);
|
||||
display(control_nr);
|
||||
else:
|
||||
control_nr = widgets.IntSlider(value=self.N);
|
||||
self.state = widgets.interactive_output(self.handler_wrapper, controls={'N': control_nr});
|
||||
display(self.state);
|
||||
|
||||
def handler_plot(self, N: int, show_labels: bool, **kwargs):
|
||||
cardinalities = [ kwargs[f'card_{k}'] for k in range(N+1)];
|
||||
injective = [ kwargs[f'injective_{k}'] for k in range(N)];
|
||||
surjective = [ kwargs[f'surjective_{k}'] for k in range(N)];
|
||||
X = [ randomset_alphabet(N=card) for card in cardinalities ];
|
||||
comp = Functions(*[
|
||||
Function(
|
||||
name = (f'{self.fnames[k]}', f'{self.setnames[k]}', f'{self.setnames[k+1]}'),
|
||||
domain = X[k],
|
||||
codomain = X[k+1],
|
||||
fct = random_function(X[k], X[k+1], injective=injective[k], surjective=surjective[k], force=False)
|
||||
)
|
||||
for k in range(N)
|
||||
]);
|
||||
fig, axs = comp.draw(show_labels=show_labels);
|
||||
# for k in range(N):
|
||||
# [m, n] = cardinalities[k:][:2];
|
||||
# inj = injective[k];
|
||||
# surj = surjective[k];
|
||||
# if m < n and surj:
|
||||
# print(f'\x1b[1m{self.fnames[k]}\x1b[0m kann nicht surjektiv sein');
|
||||
# if m > n and inj:
|
||||
# print(f'\x1b[1m{self.fnames[k]}\x1b[0m kann nicht injektiv sein');
|
||||
# if n == 1 and not surj:
|
||||
# print(f'\x1b[1m{self.fnames[k]}\x1b[0m kann nicht nicht-surjektiv sein');
|
||||
# if m == 1 and not inj:
|
||||
# print(f'\x1b[1m{self.fnames[k]}\x1b[0m kann nicht nicht-injektiv sein');
|
||||
return;
|
||||
|
||||
def handler_wrapper(self, N: int):
|
||||
show_labels = widgets.Checkbox(description='Labels anzeigen?', style={'description_width': 'initial'}, visible=True);
|
||||
control_nr = widgets.IntSlider(value=N);
|
||||
controls_card = [
|
||||
widgets.IntSlider(
|
||||
value = None,
|
||||
description = f'|{self.setnames[k]}|',
|
||||
min = 1,
|
||||
max = 24,
|
||||
)
|
||||
for k in range(N+1)
|
||||
];
|
||||
controls_injective = [
|
||||
widgets.Checkbox(
|
||||
value = None,
|
||||
description = f'{self.fnames[k]} injektiv?',
|
||||
style = {
|
||||
'description_width': 'initial',
|
||||
},
|
||||
visible = True,
|
||||
)
|
||||
for k in range(N)
|
||||
];
|
||||
controls_surjective = [
|
||||
widgets.Checkbox(
|
||||
value = None,
|
||||
description = f'{self.fnames[k]} surjectiv?',
|
||||
style = {
|
||||
'description_width': 'initial',
|
||||
},
|
||||
visible = True,
|
||||
)
|
||||
for k in range(N)
|
||||
];
|
||||
# controls_func = [None for _ in range(2*N)];
|
||||
# controls_func[::2] = controls_injective;
|
||||
# controls_func[1::2] = controls_surjective;
|
||||
# controls_func = [
|
||||
# widgets.RadioButtons(
|
||||
# options = [ None, 'inj', 'surj', 'bij' ],
|
||||
# # default:
|
||||
# value = 'inj',
|
||||
# layout = {
|
||||
# 'description_width': 'initial',
|
||||
# 'width': 'max-content',
|
||||
# },
|
||||
# description = f'{self.fnames[k]}',
|
||||
# disabled = False,
|
||||
# )
|
||||
# for k in range(N)
|
||||
# ];
|
||||
ui = widgets.VBox(
|
||||
[show_labels] \
|
||||
+ controls_card \
|
||||
+ [
|
||||
widgets.HBox([control_injective, control_surjective])
|
||||
for control_injective, control_surjective in zip(controls_injective, controls_surjective)
|
||||
]
|
||||
);
|
||||
display(ui);
|
||||
display(widgets.interactive_output(
|
||||
f = self.handler_plot,
|
||||
controls = { 'N': control_nr, 'show_labels': show_labels } \
|
||||
| { f'card_{k}': controls_card[k] for k in range(N+1) } \
|
||||
| { f'injective_{k}': controls_injective[k] for k in range(N) } \
|
||||
| { f'surjective_{k}': controls_surjective[k] for k in range(N) }
|
||||
));
|
||||
return;
|
Loading…
Reference in New Issue
Block a user