Improved Sequences

This commit is contained in:
Sven Heidemann 2022-09-14 23:01:52 +02:00
parent f0ed0bd2e1
commit 52069b7bb3
6 changed files with 50 additions and 47 deletions

View File

@ -5,7 +5,7 @@ from typing import Optional, Callable, Union
class QueryableABC(ABC): class QueryableABC(ABC):
@abstractmethod @abstractmethod
def all(self, _func: Callable) -> bool: def all(self, _func: Callable = None) -> bool:
r"""Checks if every element of list equals result found by function r"""Checks if every element of list equals result found by function
Parameter Parameter
@ -20,7 +20,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def any(self, _func: Callable) -> bool: def any(self, _func: Callable = None) -> bool:
r"""Checks if list contains result found by function r"""Checks if list contains result found by function
Parameter Parameter
@ -35,7 +35,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def average(self, _func: Callable) -> Union[int, float, complex]: def average(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Returns average value of list r"""Returns average value of list
Parameter Parameter
@ -145,7 +145,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def for_each(self, _func: Callable): def for_each(self, _func: Callable = None):
r"""Runs given function for each element of list r"""Runs given function for each element of list
Parameter Parameter
@ -174,8 +174,9 @@ class QueryableABC(ABC):
Last element of list: Optional[any] Last element of list: Optional[any]
""" """
pass pass
@abstractmethod @abstractmethod
def max(self, _func: Callable) -> Union[int, float, complex]: def max(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Returns the highest value r"""Returns the highest value
Parameter Parameter
@ -199,9 +200,8 @@ class QueryableABC(ABC):
""" """
pass pass
@abstractmethod @abstractmethod
def min(self, _func: Callable) -> Union[int, float, complex]: def min(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Returns the lowest value r"""Returns the lowest value
Parameter Parameter
@ -216,7 +216,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def order_by(self, _func: Callable) -> 'QueryableABC': def order_by(self, _func: Callable = None) -> 'QueryableABC':
r"""Sorts elements by function in ascending order r"""Sorts elements by function in ascending order
Parameter Parameter
@ -231,7 +231,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def order_by_descending(self, _func: Callable) -> 'QueryableABC': def order_by_descending(self, _func: Callable = None) -> 'QueryableABC':
r"""Sorts elements by function in descending order r"""Sorts elements by function in descending order
Parameter Parameter
@ -331,7 +331,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def sum(self, _func: Callable) -> Union[int, float, complex]: def sum(self, _func: Callable = None) -> Union[int, float, complex]:
r"""Sum of all values r"""Sum of all values
Parameter Parameter
@ -376,7 +376,7 @@ class QueryableABC(ABC):
pass pass
@abstractmethod @abstractmethod
def where(self, _func: Callable) -> 'QueryableABC': def where(self, _func: Callable = None) -> 'QueryableABC':
r"""Select element by function r"""Select element by function
Parameter Parameter

View File

@ -37,9 +37,6 @@ class SequenceABC(ABC):
def type(self) -> type: def type(self) -> type:
return self._type return self._type
def reset(self):
self._values.reset()
def to_list(self) -> list: def to_list(self) -> list:
r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list` r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list`

View File

@ -19,20 +19,22 @@ class SequenceValues:
if data is None: if data is None:
data = [] data = []
if len(data) > 0:
def type_check(_t: type, _l: list):
return all(isinstance(x, _t) for x in _l)
if not type_check(_t, data):
raise Exception(f'Unexpected type\nExpected type: {_t}')
if not hasattr(data, '__iter__'): if not hasattr(data, '__iter__'):
raise TypeError(f'{type(self).__name__} must be instantiated with an iterable object') raise TypeError(f'{type(self).__name__} must be instantiated with an iterable object')
self._data = [] self._data = data
for element in data:
if _t is not None and type(element) != _t and not isinstance(type(element), _t) and not issubclass(type(element), _t):
raise Exception(f'Unexpected type: {type(element)}\nExpected type: {_t}')
self._data.append(element)
self._index = 0 self._index = 0
self._len = sum(1 for item in self._data)
self._cycle = itertools.cycle(self._data) self._cycle = itertools.cycle(self._data)
def __len__(self): def __len__(self):
return self._len return sum(1 for item in self._data)
def __iter__(self): def __iter__(self):
i = 0 i = 0

View File

@ -1,7 +1,6 @@
from typing import Union, Callable, Optional, Iterable from typing import Union, Callable, Optional
from cpl_query._helper import is_number from cpl_query._helper import is_number
from cpl_query.base.sequence_values import SequenceValues
from cpl_query.enumerable.enumerable_abc import EnumerableABC from cpl_query.enumerable.enumerable_abc import EnumerableABC
from cpl_query.enumerable.ordered_enumerable_abc import OrderedEnumerableABC from cpl_query.enumerable.ordered_enumerable_abc import OrderedEnumerableABC
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException, IndexOutOfRangeException from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException, IndexOutOfRangeException
@ -88,7 +87,7 @@ class Enumerable(EnumerableABC):
return result return result
def element_at(self, _index: int) -> any: def element_at(self, _index: int) -> any:
self.reset() self._values.reset()
while _index >= 0: while _index >= 0:
current = self.next() current = self.next()
if _index == 0: if _index == 0:
@ -195,7 +194,7 @@ class Enumerable(EnumerableABC):
@staticmethod @staticmethod
def range(start: int, length: int) -> 'EnumerableABC': def range(start: int, length: int) -> 'EnumerableABC':
return Enumerable(int, range(start, start + length, 1)) return Enumerable(int, range(start, length))
def reverse(self: EnumerableABC) -> EnumerableABC: def reverse(self: EnumerableABC) -> EnumerableABC:
if self is None: if self is None:
@ -295,7 +294,6 @@ class Enumerable(EnumerableABC):
raise ArgumentNoneException(ExceptionArgument.index) raise ArgumentNoneException(ExceptionArgument.index)
_list = self.to_list() _list = self.to_list()
index = len(_list) - _index index = len(_list) - _index
if index >= len(_list) or index < 0: if index >= len(_list) or index < 0:
@ -322,12 +320,4 @@ class Enumerable(EnumerableABC):
if _func is None: if _func is None:
raise ArgumentNoneException(ExceptionArgument.func) raise ArgumentNoneException(ExceptionArgument.func)
if _func is None: return Enumerable(self.type, [x for x in self if _func(x)])
_func = _default_lambda
result = Enumerable(self.type)
for element in self:
if _func(element):
result.add(element)
return result

View File

@ -15,21 +15,21 @@ class IterableABC(SequenceABC, QueryableABC):
SequenceABC.__init__(self, t, values) SequenceABC.__init__(self, t, values)
def __getitem__(self, n) -> object: def __getitem__(self, n) -> object:
r"""Gets item in enumerable at specified zero-based index return self.to_list().__getitem__(n)
Parameter def __delitem__(self, i: int):
-------- """Delete an item"""
n: the index of the item to get _l = self.to_list()
del _l[i]
self._values = SequenceValues(_l, self._type)
Returns def __setitem__(self, i: int, value):
------- _l = self.to_list()
The element at the specified index. _l.__setitem__(i, value)
self._values = SequenceValues(_l, self._type)
Raises def __str__(self):
------ return str(self.to_list())
IndexError if n > number of elements in the iterable
"""
return list.__getitem__(self.to_list(), n)
def append(self, __object: object) -> None: def append(self, __object: object) -> None:
r"""Adds element to list r"""Adds element to list

View File

@ -19,3 +19,17 @@ class IterableTestCase(unittest.TestCase):
self.assertEqual(self._list.to_list(), [1, 2, 3]) self.assertEqual(self._list.to_list(), [1, 2, 3])
self.assertRaises(Exception, lambda v: self._list.append(v), '3') self.assertRaises(Exception, lambda v: self._list.append(v), '3')
def test_assign(self):
self._list.append(1)
self._list.append(2)
self._list.append(3)
self._list[0] = 42
self.assertEqual(self._list[0], 42)
self._list[0] = 1
self._list.append(42)
self.assertEqual(self._list[3], 42)
del self._list[3]
self.assertEqual(self._list.to_list(), [1, 2, 3])
self.assertRaises(Exception, lambda v: self._list.append(v), '3')