From a3a0a150a8440393e40b1518ee4d8a02aeb7ac5f Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Tue, 27 Jul 2021 11:29:52 +0200 Subject: [PATCH] Added element at query --- src/cpl_query/_extension/iterable.py | 7 +++++++ src/cpl_query/_query/element_at.py | 25 +++++++++++++++++++++++++ src/cpl_query/exceptions.py | 1 + src/cpl_query/extension/iterable_abc.py | 6 ++++++ src/cpl_query/tests/query_test.py | 9 +++++++++ 5 files changed, 48 insertions(+) create mode 100644 src/cpl_query/_query/element_at.py diff --git a/src/cpl_query/_extension/iterable.py b/src/cpl_query/_extension/iterable.py index 2361fe67..cb0f868e 100644 --- a/src/cpl_query/_extension/iterable.py +++ b/src/cpl_query/_extension/iterable.py @@ -8,6 +8,7 @@ from .._query.avg import avg_query from .._query.contains import contains_query from .._query.count import count_query from .._query.distinct import distinct_query +from .._query.element_at import element_at_query, element_at_or_default_query from .._query.first import first_or_default_query, first_query from .._query.for_each import for_each_query from .._query.order_by import order_by_query, order_by_descending_query @@ -41,6 +42,12 @@ class Iterable(IterableABC): res.__class__ = Iterable return res + def element_at(self, index: int) -> any: + return element_at_query(self, index) + + def element_at_or_default(self, index: int) -> Optional[any]: + return element_at_or_default_query(self, index) + def first(self) -> any: return first_query(self) diff --git a/src/cpl_query/_query/element_at.py b/src/cpl_query/_query/element_at.py new file mode 100644 index 00000000..67bd514c --- /dev/null +++ b/src/cpl_query/_query/element_at.py @@ -0,0 +1,25 @@ +from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument +from cpl_query.extension.iterable_abc import IterableABC + + +def element_at_query(_list: IterableABC, _index: int) -> any: + if _list is None: + raise ArgumentNoneException(ExceptionArgument.list) + + if _index is None: + raise ArgumentNoneException(ExceptionArgument.index) + + return _list[_index] + + +def element_at_or_default_query(_list: IterableABC, _index: int) -> any: + if _list is None: + raise ArgumentNoneException(ExceptionArgument.list) + + if _index is None: + raise ArgumentNoneException(ExceptionArgument.index) + + try: + return _list[_index] + except IndexError: + return None diff --git a/src/cpl_query/exceptions.py b/src/cpl_query/exceptions.py index c9694221..1b6e550d 100644 --- a/src/cpl_query/exceptions.py +++ b/src/cpl_query/exceptions.py @@ -7,6 +7,7 @@ class ExceptionArgument(Enum): func = 'func' type = 'type' value = 'value' + index = 'index' # exceptions diff --git a/src/cpl_query/extension/iterable_abc.py b/src/cpl_query/extension/iterable_abc.py index bd031833..28cb188b 100644 --- a/src/cpl_query/extension/iterable_abc.py +++ b/src/cpl_query/extension/iterable_abc.py @@ -26,6 +26,12 @@ class IterableABC(ABC, list): @abstractmethod def distinct(self, func: Callable) -> 'IterableABC': pass + @abstractmethod + def element_at(self, index: int) -> any: pass + + @abstractmethod + def element_at_or_default(self, index: int) -> Optional[any]: pass + @abstractmethod def first(self) -> any: pass diff --git a/src/cpl_query/tests/query_test.py b/src/cpl_query/tests/query_test.py index 9a187f3e..2481f60e 100644 --- a/src/cpl_query/tests/query_test.py +++ b/src/cpl_query/tests/query_test.py @@ -91,6 +91,15 @@ class QueryTest(unittest.TestCase): res = self._tests.distinct(lambda u: u.address.nr).where(lambda u: u.address.nr == 5) self.assertEqual(1, len(res)) + def test_element_at(self): + index = randint(0, len(self._tests) - 1) + self.assertEqual(self._tests[index], self._tests.element_at(index)) + + def test_element_at_or_default(self): + index = randint(0, len(self._tests) - 1) + self.assertEqual(self._tests[index], self._tests.element_at_or_default(index)) + self.assertIsNone(self._tests.element_at_or_default(len(self._tests))) + def test_first(self): results = [] for user in self._tests: