Skip to content

Commit

Permalink
core.LenaSequence gets an initialiser with the sequence.
Browse files Browse the repository at this point in the history
  • Loading branch information
ynikitenko committed Sep 1, 2023
1 parent 8b85a93 commit 090ddb7
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 46 deletions.
51 changes: 42 additions & 9 deletions lena/core/fill_compute_seq.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

def _init_sequence_with_el(self, args, el_attr, check_el_type,
el_name, seq_name):
# todo: remove after we remove FillRequestSeq
before = []
after = []
el = None
Expand Down Expand Up @@ -78,13 +79,46 @@ def __init__(self, *args):
could not be correctly initialized,
:exc:`.LenaTypeError` is raised.
"""
# *args* can consist of one tuple, which is in that case expanded.
_init_sequence_with_el(
self, args, "_fill_compute",
check_sequence_type.is_fill_compute_el,
el_name="FillCompute", seq_name="FillComputeSeq"
)
before = []
fc_el = None
after = []

# same as for Sequence
if len(args) == 1 and isinstance(args[0], tuple):
args = args[0]

for ind, el in enumerate(args):
if not check_sequence_type.is_fill_compute_el(el):
before.append(el)
else:
fc_el = el
break

if fc_el is None:
raise exceptions.LenaTypeError(
"FillComputeSeq must contain a FillCompute element, "
"none provided: {}".format(args)
)
self._fill_compute = fc_el

for el in args[ind+1:]:
after.append(el)

before.append(fc_el)
try:
before_seq = fill_seq.FillSeq(*before)
except exceptions.LenaTypeError as err:
raise err
self._fill_seq = before_seq
self.fill = self._fill_seq.fill
# to do: do we check for exceptions like above
# or skip like here?
self._after = sequence.Sequence(*after)

self._name = "FillComputeSeq"
seq = list(before_seq)
seq.extend(self._after._seq)
super(FillComputeSeq, self).__init__(*seq)

def fill(self, value):
"""Fill *self* with *value*.
Expand All @@ -102,9 +136,8 @@ def compute(self):
it postprocesses the results yielded
from *FillCompute* element.
"""
vals = self._fill_compute.compute()

results = self._after.run(vals)
flow = self._fill_compute.compute()
results = self._after.run(flow)
return results

def __eq__(self, other):
Expand Down
28 changes: 14 additions & 14 deletions lena/core/fill_seq.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def __init__(self, *args):
or if an *args* is empty,
:exc:`.LenaTypeError` is raised.
"""
self._seq = []
self._name = "FillSeq"
seq = []

if not args:
raise exceptions.LenaTypeError(
Expand All @@ -54,33 +53,34 @@ def __init__(self, *args):
"{} given".format(args[-1])
)
# convert all elements except last to FillInto (if needed)
for elem in args[:-1]:
fill_into = getattr(elem, "fill_into", None)
if callable(fill_into):
# default method found
self._seq.append(elem)
for el in args[:-1]:
if hasattr(el, "fill_into") and callable(el.fill_into):
seq.append(el)
else:
# try to convert to FillInto
# try to convert to FillInto (e.g. Call)
try:
fill_into_elem = adapters.FillInto(elem, explicit=False)
fill_into_el = adapters.FillInto(el, explicit=False)
except exceptions.LenaTypeError:
raise exceptions.LenaTypeError(
"arguments must implement fill_into method, "
"or be convertible to FillInto, "
"{} given".format(elem)
"{} given".format(el)
)
else:
self._seq.append(fill_into_elem)
self._seq.append(args[-1])
# transform FillInto elements to _Fill
seq.append(fill_into_el)
seq.append(args[-1])
# transform FillInto elements into _Fill
fill_el = args[-1]
for el in reversed(self._seq[:-1]):
for el in reversed(seq[:-1]):
fill_el = _Fill(el, fill_el)
# note that self._seq consists of original FillInto elements.
self._fill_el = fill_el
# self for these methods is different
self.fill = fill_el.fill

self._name = "FillSeq" # for repr
super(FillSeq, self).__init__(*seq)

def fill(self, value):
"""Fill *value* into an *element*.
Expand Down
5 changes: 2 additions & 3 deletions lena/core/lena_sequence.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
"""LenaSequence abstract base class."""


# pylint: disable=no-member
# this is an abstract base class and _seq will be defined in subclasses

class LenaSequence(object):
"""Abstract base class for all Lena sequences.
A sequence consists of elements.
*LenaSequence* provides methods to iterate over a sequence,
get its length and get an item at the given index.
"""
def __init__(self, *args):
self._seq = args

def __iter__(self):
return self._seq.__iter__()
Expand Down
28 changes: 15 additions & 13 deletions lena/core/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,33 @@ def __init__(self, *args):
For more information about the *run* method and callables,
see :class:`Run`.
"""
self._seq = []
seq = []

# Sequence can be initialized from a single tuple
if len(args) == 1 and isinstance(args[0], tuple):
args = args[0]

for elem in args:
run = getattr(elem, "run", None)
if callable(run):
self._seq.append(elem)
for el in args:
if hasattr(el, "run") and callable(el.run):
seq.append(el)
else:
try:
run_elem = adapters.Run(elem)
# convert to a Run element
# (for example, el could be a Call)
run_el = adapters.Run(el)
except exceptions.LenaTypeError:
raise exceptions.LenaTypeError(
"arguments must implement run method, "
"or be callable generators (convertible to Run), "
"{} given".format(elem)
"{} given".format(el)
)
else:
self._seq.append(run_elem)
seq.append(run_el)
# _name is used for representation.
# Subclass must set its own name or provide a different repr
self._name = "Sequence"
# we don't call super init (yet),
# because it has no variables (and no init)
# https://softwareengineering.stackexchange.com/a/318171/42050

super(Sequence, self).__init__(*seq)

def run(self, flow):
"""Generator, which transforms the incoming flow.
Expand All @@ -65,8 +67,8 @@ def run(self, flow):
"""
flow = functions.flow_to_iter(flow)

for elem in self._seq:
flow = elem.run(flow)
for el in self:
flow = el.run(flow)

flow = functions.flow_to_iter(flow)

Expand Down
16 changes: 9 additions & 7 deletions lena/core/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,24 @@ def __init__(self, *args):
+ "must be callable"
)
self._first = args[0]
# _seq is an attribute of LenaSequence
self._seq = [self._first]

seq = [self._first]
if len(args) > 1:
self._sequence = sequence.Sequence(*args[1:])
self._seq.extend(args[1:])
seq.extend(args[1:])
else:
self._sequence = ()
self._name = "Source"

self._name = "Source" # for repr
super(Source, self).__init__(*seq)

def __call__(self):
"""Generate flow."""
arg = self._first()
flow = self._first()
if self._sequence:
return self._sequence.run(arg)
return self._sequence.run(flow)
else:
return functions.flow_to_iter(arg)
return functions.flow_to_iter(flow)

def __eq__(self, other):
if not isinstance(other, Source):
Expand Down

0 comments on commit 090ddb7

Please sign in to comment.