From 662a47d3dc85d1f1cea4542b76c7e52febe731b8 Mon Sep 17 00:00:00 2001
From: Piotr Maslanka <piotr.maslanka@henrietta.com.pl>
Date: Sat, 9 Dec 2017 23:57:02 +0100
Subject: [PATCH] added DomainError

---
 firanka/exceptions.py  |  7 ++++++-
 firanka/intervals.py   | 37 +++++++++++++++++++++----------------
 firanka/series/base.py |  5 ++---
 tests/test_series.py   |  6 +++---
 4 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/firanka/exceptions.py b/firanka/exceptions.py
index b8ae481..d827061 100644
--- a/firanka/exceptions.py
+++ b/firanka/exceptions.py
@@ -4,6 +4,7 @@ from __future__ import print_function, absolute_import, division
 __all__ = [
     'FirankaError',
     'NotInDomainError',
+    'DomainError',
 ]
 
 
@@ -13,7 +14,11 @@ class FirankaError(Exception):
     """
 
 
-class NotInDomainError(FirankaError, ValueError):
+class DomainError(FirankaError):
+    """Has something to do with the domain :)"""
+
+
+class NotInDomainError(DomainError, ValueError):
     """
     Requested index is beyond this domain
     """
diff --git a/firanka/intervals.py b/firanka/intervals.py
index f3ccd68..0ed8eb7 100644
--- a/firanka/intervals.py
+++ b/firanka/intervals.py
@@ -117,27 +117,32 @@ class Interval(object):
 
         self.start, self.stop, self.left_inc, self.right_inc = args
 
+    def _contains_point(self, x):
+        if x == self.start:
+            return self.left_inc
+
+        if x == self.stop:
+            return self.right_inc
+
+        return self.start < x < self.stop
+
+    @_pre_range
+    def _contains_interval(self, x):
+        if ((x.start == self.start) and (x.left_inc ^ self.left_inc)) \
+                or ((x.stop == self.stop) and (x.right_inc ^ self.right_inc)):
+            return False
+
+        return (x.start >= self.start) and (x.stop <= self.stop)
+
     def __contains__(self, x):
         """
         :type x: index or a Interval
         """
-        if isinstance(x, six.string_types):
-            x = Interval(x)
-
-        if isinstance(x, Interval):
-            if ((x.start == self.start) and (x.left_inc ^ self.left_inc)) \
-                    or ((x.stop == self.stop) and (x.right_inc ^ self.right_inc)):
-                return False
-
-            return (x.start >= self.start) and (x.stop <= self.stop)
+        if isinstance(x, six.string_types) or isinstance(x, Interval):
+            return self._contains_interval(x)
         else:
-            if x == self.start:
-                return self.left_inc
-
-            if x == self.stop:
-                return self.right_inc
+            return self._contains_point(x)
 
-            return self.start < x < self.stop
 
     def is_empty(self):
         return (self.start == self.stop) and not (
@@ -153,7 +158,7 @@ class Interval(object):
 
     def __getitem__(self, item):
         if not isinstance(item, slice):
-            raise ValueError('must be a slice')
+            raise TypeError('must be a slice')
 
         return self.intersection(Interval(item))
 
diff --git a/firanka/series/base.py b/firanka/series/base.py
index 2f812f2..aee8b22 100644
--- a/firanka/series/base.py
+++ b/firanka/series/base.py
@@ -5,7 +5,7 @@ import inspect
 
 from sortedcontainers import SortedList
 
-from firanka.exceptions import NotInDomainError
+from firanka.exceptions import NotInDomainError, DomainError
 from firanka.intervals import Interval, EMPTY_SET
 
 
@@ -127,8 +127,7 @@ class DiscreteSeries(Series):
 
         if len(data) > 0:
             if self.domain.start < data[0][0]:
-                raise ValueError(
-                    'some domain space is not covered by definition!')
+                raise DomainError('some domain space is not covered by definition!')
 
     def apply(self, fun):
         assert _has_arguments(fun, 2), 'fun must have at least 2 arguments'
diff --git a/tests/test_series.py b/tests/test_series.py
index 0329e8c..c947e31 100644
--- a/tests/test_series.py
+++ b/tests/test_series.py
@@ -4,7 +4,7 @@ from __future__ import print_function, absolute_import, division
 import math
 import unittest
 
-from firanka.exceptions import NotInDomainError
+from firanka.exceptions import NotInDomainError, DomainError
 from firanka.intervals import Interval
 from firanka.series import DiscreteSeries, FunctionSeries, ModuloSeries, \
     LinearInterpolationSeries, Series
@@ -27,7 +27,7 @@ class TestDiscreteSeries(unittest.TestCase):
         a.join(b, lambda i, x, y: x + y)
 
     def test_uncov(self):
-        self.assertRaises(ValueError,
+        self.assertRaises(DomainError,
                           lambda: DiscreteSeries([[0, 0], [1, 1], [2, 2]],
                                                  '<-5;2>'))
 
@@ -124,7 +124,7 @@ class TestDiscreteSeries(unittest.TestCase):
 
     def test_discretize(self):
         # note the invalid data for covering this domain
-        self.assertRaises(ValueError, lambda: FunctionSeries(lambda x: x ** 2,
+        self.assertRaises(DomainError, lambda: FunctionSeries(lambda x: x ** 2,
                                                              '<-10;10)').discretize(
             [0, 1, 2, 3, 4, 5], '(-1;6)'))
 
-- 
GitLab