Implementation of a function chaining mechanism
This merge request addresses the issue of function composition and chaining (see #118 (closed)).
The proposed chaining mechanism is based on the idea of flagGeneric
and procGeneric
and comes without additional core
functionality. the relevant function (which really needs a better name, ideas are very welcome) takes an function argument of type Callable[[saqc.core.SaQC], saqc.core.SaQC]
and evaluates this function on a copy of the original SaQC
object.
That implicates, that we simply use the existing evaluation mechanisms provided in core
on a copy of the original and integrate this copy back after evaluation.
To give a more concrete idea of the implementation:
saqc = SaQC(data, flagger)
saqc.functionChain(
fields=["z"],
lambda s: s.flagRange("x", min=0, max=100).flagRange("y", min=0, max=10).procGeneric("z", lambda x, y: x+y)
)
In the above example a (deep) copy of data
and flagger
within a new SaQC
object will be passed to the lambda
function, the the usual SaQC
business is executed and afterwards only the fields given in fields are copied from s
to saqc
.
A few consideration I would like to point out right from the beginning:
- The present implementation is a MVP, working, but not feature complete (although I think it would still be mergable, but that is just me...).
- The MR sit on top of !167 (merged) as the feature move proposed there also solves an issue here. But !167 (merged) is not a prerequisite.
-
fields
can be a collection, which is in contrast to our current policy enforcing scalarfield
s. - Its maybe a bit verbose.
- There is no implementation for the configuration syntax, so this is still a TODO.
- As pointed out within the code, we loose additional arguments to the
SaQC
-Object due to the copy. This is unfortunate, could be resolved, but maybe things get easier, when we restructure the function interface. - And now for the most spectacular feature
🥁 : It is simple and only uses the machinery already present! I mean, come on, it's just 10 LOCs ...