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