Added avg query

This commit is contained in:
Sven Heidemann 2021-07-27 09:26:30 +02:00
parent 0f85d4b9bc
commit e0b7728719
5 changed files with 60 additions and 2 deletions

View File

@ -1,9 +1,10 @@
from typing import Optional, Callable from typing import Optional, Callable, Union
from cpl_query._extension.ordered_iterable import OrderedIterable from cpl_query._extension.ordered_iterable import OrderedIterable
from cpl_query.extension.ordered_iterable_abc import OrderedIterableABC from cpl_query.extension.ordered_iterable_abc import OrderedIterableABC
from .._query.all_query import all_query from .._query.all_query import all_query
from .._query.any_query import any_query from .._query.any_query import any_query
from .._query.avg_query import avg_query
from .._query.first_query import first_or_default_query, first_query from .._query.first_query import first_or_default_query, first_query
from .._query.for_each_query import for_each_query from .._query.for_each_query import for_each_query
from .._query.order_by import order_by_query, order_by_descending_query from .._query.order_by import order_by_query, order_by_descending_query
@ -23,6 +24,9 @@ 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]:
return avg_query(self, t, func)
def first(self) -> any: def first(self) -> any:
return first_query(self) return first_query(self)

View File

@ -0,0 +1,22 @@
from typing import Callable, Union
from cpl_query.exceptions import InvalidTypeException, WrongTypeException
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)
if _t != int and _t != float and _t != complex:
raise InvalidTypeException()
for element in _list:
value = _func(element)
if type(value) != _t:
raise WrongTypeException()
average += value
return average / count

View File

@ -0,0 +1,6 @@
class InvalidTypeException(Exception):
pass
class WrongTypeException(Exception):
pass

View File

@ -1,5 +1,5 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional, Callable from typing import Optional, Callable, Union
class IterableABC(ABC, list): class IterableABC(ABC, list):
@ -14,6 +14,9 @@ class IterableABC(ABC, list):
@abstractmethod @abstractmethod
def all(self, func: Callable) -> bool: pass def all(self, func: Callable) -> bool: pass
@abstractmethod
def average(self, t: type, func: Callable) -> Union[int, float, complex]: pass
@abstractmethod @abstractmethod
def first(self) -> any: pass def first(self) -> any: pass

View File

@ -3,6 +3,7 @@ import unittest
from random import randint from random import randint
from cpl.utils import String from cpl.utils import String
from cpl_query.exceptions import InvalidTypeException, WrongTypeException
from cpl_query.extension.list import List from cpl_query.extension.list import List
from cpl_query.tests.models import User, Address from cpl_query.tests.models import User, Address
@ -59,6 +60,28 @@ class QueryTest(unittest.TestCase):
self.assertTrue(res) self.assertTrue(res)
self.assertFalse(n_res) self.assertFalse(n_res)
def test_avg(self):
avg = 0
for user in self._tests:
avg += user.address.nr
avg = avg / len(self._tests)
res = self._tests.average(int, lambda u: u.address.nr)
self.assertEqual(res, avg)
def test_avg_invalid(self):
def _():
res = self._tests.average(str, lambda u: u.address.nr)
self.assertRaises(InvalidTypeException, _)
def test_avg_wrong(self):
def _():
res = self._tests.average(int, lambda u: u.address.street)
self.assertRaises(WrongTypeException, _)
def test_first(self): def test_first(self):
results = [] results = []
for user in self._tests: for user in self._tests: