From 1ed3e094a0fa402cf777cd023f78d2f14e10168a Mon Sep 17 00:00:00 2001
From: Piotr Maslanka <piotr.maslanka@henrietta.com.pl>
Date: Sat, 9 Dec 2017 22:46:35 +0100
Subject: [PATCH] extra asserts

---
 README.md              | 22 ++++++++++++++++++++++
 firanka/series/base.py | 11 +++++++++++
 tests/test_series.py   |  2 +-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index edaad25..a431d0b 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 2855e20..b31c3ad 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 627ecfa..8c4301b 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):
-- 
GitLab