From 9bcc5df0be22633892ebd162ce074b10306fbf21 Mon Sep 17 00:00:00 2001
From: Piotr Maslanka <piotr.maslanka@henrietta.com.pl>
Date: Sat, 9 Dec 2017 08:52:22 +0100
Subject: [PATCH] refactor

---
 README.md                             |  8 +++
 firanka/series/__init__.py            | 14 +++++
 firanka/{series.py => series/base.py} | 77 +--------------------------
 firanka/series/linear.py              | 45 ++++++++++++++++
 firanka/series/modulo.py              | 39 ++++++++++++++
 5 files changed, 107 insertions(+), 76 deletions(-)
 create mode 100644 firanka/series/__init__.py
 rename firanka/{series.py => series/base.py} (77%)
 create mode 100644 firanka/series/linear.py
 create mode 100644 firanka/series/modulo.py

diff --git a/README.md b/README.md
index 479fe21..97a694c 100644
--- a/README.md
+++ b/README.md
@@ -98,6 +98,14 @@ By definition, _ModuloSeries_ has the domain of all real numbers.
 Note that someOtherSeries's domain length must be non-zero and finite. Otherwise
 _ValueError_ will be thrown.
 
+## LinearInterpolationSeries
+
+These are discretes, but allow you to define an operator that will
+take its neighbours into account and let you return a custom value.
+
+By default, it will assumes that values can be added, subbed, multed and dived,
+and will do classical linear interpolation.
+
 ## Ranges
 
 Can be imported from _sai.ranges_.
diff --git a/firanka/series/__init__.py b/firanka/series/__init__.py
new file mode 100644
index 0000000..0a890c4
--- /dev/null
+++ b/firanka/series/__init__.py
@@ -0,0 +1,14 @@
+# coding=UTF-8
+from __future__ import absolute_import
+from .base import FunctionSeries, DiscreteSeries, Series
+from .linear import LinearInterpolationSeries, SCALAR_LINEAR_INTERPOLATOR
+from .modulo import ModuloSeries
+
+__all__ = [
+    'FunctionSeries',
+    'DiscreteSeries',
+    'ModuloSeries',
+    'Series',
+    'SCALAR_LINEAR_INTERPOLATOR',
+    'LinearInterpolationSeries',
+]
diff --git a/firanka/series.py b/firanka/series/base.py
similarity index 77%
rename from firanka/series.py
rename to firanka/series/base.py
index 606a187..52a6d16 100644
--- a/firanka/series.py
+++ b/firanka/series/base.py
@@ -8,14 +8,7 @@ import six
 from firanka.exceptions import NotInDomainError
 from firanka.ranges import Range, REAL_SET, EMPTY_SET
 
-__all__ = [
-    'FunctionSeries',
-    'DiscreteSeries',
-    'ModuloSeries',
-    'Series',
-    'SCALAR_LINEAR_INTERPOLATOR',
-    'LinearInterpolationSeries',
-]
+
 
 
 class Series(object):
@@ -289,71 +282,3 @@ class JoinedSeries(Series):
     def _get_for(self, item):
         return self.op(self.ser1._get_for(item), self.ser2._get_for(item))
 
