master > master: notebook - dynamische Anpassung

- optionen für Fkt-Eigenschaften beschränkt durch Kardinalitäten der Mengen
This commit is contained in:
RD 2022-10-22 18:39:01 +02:00
parent 011fe1d9d9
commit 240c673762

View File

@ -7,6 +7,7 @@
from __future__ import annotations;
from src.thirdparty.code import *;
from src.thirdparty.types import *;
from src.thirdparty.plots import *;
from src.thirdparty.maths import *;
@ -30,12 +31,12 @@ __all__ = [
class FunctionProperty(Enum):
NOTHING = '';
INJECTIVE = 'injektiv';
SURJECTIVE = 'surjektiv';
NOT_INJECTIVE = '¬ injektiv';
SURJECTIVE = 'surjektiv';
NOT_SURJECTIVE = '¬ surjektiv';
BOTH = 'injektiv + surjektiv';
INJECTIVE_NOT_SURJECTIVE = 'injektiv + ¬ surjektiv';
NOT_INJECTIVE_SURJECTIVE = '¬ injektiv + surjektiv';
BOTH = 'injektiv + surjektiv';
NEITHER = '¬ injektiv + ¬ surjektiv';
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -49,6 +50,7 @@ class FunctionDiagramWidget():
fnames: list[str];
setnames: list[str];
setsfrom: list[list[Any]];
card: list[int];
def __init__(
self,
@ -76,6 +78,7 @@ class FunctionDiagramWidget():
];
n = len(setsfrom);
self.setsfrom = [ setsfrom[k % n] for k, name in enumerate(setnames) ];
self.card = [ min(3, len(XX)) for XX in self.setsfrom ];
def run(self):
if self.N is None:
@ -87,11 +90,11 @@ class FunctionDiagramWidget():
display(self.state);
def handler_plot(self, N: int, show_labels: bool, **kwargs):
cardinalities = [ kwargs[f'card_{k}'] for k in range(N+1)];
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, cardinalities) ];
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]}'),
@ -102,18 +105,6 @@ class FunctionDiagramWidget():
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):
@ -129,27 +120,45 @@ class FunctionDiagramWidget():
control_nr = widgets.IntSlider(value=N);
controls_card = [
widgets.IntSlider(
# value = None,
value = min(3,len(XX)),
value = card,
description = f'|{setname}|',
min = 1,
max = len(XX),
)
for setname, XX in zip(self.setnames[:(N+1)], self.setsfrom[:(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 = [
widgets.RadioButtons(
options = [e.value for e in FunctionProperty],
options = [ e.value for e in possible_properties(all=True) ],
value = FunctionProperty.NOTHING.value,
layout = {
'description_width': 'initial',
'width': 'initial',
},
# description = f'Eigenschaften von {self.fnames[k]}',
disabled = False,
)
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, 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 ] \
@ -195,6 +204,38 @@ 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:
return [
e for e in FunctionProperty
if (is_injective(e) not in [False])
and (is_surjective(e) not in [False])
];
elif m == 1 and n > 1:
return [
e for e in FunctionProperty
if (is_injective(e) not in [False])
and (is_surjective(e) not in [True])
];
elif n == 1 and m > 1:
return [
e for e in FunctionProperty
if (is_surjective(e) not in [False])
and (is_injective(e) not in [True])
];
elif m > n:
return [
e for e in FunctionProperty
if (is_injective(e) not in [True])
];
elif n > m:
return [
e for e in FunctionProperty
if (is_surjective(e) not in [True])
];
return [ e for e in FunctionProperty ];
def is_injective(property: Optional[FunctionProperty]) -> Optional[bool]:
match property:
case FunctionProperty.INJECTIVE | FunctionProperty.INJECTIVE_NOT_SURJECTIVE | FunctionProperty.BOTH: