2022.10.9 - Enumerable & List (#105) #106

Merged
edraft merged 9 commits from 2022.10.9 into 2022.10 2022-09-15 18:21:25 +02:00
6 changed files with 59 additions and 14 deletions
Showing only changes of commit bb461f5fba - Show all commits

View File

@ -206,21 +206,17 @@ class Enumerable(EnumerableABC):
if _func is None:
_func = _default_lambda
result = Enumerable()
result.extend(_func(_o) for _o in self)
return result
_l = [_func(_o) for _o in self]
return Enumerable(self._type if len(_l) < 1 else type(_l[0]), _l)
def select_many(self, _func: Callable = None) -> EnumerableABC:
if _func is None:
_func = _default_lambda
result = Enumerable()
# The line below is pain. I don't understand anything of it...
# The line below is pain. I don't understand anything of the list comprehension...
# written on 09.11.2022 by Sven Heidemann
elements = [_a for _o in self for _a in _func(_o)]
result.extend(elements)
return result
_l = [_a for _o in self for _a in _func(_o)]
return Enumerable(self._type if len(_l) < 1 else type(_l[0]), _l)
def single(self: EnumerableABC) -> any:
if self is None:
@ -237,9 +233,9 @@ class Enumerable(EnumerableABC):
if self is None:
raise ArgumentNoneException(ExceptionArgument.list)
if len(self) > 1:
if self.count() > 1:
raise IndexError('Found more than one element')
elif len(self) == 0:
elif self.count() == 0:
return None
return self.element_at(0)

View File

@ -1,4 +1,4 @@
from typing import Callable, Optional, Union
from typing import Callable, Optional, Union, Iterable as IterableType
from cpl_query._helper import is_number
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException, IndexOutOfRangeException
@ -12,7 +12,7 @@ def _default_lambda(x: object):
class Iterable(IterableABC):
def __init__(self, t: type = None, values: list = None):
def __init__(self, t: type = None, values: IterableType = None):
IterableABC.__init__(self, t, values)
def all(self, _func: Callable = None) -> bool:

View File

@ -11,7 +11,7 @@ class IterableABC(SequenceABC, QueryableABC):
"""
@abstractmethod
def __init__(self, t: type = None, values: list = None):
def __init__(self, t: type = None, values: Iterable = None):
SequenceABC.__init__(self, t, values)
def __getitem__(self, n) -> object:

View File

@ -156,6 +156,8 @@ class EnumerableQueryTestCase(unittest.TestCase):
self.assertEqual(len(res), len(results))
self.assertEqual(res.element_at(0), s_res)
self.assertEqual(res.element_at(0), res.first())
self.assertEqual(res.first(), res.first())
def test_first_or_default(self):
results = []

View File

@ -151,6 +151,8 @@ class IterableQueryTestCase(unittest.TestCase):
self.assertEqual(len(res), len(results))
self.assertEqual(res[0], s_res)
self.assertEqual(res[0], res.first())
self.assertEqual(res.first(), res.first())
def test_first_or_default(self):
results = []

View File

@ -0,0 +1,45 @@
import sys
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
class PerformanceTestCase(unittest.TestCase):
def setUp(self):
i = 0
self.values = []
while i < VALUES:
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_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)