master > master: notebook - dynamische Anpassung
- optionen für Fkt-Eigenschaften beschränkt durch Kardinalitäten der Mengen
This commit is contained in:
parent
011fe1d9d9
commit
240c673762
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations;
|
from __future__ import annotations;
|
||||||
|
|
||||||
|
from src.thirdparty.code import *;
|
||||||
from src.thirdparty.types import *;
|
from src.thirdparty.types import *;
|
||||||
from src.thirdparty.plots import *;
|
from src.thirdparty.plots import *;
|
||||||
from src.thirdparty.maths import *;
|
from src.thirdparty.maths import *;
|
||||||
@ -30,12 +31,12 @@ __all__ = [
|
|||||||
class FunctionProperty(Enum):
|
class FunctionProperty(Enum):
|
||||||
NOTHING = '—';
|
NOTHING = '—';
|
||||||
INJECTIVE = 'injektiv';
|
INJECTIVE = 'injektiv';
|
||||||
SURJECTIVE = 'surjektiv';
|
|
||||||
NOT_INJECTIVE = '¬ injektiv';
|
NOT_INJECTIVE = '¬ injektiv';
|
||||||
|
SURJECTIVE = 'surjektiv';
|
||||||
NOT_SURJECTIVE = '¬ surjektiv';
|
NOT_SURJECTIVE = '¬ surjektiv';
|
||||||
|
BOTH = 'injektiv + surjektiv';
|
||||||
INJECTIVE_NOT_SURJECTIVE = 'injektiv + ¬ surjektiv';
|
INJECTIVE_NOT_SURJECTIVE = 'injektiv + ¬ surjektiv';
|
||||||
NOT_INJECTIVE_SURJECTIVE = '¬ injektiv + surjektiv';
|
NOT_INJECTIVE_SURJECTIVE = '¬ injektiv + surjektiv';
|
||||||
BOTH = 'injektiv + surjektiv';
|
|
||||||
NEITHER = '¬ injektiv + ¬ surjektiv';
|
NEITHER = '¬ injektiv + ¬ surjektiv';
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -49,6 +50,7 @@ class FunctionDiagramWidget():
|
|||||||
fnames: list[str];
|
fnames: list[str];
|
||||||
setnames: list[str];
|
setnames: list[str];
|
||||||
setsfrom: list[list[Any]];
|
setsfrom: list[list[Any]];
|
||||||
|
card: list[int];
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -76,6 +78,7 @@ class FunctionDiagramWidget():
|
|||||||
];
|
];
|
||||||
n = len(setsfrom);
|
n = len(setsfrom);
|
||||||
self.setsfrom = [ setsfrom[k % n] for k, name in enumerate(setnames) ];
|
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):
|
def run(self):
|
||||||
if self.N is None:
|
if self.N is None:
|
||||||
@ -87,11 +90,11 @@ class FunctionDiagramWidget():
|
|||||||
display(self.state);
|
display(self.state);
|
||||||
|
|
||||||
def handler_plot(self, N: int, show_labels: bool, **kwargs):
|
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)];
|
properties = [ option_to_property(kwargs[f'property_{k}']) for k in range(N)];
|
||||||
injective = list(map(is_injective, properties));
|
injective = list(map(is_injective, properties));
|
||||||
surjective = list(map(is_surjective, 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(*[
|
comp = Functions(*[
|
||||||
Function(
|
Function(
|
||||||
name = (f'{self.fnames[k]}', f'{self.setnames[k]}', f'{self.setnames[k+1]}'),
|
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)
|
for k in range(N)
|
||||||
]);
|
]);
|
||||||
fig, axs = comp.draw(show_labels=show_labels);
|
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;
|
return;
|
||||||
|
|
||||||
def handler_wrapper(self, N: int):
|
def handler_wrapper(self, N: int):
|
||||||
@ -129,27 +120,45 @@ class FunctionDiagramWidget():
|
|||||||
control_nr = widgets.IntSlider(value=N);
|
control_nr = widgets.IntSlider(value=N);
|
||||||
controls_card = [
|
controls_card = [
|
||||||
widgets.IntSlider(
|
widgets.IntSlider(
|
||||||
# value = None,
|
value = card,
|
||||||
value = min(3,len(XX)),
|
|
||||||
description = f'|{setname}|',
|
description = f'|{setname}|',
|
||||||
min = 1,
|
min = 1,
|
||||||
max = len(XX),
|
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 = [
|
controls_property = [
|
||||||
widgets.RadioButtons(
|
widgets.RadioButtons(
|
||||||
options = [e.value for e in FunctionProperty],
|
options = [ e.value for e in possible_properties(all=True) ],
|
||||||
value = FunctionProperty.NOTHING.value,
|
value = FunctionProperty.NOTHING.value,
|
||||||
layout = {
|
layout = {
|
||||||
'description_width': 'initial',
|
'description_width': 'initial',
|
||||||
'width': 'initial',
|
'width': 'initial',
|
||||||
},
|
},
|
||||||
# description = f'Eigenschaften von {self.fnames[k]}',
|
|
||||||
disabled = False,
|
disabled = False,
|
||||||
)
|
)
|
||||||
for k in range(N)
|
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(
|
ui = widgets.VBox(
|
||||||
[ button_refresh ] \
|
[ button_refresh ] \
|
||||||
+ [ button_show_labels ] \
|
+ [ button_show_labels ] \
|
||||||
@ -195,6 +204,38 @@ def option_to_property(option: str) -> Optional[FunctionProperty]:
|
|||||||
except:
|
except:
|
||||||
return None;
|
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]:
|
def is_injective(property: Optional[FunctionProperty]) -> Optional[bool]:
|
||||||
match property:
|
match property:
|
||||||
case FunctionProperty.INJECTIVE | FunctionProperty.INJECTIVE_NOT_SURJECTIVE | FunctionProperty.BOTH:
|
case FunctionProperty.INJECTIVE | FunctionProperty.INJECTIVE_NOT_SURJECTIVE | FunctionProperty.BOTH:
|
||||||
|
Loading…
Reference in New Issue
Block a user