From ae3192b63c41a6257515e4f6a5a34a82da104dea Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Thu, 15 Sep 2022 12:48:05 +0200 Subject: [PATCH] Removed SequenceABC --- src/cpl_query/base/sequence_abc.py | 47 ------------------- src/cpl_query/base/sequence_values.py | 10 ---- src/cpl_query/enumerable/enumerable_abc.py | 39 +++++++++++++-- src/cpl_query/extension/list.py | 3 +- src/cpl_query/iterable/iterable_abc.py | 34 +++++++------- .../unittests_query/performance_test_case.py | 46 +++++++++--------- 6 files changed, 75 insertions(+), 104 deletions(-) delete mode 100644 src/cpl_query/base/sequence_abc.py diff --git a/src/cpl_query/base/sequence_abc.py b/src/cpl_query/base/sequence_abc.py deleted file mode 100644 index 23bbf592..00000000 --- a/src/cpl_query/base/sequence_abc.py +++ /dev/null @@ -1,47 +0,0 @@ -from abc import abstractmethod, ABC -from typing import Union - -from cpl_query.base.sequence_values import SequenceValues - - -class SequenceABC(ABC): - - @abstractmethod - def __init__(self, t: type = None, values: Union[list, iter] = None): - ABC.__init__(self) - - if t == any: - t = None - elif t is None and values is not None: - t = type(values[0]) - - self._type = t - self._values = SequenceValues(values, t) - - def __len__(self): - return len(self._values) - - def __iter__(self): - return iter(self._values) - - def next(self): - return next(self._values) - - def __next__(self): - return self.next() - - def __repr__(self): - return f'<{type(self).__name__} {list(self).__repr__()}>' - - @property - def type(self) -> type: - return self._type - - def to_list(self) -> list: - r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list` - - Returns - ------- - :class: `list` - """ - return [x for x in self] diff --git a/src/cpl_query/base/sequence_values.py b/src/cpl_query/base/sequence_values.py index c0a70526..e5406412 100644 --- a/src/cpl_query/base/sequence_values.py +++ b/src/cpl_query/base/sequence_values.py @@ -4,16 +4,6 @@ import itertools from cpl_query.exceptions import IndexOutOfRangeException -class SequenceEnd: - - def __init__(self): - self.is_ended = False - - def set_end(self, value: bool) -> 'SequenceEnd': - self.is_ended = value - return self - - class SequenceValues: def __init__(self, data, _t: type): if data is None: diff --git a/src/cpl_query/enumerable/enumerable_abc.py b/src/cpl_query/enumerable/enumerable_abc.py index 517540d7..ff587f1a 100644 --- a/src/cpl_query/enumerable/enumerable_abc.py +++ b/src/cpl_query/enumerable/enumerable_abc.py @@ -2,18 +2,38 @@ from abc import abstractmethod from typing import Iterable from cpl_query.base.queryable_abc import QueryableABC -from cpl_query.base.sequence_abc import SequenceABC from cpl_query.base.sequence_values import SequenceValues -class EnumerableABC(SequenceABC, QueryableABC): +class EnumerableABC(QueryableABC): r"""ABC to define functions on list """ @abstractmethod - def __init__(self, t: type = None, values: Iterable = None): - SequenceABC.__init__(self, t, values) - self._remove_error_check = True + def __init__(self, t: type = None, values: list = None): + if t == any or t is None and values is not None: + t = type(values[0]) + + self._type, self._values, self._remove_error_check = t, SequenceValues(values, t), True + + def __len__(self): + return len(self._values) + + def __iter__(self): + return iter(self._values) + + def next(self): + return next(self._values) + + def __next__(self): + return self.next() + + def __repr__(self): + return f'<{type(self).__name__} {list(self).__repr__()}>' + + @property + def type(self) -> type: + return self._type def set_remove_error_check(self, _value: bool): r"""Set flag to check if element exists before removing @@ -75,3 +95,12 @@ class EnumerableABC(SequenceABC, QueryableABC): """ from cpl_query.iterable.iterable import Iterable return Iterable(self._type, self.to_list()) + + def to_list(self) -> list: + r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list` + + Returns + ------- + :class: `list` + """ + return [x for x in self] diff --git a/src/cpl_query/extension/list.py b/src/cpl_query/extension/list.py index fbc7c086..62e0d5b4 100644 --- a/src/cpl_query/extension/list.py +++ b/src/cpl_query/extension/list.py @@ -3,13 +3,12 @@ from typing import Iterable as IterableType from cpl_query.iterable.iterable import Iterable -class List(Iterable, list): +class List(Iterable): r"""Implementation of :class: `cpl_query.extension.iterable.Iterable` """ def __init__(self, t: type = None, values: IterableType = None): Iterable.__init__(self, t, values) - list.__init__(self) def to_enumerable(self) -> 'EnumerableABC': r"""Converts :class: `cpl_query.iterable.iterable_abc.IterableABC` to :class: `cpl_query.enumerable.enumerable_abc.EnumerableABC` diff --git a/src/cpl_query/iterable/iterable_abc.py b/src/cpl_query/iterable/iterable_abc.py index b2b6ccc2..cc6672a4 100644 --- a/src/cpl_query/iterable/iterable_abc.py +++ b/src/cpl_query/iterable/iterable_abc.py @@ -2,31 +2,32 @@ from abc import abstractmethod from typing import Iterable from cpl_query.base.queryable_abc import QueryableABC -from cpl_query.base.sequence_abc import SequenceABC -from cpl_query.base.sequence_values import SequenceValues -class IterableABC(SequenceABC, QueryableABC): +class IterableABC(list, QueryableABC): r"""ABC to define functions on list """ @abstractmethod def __init__(self, t: type = None, values: Iterable = None): - SequenceABC.__init__(self, t, values) + self._type = t + list.__init__(self, [] if values is None else values) - def __getitem__(self, n) -> object: - return self.to_list().__getitem__(n) + def __repr__(self): + return f'<{type(self).__name__} {list(self).__repr__()}>' - def __delitem__(self, i: int): - """Delete an item""" - _l = self.to_list() - del _l[i] - self._values = SequenceValues(_l, self._type) + @property + def type(self) -> type: + return self._type - def __setitem__(self, i: int, value): - _l = self.to_list() - _l.__setitem__(i, value) - self._values = SequenceValues(_l, self._type) + def to_list(self) -> list: + r"""Converts :class: `cpl_query.base.sequence_abc.SequenceABC` to :class: `list` + + Returns + ------- + :class: `list` + """ + return [x for x in self] def __str__(self): return str(self.to_list()) @@ -44,7 +45,8 @@ class IterableABC(SequenceABC, QueryableABC): if len(self) == 0 and self._type is None: self._type = type(__object) - self._values = SequenceValues([*self._values, __object], self._type) + # self._values = SequenceValues([*self._values, __object], self._type) + super().append(__object) def extend(self, __iterable: Iterable) -> 'IterableABC': r"""Adds elements of given list to list diff --git a/unittests/unittests_query/performance_test_case.py b/unittests/unittests_query/performance_test_case.py index 1be52d01..9a375763 100644 --- a/unittests/unittests_query/performance_test_case.py +++ b/unittests/unittests_query/performance_test_case.py @@ -3,11 +3,10 @@ import timeit import unittest from cpl_query.enumerable import Enumerable -from cpl_query.extension.list import List from cpl_query.iterable import Iterable VALUES = 1000 -COUNT = 100 +COUNT = 50 class PerformanceTestCase(unittest.TestCase): @@ -19,27 +18,26 @@ class PerformanceTestCase(unittest.TestCase): self.values.append(i) i += 1 - # def test_range(self): - # default = timeit.timeit(lambda: list(self.values), number=COUNT) - # enumerable = timeit.timeit(lambda: Enumerable(int, self.values), number=COUNT) - # iterable = timeit.timeit(lambda: Iterable(int, self.values), number=COUNT) - # - # print(f'd: {default}') - # print(f'e: {enumerable}') - # print(f'i: {iterable}') - # - # self.assertLess(default, enumerable) - # self.assertLess(default, iterable) + def test_range(self): + default = timeit.timeit(lambda: list(self.values), number=COUNT) + enumerable = timeit.timeit(lambda: Enumerable(int, self.values), number=COUNT) + iterable = timeit.timeit(lambda: Iterable(int, self.values), number=COUNT) + + print(f'd: {default}') + print(f'i: {iterable}') + print(f'e: {enumerable}') + + self.assertLess(default, enumerable) + self.assertLess(default, iterable) def test_where_single(self): - print(Enumerable(int, self.values).where(lambda x: x == COUNT).single_or_default()) - # default = timeit.timeit(lambda: [x for x in list(self.values) if x == 50], number=COUNT) - # enumerable = timeit.timeit(lambda: Enumerable(int, self.values).where(lambda x: x == 50).single(), number=COUNT) - # iterable = timeit.timeit(lambda: Iterable(int, self.values).where(lambda x: x == 50).single(), number=COUNT) - # - # print(f'd: {default}') - # print(f'e: {enumerable}') - # print(f'i: {iterable}') - # - # self.assertLess(default, enumerable) - # self.assertLess(default, iterable) + default = timeit.timeit(lambda: [x for x in list(self.values) if x == 50], number=COUNT) + iterable = timeit.timeit(lambda: Iterable(int, self.values).where(lambda x: x == 50).single(), number=COUNT) + enumerable = timeit.timeit(lambda: Enumerable(int, self.values).where(lambda x: x == 50).single(), number=COUNT) + + print(f'd: {default}') + print(f'i: {iterable}') + print(f'e: {enumerable}') + + self.assertLess(default, enumerable) + self.assertLess(default, iterable)