Improved avg query
This commit is contained in:
parent
d4b5c32a21
commit
daac14e099
@ -20,8 +20,8 @@ from cpl_query.extension.iterable_abc import IterableABC
|
|||||||
|
|
||||||
class Iterable(IterableABC):
|
class Iterable(IterableABC):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, t: type = None, values: list = None):
|
||||||
IterableABC.__init__(self)
|
IterableABC.__init__(self, t, values)
|
||||||
|
|
||||||
def any(self, func: Callable) -> bool:
|
def any(self, func: Callable) -> bool:
|
||||||
return any_query(self, func)
|
return any_query(self, func)
|
||||||
@ -29,8 +29,8 @@ class Iterable(IterableABC):
|
|||||||
def all(self, func: Callable) -> bool:
|
def all(self, func: Callable) -> bool:
|
||||||
return all_query(self, func)
|
return all_query(self, func)
|
||||||
|
|
||||||
def average(self, t: type, func: Callable) -> Union[int, float, complex]:
|
def average(self, func: Callable = None) -> Union[int, float, complex]:
|
||||||
return avg_query(self, t, func)
|
return avg_query(self, func)
|
||||||
|
|
||||||
def contains(self, value: object) -> bool:
|
def contains(self, value: object) -> bool:
|
||||||
return contains_query(self, value)
|
return contains_query(self, value)
|
||||||
|
2
src/cpl_query/_helper.py
Normal file
2
src/cpl_query/_helper.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
def is_number(t: type) -> bool:
|
||||||
|
return issubclass(t, int) or issubclass(t, float) or issubclass(t, complex)
|
@ -1,28 +1,27 @@
|
|||||||
from typing import Callable, Union
|
from typing import Callable, Union
|
||||||
|
|
||||||
|
from cpl_query._helper import is_number
|
||||||
from cpl_query.exceptions import InvalidTypeException, WrongTypeException, ExceptionArgument, ArgumentNoneException
|
from cpl_query.exceptions import InvalidTypeException, WrongTypeException, ExceptionArgument, ArgumentNoneException
|
||||||
from cpl_query.extension.iterable_abc import IterableABC
|
from cpl_query.extension.iterable_abc import IterableABC
|
||||||
|
|
||||||
|
|
||||||
def avg_query(_list: IterableABC, _t: type, _func: Callable) -> Union[int, float, complex]:
|
def avg_query(_list: IterableABC, _func: Callable) -> Union[int, float, complex]:
|
||||||
average = 0
|
|
||||||
count = len(_list)
|
|
||||||
|
|
||||||
if _list is None:
|
if _list is None:
|
||||||
raise ArgumentNoneException(ExceptionArgument.list)
|
raise ArgumentNoneException(ExceptionArgument.list)
|
||||||
|
|
||||||
if _func is None:
|
average = 0
|
||||||
raise ArgumentNoneException(ExceptionArgument.func)
|
count = len(_list)
|
||||||
|
|
||||||
if _t != int and _t != float and _t != complex:
|
|
||||||
raise InvalidTypeException()
|
|
||||||
|
|
||||||
for element in _list:
|
for element in _list:
|
||||||
value = _func(element)
|
if _func is not None:
|
||||||
if type(value) != _t:
|
value = _func(element)
|
||||||
|
|
||||||
|
else:
|
||||||
|
value = element
|
||||||
|
|
||||||
|
if _list.type is not None and type(element) != _list.type or not is_number(type(value)):
|
||||||
raise WrongTypeException()
|
raise WrongTypeException()
|
||||||
|
|
||||||
average += value
|
average += value
|
||||||
|
|
||||||
return average / count
|
return average / count
|
||||||
|
|
||||||
|
@ -5,17 +5,35 @@ from typing import Optional, Callable, Union
|
|||||||
class IterableABC(ABC, list):
|
class IterableABC(ABC, list):
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __init__(self):
|
def __init__(self, t: type = None, values: list = None):
|
||||||
list.__init__(self)
|
list.__init__(self)
|
||||||
|
|
||||||
|
if t == any:
|
||||||
|
t = None
|
||||||
|
self._type = t
|
||||||
|
|
||||||
|
if values is not None:
|
||||||
|
for value in values:
|
||||||
|
self.append(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> type:
|
||||||
|
return self._type
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def any(self, func: Callable) -> bool: pass
|
def any(self, func: Callable) -> bool: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def all(self, func: Callable) -> bool: pass
|
def all(self, func: Callable) -> bool: pass
|
||||||
|
|
||||||
|
def append(self, __object: object) -> None:
|
||||||
|
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)}')
|
||||||
|
|
||||||
|
super().append(__object)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def average(self, t: type, func: Callable) -> Union[int, float, complex]: pass
|
def average(self, func: Callable = None) -> Union[int, float, complex]: pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def contains(self, value: object) -> bool: pass
|
def contains(self, value: object) -> bool: pass
|
||||||
|
@ -4,15 +4,4 @@ from .._extension.iterable import Iterable
|
|||||||
class List(Iterable):
|
class List(Iterable):
|
||||||
|
|
||||||
def __init__(self, t: type = None, values: list = None):
|
def __init__(self, t: type = None, values: list = None):
|
||||||
Iterable.__init__(self)
|
Iterable.__init__(self, t, values)
|
||||||
|
|
||||||
self._type = t
|
|
||||||
|
|
||||||
if values is not None:
|
|
||||||
self.extend(values)
|
|
||||||
|
|
||||||
def append(self, __object: object) -> None:
|
|
||||||
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)}')
|
|
||||||
|
|
||||||
super().append(__object)
|
|
||||||
|
@ -66,19 +66,24 @@ class QueryTest(unittest.TestCase):
|
|||||||
avg += user.address.nr
|
avg += user.address.nr
|
||||||
|
|
||||||
avg = avg / len(self._tests)
|
avg = avg / len(self._tests)
|
||||||
res = self._tests.average(int, lambda u: u.address.nr)
|
res = self._tests.average(lambda u: u.address.nr)
|
||||||
|
|
||||||
self.assertEqual(res, avg)
|
self.assertEqual(avg, res)
|
||||||
|
|
||||||
def invalid():
|
|
||||||
e_res = self._tests.average(str, lambda u: u.address.nr)
|
|
||||||
|
|
||||||
def wrong():
|
def wrong():
|
||||||
e_res = self._tests.average(int, lambda u: u.address.street)
|
e_res = self._tests.average(lambda u: u.address.street)
|
||||||
|
|
||||||
self.assertRaises(InvalidTypeException, invalid)
|
|
||||||
self.assertRaises(WrongTypeException, wrong)
|
self.assertRaises(WrongTypeException, wrong)
|
||||||
|
|
||||||
|
tests = List(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(sum(tests) / len(tests), tests.average())
|
||||||
|
|
||||||
|
def wrong2():
|
||||||
|
tests2 = List(int, values=list(range(0, 100)))
|
||||||
|
e_res = tests2.average(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
self.assertRaises(AttributeError, wrong2)
|
||||||
|
|
||||||
def test_contains(self):
|
def test_contains(self):
|
||||||
self.assertTrue(self._tests.contains(self._t_user))
|
self.assertTrue(self._tests.contains(self._t_user))
|
||||||
self.assertFalse(self._tests.contains(User("Test", None)))
|
self.assertFalse(self._tests.contains(User("Test", None)))
|
||||||
|
Loading…
Reference in New Issue
Block a user