-
-class ModuloSeries(Series):
-    def __init__(self, series, *args, **kwargs):
-        """
-        Construct a modulo series
-        :param series: base series to use
-        :raise ValueError: invalid domain length
-        """
-        super(ModuloSeries, self).__init__(REAL_SET, *args, **kwargs)
-
-        self.series = series
-        self.period = self.series.domain.length()
-
-        if self.period == 0:
-            raise ValueError('Modulo series cannot have a period of 0')
-        elif math.isinf(self.period):
-            raise ValueError('Modulo series cannot have an infinite period')
-
-    def _get_for(self, item):
-        if item < 0:
-            item = -(item // self.period) * self.period + item
-        elif item > self.period:
-            item = item - (item // self.period) * self.period
-        elif item == self.period:
-            item = 0
-
-        return self.series._get_for(self.series.domain.start + item)
-
-
-def SCALAR_LINEAR_INTERPOLATOR(t0, v0, t1, v1, tt):
-    """
-    Good intepolator if our values can be added, subtracted, multiplied and divided
-    """
-    return v0 + (tt-t0) * (t1-t0)/(v1-v0)
-
-
-class LinearInterpolationSeries(DiscreteSeries):
-
-    def __init__(self, data, domain=None,
-                 interpolator=lambda t0, v0, t1, v1, tt: v0
-                 , *args, **kwargs):
-        """
-        :param interpolator: callable(t0: float, v0: any, t1: float, v1: any, tt: float) -> any
-            This, given intepolation points (t0, v0) and (t1, v1) such that t0 <= tt <= t1,
-            return a value for index tt
-        """
-        self.interpolator = interpolator
-        if isinstance(data, DiscreteSeries):
-            self.data = data.data
-            self.domain = domain or data.domain
-        else:
-            super(LinearInterpolationSeries, self).__init__(data, domain, *args, **kwargs)
-
-    def _get_for(self, item):
-        if item == self.domain.start:
-            return self.data[0][1]
-
-        if len(self.data) == 1:
-            return super(LinearInterpolationSeries, self).__getitem__(item)
-
-        for i in six.moves.range(0, len(self.data)-1):
-            cur_i, cur_v = self.data[i]
-            next_i, next_v = self.data[i+1]
-
-            if cur_i <= item <= next_i:
-                return self.interpolator(cur_i, cur_v, next_i, next_v, item)
-
-        return self.data[-1][1]
diff --git a/firanka/series/linear.py b/firanka/series/linear.py
new file mode 100644
index 0000000..5814bcb
--- /dev/null
+++ b/firanka/series/linear.py
@@ -0,0 +1,45 @@
+# coding=UTF-8
+from __future__ import print_function, absolute_import, division
+import six
+
+from .base import DiscreteSeries
+
+
+def SCALAR_LINEAR_INTERPOLATOR(t0, v0, t1, v1, tt):
+    """
+    Good intepolator if our values can be added, subtracted, multiplied and divided
+    """
+    return v0 + (tt-t0) * (t1-t0)/(v1-v0)
+
+
+class LinearInterpolationSeries(DiscreteSeries):
+
+    def __init__(self, data, domain=None, interpolator=SCALAR_LINEAR_INTERPOLATOR,
+                 *args, **kwargs):
+        """
+        :param interpolator: callable(t0: float, v0: any, t1: float, v1: any, tt: float) -> any
+            This, given intepolation points (t0, v0) and (t1, v1) such that t0 <= tt <= t1,
+            return a value for index tt
+        """
+        self.interpolator = interpolator
+        if isinstance(data, DiscreteSeries):
+            self.data = data.data
+            self.domain = domain or data.domain
+        else:
+            super(LinearInterpolationSeries, self).__init__(data, domain, *args, **kwargs)
+
+    def _get_for(self, item):
+        if item == self.domain.start:
+            return self.data[0][1]
+
+        if len(self.data) == 1:
+            return super(LinearInterpolationSeries, self).__getitem__(item)
+
+        for i in six.moves.range(0, len(self.data)-1):
+            cur_i, cur_v = self.data[i]
+            next_i, next_v = self.data[i+1]
+
+            if cur_i <= item <= next_i:
+                return self.interpolator(cur_i, cur_v, next_i, next_v, item)
+
+        return self.data[-1][1]
diff --git a/firanka/series/modulo.py b/firanka/series/modulo.py
new file mode 100644
index 0000000..665ea72
--- /dev/null
+++ b/firanka/series/modulo.py
@@ -0,0 +1,39 @@
+# coding=UTF-8
+from __future__ import print_function, absolute_import, division
+import six
+import logging
+import math
+
+from .base import Series
+from ..ranges import REAL_SET
+
+
+class ModuloSeries(Series):
+    def __init__(self, series, *args, **kwargs):
+        """
+        Construct a modulo series
+        :param series: base series to use
+        :raise ValueError: invalid domain length
+        """
+        super(ModuloSeries, self).__init__(REAL_SET, *args, **kwargs)
+
+        self.series = series
+        self.period = self.series.domain.length()
+
+        if self.period == 0:
+            raise ValueError('Modulo series cannot have a period of 0')
+        elif math.isinf(self.period):
+            raise ValueError('Modulo series cannot have an infinite period')
+
+    def _get_for(self, item):
+        if item < 0:
+            item = -(item // self.period) * self.period + item
+        elif item > self.period:
+            item = item - (item // self.period) * self.period
+        elif item == self.period:
+            item = 0
+
+        return self.series._get_for(self.series.domain.start + item)
+
+
+
-- 
GitLab