From 67b3ee545ae9e8b6e45897c651e1b5b2923a7a05 Mon Sep 17 00:00:00 2001
From: Piotr Maslanka <piotr.maslanka@henrietta.com.pl>
Date: Sat, 9 Dec 2017 23:49:33 +0100
Subject: [PATCH] go

---
 firanka/__init__.py                        |  2 +-
 firanka/builders.py                        | 11 ++---------
 firanka/intervals.py                       | 18 ++++++++++++++++++
 tests/{test_range.py => test_intervals.py} | 10 +++++++++-
 4 files changed, 30 insertions(+), 11 deletions(-)
 rename tests/{test_range.py => test_intervals.py} (88%)

diff --git a/firanka/__init__.py b/firanka/__init__.py
index e6d0c4f..8ae966b 100644
--- a/firanka/__init__.py
+++ b/firanka/__init__.py
@@ -1 +1 @@
-__version__ = '0.1.12'
+__version__ = '0.1.13rc1'
diff --git a/firanka/builders.py b/firanka/builders.py
index 028ea68..2c6e0d8 100644
--- a/firanka/builders.py
+++ b/firanka/builders.py
@@ -5,7 +5,6 @@ import copy
 
 from sortedcontainers import SortedList
 
-from .intervals import Interval
 from .series import DiscreteSeries
 
 """
@@ -21,7 +20,7 @@ class DiscreteSeriesBuilder(object):
     def __init__(self, series=None):
 
         if series is None:
-            series = DiscreteSeries([], '(0;0)')
+            series = DiscreteSeries([])
 
         if not isinstance(series, DiscreteSeries):
             raise TypeError('discrete knowledge builder supports only discrete series')
@@ -31,13 +30,7 @@ class DiscreteSeriesBuilder(object):
         self.series = series
 
     def put(self, index, value):
-
-        if index not in self.domain:
-            if index <= self.domain.start:
-                self.domain = Interval(index, self.domain.stop, True, self.domain.right_inc)
-            if index >= self.domain.stop:
-                self.domain = Interval(self.domain.start, index, self.domain.left_inc, True)
-
+        self.domain = self.domain.extend_to_point(index)
         self.new_data[index] = value
 
     def as_series(self):
diff --git a/firanka/intervals.py b/firanka/intervals.py
index 1ec6354..f3ccd68 100644
--- a/firanka/intervals.py
+++ b/firanka/intervals.py
@@ -28,6 +28,24 @@ class Interval(object):
     """
     __slots__ = ('start', 'stop', 'left_inc', 'right_inc')
 
+    def extend_to_point(self, p):
+        """
+        Return a minimally extended interval required to grab point p
+        :param p: a point, float
+        :return: new Interval
+        """
+        if p in self:
+            return self
+        elif self.is_empty():
+            return Interval(p, p)
+        else:
+            if p <= self.start:
+                return Interval(p, self.stop, not math.isinf(p), self.right_inc)
+            elif p >= self.stop:
+                return Interval(self.start, p, self.left_inc, not math.isinf(p))
+            else:
+                raise RuntimeError('Cannot happen!')
+
     @_pre_range
     def __add__(self, other):
         if self.start > other.start:
diff --git a/tests/test_range.py b/tests/test_intervals.py
similarity index 88%
rename from tests/test_range.py
rename to tests/test_intervals.py
index 467d2c9..f02bf53 100644
--- a/tests/test_range.py
+++ b/tests/test_intervals.py
@@ -6,7 +6,7 @@ import unittest
 from firanka.intervals import Interval
 
 
-class TestRange(unittest.TestCase):
+class TestIntervals(unittest.TestCase):
     def do_intersect(self, a, b, val):
         if type(val) == bool:
             p = Interval(a).intersection(b)
@@ -52,6 +52,14 @@ class TestRange(unittest.TestCase):
         r = Interval(1, 2, True, False)
         self.assertEqual(r, Interval(r))
 
+    def test_extend(self):
+        i = Interval('(-1;1)')
+
+        self.assertEqual(i.extend_to_point(-1), '<-1;1)')
+        self.assertEqual(i.extend_to_point(1), '(-1;1>')
+        self.assertEqual(i.extend_to_point(float('inf')), '(-1;inf)')
+        self.assertEqual(i.extend_to_point(float('-inf')), '(-inf;1)')
+
     def test_contains(self):
         self.assertFalse(-1 in Interval('<-10;-1)'))
         self.assertTrue(-10 in Interval('<-10;-1)'))
-- 
GitLab