diff --git a/README.md b/README.md index edaad25dbe128aa0e0a75338471991814e679806..a431d0b1cb853ddf30baa5776414626504791a14 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,14 @@ Series are immutable, but non-hashable. Read the source code of the [base class](firanka/series/series.py#L11) to get to know more about series operations. + +### Applying and joining + +Applying requires a callable(index: float, value: current value) -> value. +Joining requires a callable(index: float, valueSelf, valueOther: values from self and other table) -> value. + + + ### DiscreteSeries To use a _DiscreteSeries_ you must give it a set of data to work with. These @@ -116,6 +124,20 @@ any other discrete series would be. Sometimes you just need to update a DiscreteSeries, or to blang a brand new one. This little fella will help you out. +You can pass a DiscreteSeries to build on or start from stratch: +```python +kb = DiscreteSeriesBuilder(series) +kb = DiscreteSeriesBuilder() + +kb.put(1,2) + +series = kb.as_series() +isinstance(series, DiscreteSeries) +``` + +By calling `as_series()` you get a new DiscreteSeries instance returned. + + ## Ranges Can be imported from _sai.ranges_. diff --git a/firanka/series/base.py b/firanka/series/base.py index 2855e208337b741c37aaca02b9bb6e2325a111c1..b31c3ad802f20e7b24953c4a2624db7bf0f3b45a 100644 --- a/firanka/series/base.py +++ b/firanka/series/base.py @@ -2,12 +2,17 @@ from __future__ import print_function, absolute_import, division import six +import inspect from firanka.exceptions import NotInDomainError from firanka.ranges import Range, EMPTY_SET from sortedcontainers import SortedList +def has_arguments(fun, n): + return len(inspect.getargspec(fun).args) == n + + class Series(object): """ Abstract, base class for series. @@ -60,6 +65,8 @@ class Series(object): :param fun: callable(index: float, value: any) => 1 :return: Series instance """ + assert has_arguments(fun, 2), 'Callable to apply needs 2 arguments' + return AlteredSeries(self, applyfun=fun) def discretize(self, points, domain=None): @@ -87,6 +94,8 @@ class Series(object): :param fun: callable(t: float, v1: any, v2: any) => value :return: new Series instance """ + assert has_arguments(fun, 3), 'Callable to join needs 3 arguments' + return JoinedSeries(self, series, fun) def translate(self, x): @@ -241,6 +250,8 @@ class JoinedSeries(Series): def __init__(self, ser1, ser2, op, *args, **kwargs): """:type op: callable(time: float, v1, v2: any) -> v""" + assert has_arguments(op, 3), 'op must have 3 arguments' + super(JoinedSeries, self).__init__(ser1.domain.intersection(ser2.domain), *args, **kwargs) self.ser1 = ser1 self.ser2 = ser2 diff --git a/tests/test_series.py b/tests/test_series.py index 627ecfa531528f98020ac510be8981bcc231cadf..8c4301b8d8bb233593cffb0b62c5274309dc0a78 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -207,7 +207,7 @@ class TestModuloSeries(unittest.TestCase): ser1 = ModuloSeries(FunctionSeries(lambda x: x ** 2, '<0;3)')) ser2 = FunctionSeries(NOOP, '<0;3)') - ser3 = ser1.join(ser2, lambda x, y: x * y) + ser3 = ser1.join(ser2, lambda i, x, y: x * y) class TestLinearInterpolation(unittest.TestCase):