Improved avg, max and min queries type handling

This commit is contained in:
Sven Heidemann 2021-07-27 12:42:33 +02:00
parent daac14e099
commit a26c6f1bd9
5 changed files with 36 additions and 27 deletions

View File

@ -64,11 +64,11 @@ class Iterable(IterableABC):
def for_each(self, func: Callable): def for_each(self, func: Callable):
for_each_query(self, func) for_each_query(self, func)
def max(self, t: type, func: Callable) -> Union[int, float, complex]: def max(self, func: Callable) -> Union[int, float, complex]:
return max_query(self, t, func) return max_query(self, func)
def min(self, t: type, func: Callable) -> Union[int, float, complex]: def min(self, func: Callable) -> Union[int, float, complex]:
return min_query(self, t, func) return min_query(self, func)
def order_by(self, func: Callable) -> OrderedIterableABC: def order_by(self, func: Callable) -> OrderedIterableABC:
res = order_by_query(self, func) res = order_by_query(self, func)

View File

@ -19,7 +19,7 @@ def avg_query(_list: IterableABC, _func: Callable) -> Union[int, float, complex]
else: else:
value = element value = element
if _list.type is not None and type(element) != _list.type or not is_number(type(value)): if _func is None and type(element) != _list.type or not is_number(type(value)):
raise WrongTypeException() raise WrongTypeException()
average += value average += value

View File

@ -1,43 +1,46 @@
from collections import Callable from collections import Callable
from typing import Union from typing import Union
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException from cpl_query._helper import is_number
from cpl_query.exceptions import ArgumentNoneException, ExceptionArgument, InvalidTypeException, WrongTypeException
from cpl_query.extension.iterable_abc import IterableABC from cpl_query.extension.iterable_abc import IterableABC
def max_query(_list: IterableABC, _t: type, _func: Callable) -> Union[int, float, complex]: def max_query(_list: IterableABC, _func: Callable) -> Union[int, float, complex]:
if _list is None: if _list is None:
raise ArgumentNoneException(ExceptionArgument.list) raise ArgumentNoneException(ExceptionArgument.list)
if _func is None: max_value = 0
raise ArgumentNoneException(ExceptionArgument.func)
if _t != int and _t != float and _t != complex:
raise InvalidTypeException()
max_value = _t()
for element in _list: for element in _list:
if _func is not None:
value = _func(element) value = _func(element)
else:
value = element
if _func is None and type(value) != _list.type or not is_number(type(value)):
raise WrongTypeException()
if value > max_value: if value > max_value:
max_value = value max_value = value
return max_value return max_value
def min_query(_list: IterableABC, _t: type, _func: Callable) -> Union[int, float, complex]: def min_query(_list: IterableABC, _func: Callable) -> Union[int, float, complex]:
if _list is None: if _list is None:
raise ArgumentNoneException(ExceptionArgument.list) raise ArgumentNoneException(ExceptionArgument.list)
if _func is None: min_value = 0
raise ArgumentNoneException(ExceptionArgument.func)
if _t != int and _t != float and _t != complex:
raise InvalidTypeException()
min_value = _t()
is_first = True is_first = True
for element in _list: for element in _list:
if _func is not None:
value = _func(element) value = _func(element)
else:
value = element
if _func is None and type(value) != _list.type or not is_number(type(value)):
raise WrongTypeException()
if is_first: if is_first:
min_value = value min_value = value
is_first = False is_first = False

View File

@ -30,6 +30,9 @@ class IterableABC(ABC, list):
if self._type is not None and type(__object) != self._type and not isinstance(type(__object), self._type): if self._type is not None and type(__object) != self._type and not isinstance(type(__object), self._type):
raise Exception(f'Unexpected type: {type(__object)}') raise Exception(f'Unexpected type: {type(__object)}')
if len(self) == 0 and self._type is None:
self._type = type(__object)
super().append(__object) super().append(__object)
@abstractmethod @abstractmethod
@ -66,7 +69,10 @@ class IterableABC(ABC, list):
def for_each(self, func: Callable) -> Union[int, float, complex]: pass def for_each(self, func: Callable) -> Union[int, float, complex]: pass
@abstractmethod @abstractmethod
def max(self, t: type, func: Callable) -> Union[int, float, complex]: pass def max(self, func: Callable) -> Union[int, float, complex]: pass
@abstractmethod
def min(self, func: Callable) -> Union[int, float, complex]: pass
@abstractmethod @abstractmethod
def order_by(self, func: Callable) -> 'IterableABC': pass def order_by(self, func: Callable) -> 'IterableABC': pass

View File

@ -168,11 +168,11 @@ class QueryTest(unittest.TestCase):
self.assertEqual(len(users), len(self._tests)) self.assertEqual(len(users), len(self._tests))
def test_max(self): def test_max(self):
res = self._tests.max(int, lambda u: u.address.nr) res = self._tests.max(lambda u: u.address.nr)
self.assertEqual(self._t_user.address.nr, res) self.assertEqual(self._t_user.address.nr, res)
def test_min(self): def test_min(self):
res = self._tests.min(int, lambda u: u.address.nr) res = self._tests.min(lambda u: u.address.nr)
self.assertEqual(1, res) self.assertEqual(1, res)
def test_order_by(self): def test_order_by(self):