master > master: src - cleanup
This commit is contained in:
parent
8d585f96c7
commit
dc5918682c
@ -22,9 +22,7 @@ __all__ = [
|
||||
'GetState',
|
||||
'CallValue',
|
||||
'CallError',
|
||||
'keep_calm_and_carry_on',
|
||||
'run_safely',
|
||||
'to_async',
|
||||
];
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -52,6 +52,12 @@ class FunctionDiagramWidget():
|
||||
setsfrom: list[list[Any]];
|
||||
card: list[int];
|
||||
|
||||
ctrl_nr: widgets.IntSlider;
|
||||
btn_refresh: widgets.ToggleButton;
|
||||
ctrls_card: list[widgets.IntSlider];
|
||||
ctrls_property: list[widgets.IntSlider];
|
||||
fcts: Functions;
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
fnames: list[str],
|
||||
@ -60,7 +66,7 @@ class FunctionDiagramWidget():
|
||||
N: Optional[int] = None,
|
||||
):
|
||||
self.state = None;
|
||||
self.N = N;
|
||||
self.N = N or 1;
|
||||
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;
|
||||
@ -81,35 +87,23 @@ class FunctionDiagramWidget():
|
||||
self.card = [ min(3, len(XX)) for XX in self.setsfrom ];
|
||||
|
||||
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):
|
||||
self.card[:(N+1)] = [ kwargs[f'card_{k}'] for k in range(N+1) ];
|
||||
properties = [ option_to_property(kwargs[f'property_{k}']) for k in range(N)];
|
||||
injective = list(map(is_injective, properties));
|
||||
surjective = list(map(is_surjective, properties));
|
||||
X = [ XX[:card] for XX, card in zip(self.setsfrom[:(N+1)], self.card[:(N+1)]) ];
|
||||
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);
|
||||
'''
|
||||
Runs the widget.
|
||||
'''
|
||||
self.create_widgets();
|
||||
display(widgets.interactive_output(
|
||||
f = self.handler_main,
|
||||
controls = {'N': self.ctrl_nr},
|
||||
));
|
||||
return;
|
||||
|
||||
def handler_wrapper(self, N: int):
|
||||
button_refresh = widgets.ToggleButton(description='Neu laden');
|
||||
button_show_labels = widgets.Checkbox(
|
||||
def create_widgets(self):
|
||||
'''
|
||||
Initialises the widgets.
|
||||
'''
|
||||
N = self.N_max;
|
||||
self.btn_refresh = widgets.ToggleButton(description='Neu laden');
|
||||
self.btn_show_labels = widgets.Checkbox(
|
||||
description = 'Labels anzeigen?',
|
||||
value = True,
|
||||
style = {
|
||||
@ -117,21 +111,31 @@ class FunctionDiagramWidget():
|
||||
},
|
||||
visible = True
|
||||
);
|
||||
control_nr = widgets.IntSlider(value=N);
|
||||
controls_card = [
|
||||
self.ctrl_nr = widgets.IntSlider(value=self.N, description=f'# Funktionen', min=1, max=self.N_max);
|
||||
cards_max = [ len(XX) for XX in self.setsfrom ];
|
||||
card_max_max = max(cards_max);
|
||||
self.ctrls_card = [
|
||||
widgets.IntSlider(
|
||||
value = card,
|
||||
description = f'|{setname}|',
|
||||
min = 1,
|
||||
max = len(XX),
|
||||
max = card_max,
|
||||
layout = {
|
||||
'width': 'initial',
|
||||
# FIXME: scales wrong:
|
||||
# 'width': f'{100*cards_max/card_max_max}%',
|
||||
},
|
||||
)
|
||||
for setname, XX, card, card_max in zip(
|
||||
self.setnames[:(N+1)],
|
||||
self.setsfrom[:(N+1)],
|
||||
self.card[:(N+1)],
|
||||
cards_max[:(N+1)],
|
||||
)
|
||||
for setname, XX, card in zip(self.setnames[:(N+1)], self.setsfrom[:(N+1)], self.card[:(N+1)])
|
||||
];
|
||||
|
||||
# controls for properties of functions
|
||||
controls_property = [
|
||||
self.ctrls_property = [
|
||||
widgets.RadioButtons(
|
||||
options = [ e.value for e in possible_properties(all=True) ],
|
||||
options = [ e.value for e in possible_properties(self.card[k], self.card[k+1]) ],
|
||||
value = FunctionProperty.NOTHING.value,
|
||||
layout = {
|
||||
'description_width': 'initial',
|
||||
@ -141,35 +145,28 @@ class FunctionDiagramWidget():
|
||||
)
|
||||
for k in range(N)
|
||||
];
|
||||
# NOTE: dynamically change the possible properties based on the cardinalities.
|
||||
def update_controls_property(change, k: int):
|
||||
self.card[k] = change['new'];
|
||||
if k > 0:
|
||||
m = self.card[k-1];
|
||||
n = self.card[k];
|
||||
controls_property[k-1].options = [ e.value for e in possible_properties(m, n) ];
|
||||
if k < N:
|
||||
m = self.card[k];
|
||||
n = self.card[k+1];
|
||||
controls_property[k].options = [ e.value for e in possible_properties(m, n) ];
|
||||
for k, ctrl_card in enumerate(self.ctrls_card):
|
||||
ctrl_card.observe(partial(self.handler_upd_card, k=k), names='value');
|
||||
# FIXME: this does not behave correctly:
|
||||
self.btn_show_labels.observe(partial(self.handler_plot, create=False));
|
||||
return;
|
||||
|
||||
for k, control_card in enumerate(controls_card):
|
||||
control_card.observe(
|
||||
partial(update_controls_property, k=k),
|
||||
names='value',
|
||||
);
|
||||
|
||||
ui = widgets.VBox(
|
||||
[ button_refresh ] \
|
||||
+ [ button_show_labels ] \
|
||||
+ controls_card \
|
||||
+ [
|
||||
widgets.HBox(
|
||||
def handler_main(self, *_, **__):
|
||||
'''
|
||||
Main handler for updating widgets.
|
||||
'''
|
||||
N = self.N = self.ctrl_nr.value;
|
||||
ui = widgets.VBox([] \
|
||||
+ [ self.btn_refresh ] \
|
||||
+ [ self.btn_show_labels ] \
|
||||
+ [ widgets.Text(f'Größen den Mengen:') ] \
|
||||
+ self.ctrls_card[:(N+1)] \
|
||||
+ [widgets.HBox(
|
||||
[
|
||||
widgets.VBox(
|
||||
[
|
||||
widgets.Text(f'Eigenschaften von {fname}'),
|
||||
control_property
|
||||
ctrl_property
|
||||
],
|
||||
layout = {
|
||||
'description_width': 'initial',
|
||||
@ -179,21 +176,90 @@ class FunctionDiagramWidget():
|
||||
'overflow': 'hidden',
|
||||
}
|
||||
)
|
||||
for fname, control_property in zip(self.fnames[:N], controls_property)
|
||||
],
|
||||
)
|
||||
for fname, ctrl_property in zip(self.fnames[:N], self.ctrls_property[:N])
|
||||
],
|
||||
)],
|
||||
);
|
||||
display(ui);
|
||||
display(widgets.interactive_output(
|
||||
f = self.handler_plot,
|
||||
controls = { 'N': control_nr, 'show_labels': button_show_labels } \
|
||||
| { f'card_{k}': controls_card[k] for k in range(N+1) } \
|
||||
| { f'property_{k}': controls_property[k] for k in range(N) } \
|
||||
| { 'refresh': button_refresh }
|
||||
controls = dict(
|
||||
N = self.ctrl_nr,
|
||||
refresh = self.btn_refresh,
|
||||
# FIXME: shoud not have to rely on this:
|
||||
show_labels = self.btn_show_labels,
|
||||
**{
|
||||
f'card[{k}]': ctrl_card
|
||||
for k, ctrl_card in enumerate(self.ctrls_card)
|
||||
},
|
||||
**{
|
||||
f'property[{k}]': ctrl_property
|
||||
for k, ctrl_property in enumerate(self.ctrls_property)
|
||||
},
|
||||
),
|
||||
));
|
||||
return;
|
||||
|
||||
def handler_plot(self, *_, create: bool = True, **__):
|
||||
'''
|
||||
Method to create sets, functions, and plot.
|
||||
'''
|
||||
self.card = [ ctrl_card.value for ctrl_card in self.ctrls_card ];
|
||||
if create:
|
||||
N = self.N;
|
||||
options = list(map(lambda ctrl: ctrl.value, self.ctrls_property[:N]));
|
||||
properties = list(map(option_to_property, options));
|
||||
injective = list(map(is_injective, properties));
|
||||
surjective = list(map(is_surjective, properties));
|
||||
sets = [ XX[:card] for XX, card in zip(self.setsfrom[:(N+1)], self.card[:(N+1)]) ];
|
||||
self.fcts = Functions(*[
|
||||
Function(
|
||||
name = (fname, nameX, nameY),
|
||||
domain = X,
|
||||
codomain = Y,
|
||||
fct = random_function(X, Y, injective=inj, surjective=surj, force=False),
|
||||
)
|
||||
for fname, nameX, nameY, X, Y, inj, surj in zip(
|
||||
self.fnames,
|
||||
self.setnames,
|
||||
self.setnames[1:],
|
||||
sets,
|
||||
sets[1:],
|
||||
injective,
|
||||
surjective,
|
||||
)
|
||||
]);
|
||||
# FIXME:
|
||||
# upon toggling show labels button, this even triggers multiple times,
|
||||
# and only the old value registers.
|
||||
show_labels = self.btn_show_labels.value;
|
||||
fig, axs = self.fcts.draw(show_labels=show_labels);
|
||||
return;
|
||||
|
||||
def handler_upd_card(self, change, k: int):
|
||||
'''
|
||||
Handler for altering function property options
|
||||
upon change of set cardinality.
|
||||
'''
|
||||
self.card[k] = change['new'];
|
||||
|
||||
def upd(j: int):
|
||||
m = self.card[j];
|
||||
n = self.card[j+1];
|
||||
value = self.ctrls_property[j].value;
|
||||
options = [ e.value for e in possible_properties(m, n) ];
|
||||
if value not in options:
|
||||
value = FunctionProperty.NOTHING.value;
|
||||
self.ctrls_property[j].options = options;
|
||||
self.ctrls_property[j].value = value;
|
||||
return;
|
||||
|
||||
if k > 0:
|
||||
upd(k-1);
|
||||
if k < self.N:
|
||||
upd(k);
|
||||
return;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# AUXILIARY METHODS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -204,14 +270,20 @@ def option_to_property(option: str) -> Optional[FunctionProperty]:
|
||||
except:
|
||||
return None;
|
||||
|
||||
def possible_properties(m: int = 1, n: int = 1, all: bool = False) -> list[FunctionProperty]:
|
||||
if not all:
|
||||
if m == 1 and n == 1:
|
||||
def possible_properties(m: int = 1, n: int = 1) -> list[FunctionProperty]:
|
||||
if m == n:
|
||||
if m == 1:
|
||||
return [
|
||||
e for e in FunctionProperty
|
||||
if (is_injective(e) not in [False])
|
||||
and (is_surjective(e) not in [False])
|
||||
];
|
||||
else:
|
||||
return [
|
||||
e for e in FunctionProperty
|
||||
if not (is_surjective(e) in [True] and is_injective(e) in [False])
|
||||
and not (is_surjective(e) in [False] and is_injective(e) in [True])
|
||||
];
|
||||
elif m == 1 and n > 1:
|
||||
return [
|
||||
e for e in FunctionProperty
|
||||
|
Loading…
Reference in New Issue
Block a user