Skip to content

Commit

Permalink
merge: Update the demo notebooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Wuestengecko committed Sep 25, 2023
2 parents dca9e94 + 51e8fd4 commit 4918a17
Show file tree
Hide file tree
Showing 13 changed files with 1,092 additions and 650 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ target/

# Jupyter Notebook
.ipynb_checkpoints
.virtual_documents

# IPython
profile_default/
Expand Down
67 changes: 67 additions & 0 deletions capellambse/model/common/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
_NOT_SPECIFIED = object()
"Used to detect unspecified optional arguments"

_MapFunction: te.TypeAlias = (
"cabc.Callable[[T], GenericElement | cabc.Iterable[GenericElement]]"
)


def attr_equal(attr: str) -> cabc.Callable[[type[T]], type[T]]:
def add_wrapped_eq(cls: type[T]) -> type[T]:
Expand Down Expand Up @@ -845,6 +849,69 @@ def keys(self) -> ElementListMapKeyView:
def values(self) -> ElementList[T]:
return self

def filter(
self, predicate: str | cabc.Callable[[T], bool]
) -> ElementList[T]:
"""Filter this list with a custom predicate.
The predicate may be the name of an attribute or a callable,
which will be called on each list item. If the attribute value
or the callable's return value is truthy, the item is included
in the resulting list.
When specifying the name of an attribute, nested attributes can
be chained using ``.``, like ``"parent.name"`` (which would
pick all elements whose ``parent`` has a non-empty ``name``).
"""
if isinstance(predicate, str):
predicate = operator.attrgetter(predicate)
return self._newlist([i._element for i in self if predicate(i)])

def map(self, attr: str | _MapFunction[T]) -> ElementList[GenericElement]:
"""Apply a function to each element in this list.
If the argument is a string, it is interpreted as an attribute
name, and the value of that attribute is returned for each
element. Nested attribute names can be chained with ``.``.
If the argument is a callable, it is called for each element,
and the return value is included in the result. If the callable
returns a sequence, the sequence is flattened into the result.
Duplicate values and Nones are always filtered out.
It is an error if a callable returns something that is not a
model element or a flat sequence of model elements.
"""
if isinstance(attr, str):
attr = operator.attrgetter(attr)
newelems: list[etree._Element] = []
classes: set[type[GenericElement]] = set()
for i in self:
try:
value = attr(i)
except AttributeError:
continue

if not isinstance(value, cabc.Iterable):
value = [value]

for v in value: # type: ignore[union-attr] # false-positive
if v is None:
continue
if isinstance(v, GenericElement):
newelems.append(v._element)
classes.add(type(v))
else:
raise TypeError(
f"Map function must return a model element or a list"
f" of model elements, not {v!r}"
)

if len(classes) == 1:
return ElementList(self._model, newelems, classes.pop())
return MixedElementList(self._model, newelems)


class CachedElementList(ElementList[T], t.Generic[T]):
"""An ElementList that caches the constructed proxies by UUID."""
Expand Down
247 changes: 152 additions & 95 deletions docs/source/examples/01 Introduction.ipynb

Large diffs are not rendered by default.

412 changes: 236 additions & 176 deletions docs/source/examples/02 Intro to Physical Architecture API.ipynb

Large diffs are not rendered by default.

137 changes: 96 additions & 41 deletions docs/source/examples/03 Data Values.ipynb

Large diffs are not rendered by default.

Loading

0 comments on commit 4918a17

Please sign in to comment.