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):
|
||||
|
||||
def __init__(self):
|
||||
IterableABC.__init__(self)
|
||||
def __init__(self, t: type = None, values: list = None):
|
||||
IterableABC.__init__(self, t, values)
|
||||
|
||||
def any(self, func: Callable) -> bool:
|
||||
return any_query(self, func)
|
||||
@ -29,8 +29,8 @@ class Iterable(IterableABC):
|
||||
def all(self, func: Callable) -> bool:
|
||||
return all_query(self, func)
|
||||
|
||||
def average(self, t: type, func: Callable) -> Union[int, float, complex]:
|
||||
return avg_query(self, t, func)
|
||||
def average(self, func: Callable = None) -> Union[int, float, complex]:
|
||||
return avg_query(self, func)
|
||||
|
||||
def contains(self, value: object) -> bool:
|
||||
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 cpl_query._helper import is_number
|
||||
from cpl_query.exceptions import InvalidTypeException, WrongTypeException, ExceptionArgument, ArgumentNoneException
|
||||
from cpl_query.extension.iterable_abc import IterableABC
|
||||
|
||||
|
||||
def avg_query(_list: IterableABC, _t: type, _func: Callable) -> Union[int, float, complex]:
|
||||
average = 0
|
||||
count = len(_list)
|
||||
|
||||
def avg_query(_list: IterableABC, _func: Callable) -> Union[int, float, complex]:
|
||||
if _list is None:
|
||||
raise ArgumentNoneException(ExceptionArgument.list)
|
||||
|
||||
if _func is None:
|
||||
raise ArgumentNoneException(ExceptionArgument.func)
|
||||
|
||||
if _t != int and _t != float and _t != complex:
|
||||
raise InvalidTypeException()
|
||||
average = 0
|
||||
count = len(_list)
|
||||
|
||||
for element in _list:
|
||||
if _func is not None:
|
||||
value = _func(element)
|
||||
if type(value) != _t:
|
||||
|
||||
else:
|
||||
value = element
|
||||
|
||||
if _list.type is not None and type(element) != _list.type or not is_number(type(value)):
|
||||
raise WrongTypeException()
|
||||
|
||||
average += value
|
||||
|
||||
return average / count
|
||||
|
||||
|
@ -5,17 +5,35 @@ from typing import Optional, Callable, Union
|
||||
class IterableABC(ABC, list):
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
def __init__(self, t: type = None, values: list = None):
|
||||
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
|
||||
def any(self, func: Callable) -> bool: pass
|
||||
|
||||
@abstractmethod
|
||||
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
|
||||
def average(self, t: type, func: Callable) -> Union[int, float, complex]: pass
|
||||
def average(self, func: Callable = None) -> Union[int, float, complex]: pass
|
||||
|
||||
@abstractmethod
|
||||
def contains(self, value: object) -> bool: pass
|
||||
|
@ -4,15 +4,4 @@ from .._extension.iterable import Iterable
|
||||
class List(Iterable):
|
||||
|
||||
def __init__(self, t: type = None, values: list = None):
|
||||
Iterable.__init__(self)
|
||||
|
||||
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)
|
||||
Iterable.__init__(self, t, values)
|
||||
|
@ -66,19 +66,24 @@ class QueryTest(unittest.TestCase):
|
||||
avg += user.address.nr
|
||||
|
||||
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)
|
||||
|
||||
def invalid():
|
||||
e_res = self._tests.average(str, lambda u: u.address.nr)
|
||||
self.assertEqual(avg, res)
|
||||
|
||||
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)
|
||||
|
||||
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):
|
||||
self.assertTrue(self._tests.contains(self._t_user))
|
||||
self.assertFalse(self._tests.contains(User("Test", None)))
|
||||
|
Loading…
Reference in New Issue
Block a user