diff --git a/src/curry_task.py b/src/curry_task.py new file mode 100644 index 0000000..891f2cb --- /dev/null +++ b/src/curry_task.py @@ -0,0 +1,44 @@ +class MyError(Exception): + pass + + +def curry(func, arity): + # для ф inner этот список будет глобальным + if arity <= 0: + raise MyError("Арность не может быть меньше или равна 0.") + if arity > func.__code__.co_argcount: + raise MyError("Переданная арность больше действительной.") + if not isinstance(arity, int): + raise MyError("Переданная арность функции обязана быть целым числом.") + lst = [] + + def inner(arg): + nonlocal lst + lst.append(arg) + if len(lst) == arity: + tmp = func(*lst) + # освобождаем список, чтобы функцию можно было использовать повторно + lst = [] + return tmp + return inner + + return inner + + +def uncurry(curried_func, arity): + """ + Этой функции передается внутренняя функция inner функции curry, принимающая один аргумент. + Сначала возвращается функция, способная принимать любое кол-во аргументов. + Все последующее обращение будет к внутренней функции. + """ + + def uncarried_func(*args): + tmp_func = curried_func + if len(args) != arity: + raise MyError("Передано неверное кол-во аргументов.") + if len(args) == arity: + for el in args: + tmp_func = tmp_func(el) + return tmp_func + + return uncarried_func diff --git a/tests/test_for_curry_task.py b/tests/test_for_curry_task.py new file mode 100644 index 0000000..f8e5ac8 --- /dev/null +++ b/tests/test_for_curry_task.py @@ -0,0 +1,84 @@ +import hypothesis.strategies as st +from src.curry_task import curry, uncurry, MyError +from hypothesis import given + + +@given(a=st.integers(), b=st.integers(), c=st.integers()) +def test_sum_three_elements_check(a, b, c): + def summ(a, b, c): + return a + b + c + + func = curry(summ, 3) + uncarried_func = uncurry(func, 3) + for el in (a, b, c): + func = func(el) + assert func == a + b + c + assert uncarried_func(a, b, c) == a + b + c + + +@given(a=st.integers(), b=st.integers(), c=st.integers()) +def test_mul_three_elements_check(a, b, c): + def mul(a, b, c): + return a * b * c + + func = curry(mul, 3) + uncarried_func = uncurry(func, 3) + for el in (a, b, c): + func = func(el) + assert func == a * b * c + assert uncarried_func(a, b, c) == a * b * c + + +def test_wrong_arity_errors1(): + try: + + def summ(a, b, c): + return a + b + c + + curry(summ, -1) + assert False + except MyError as e: + assert isinstance(e, MyError) + assert str(e) == "Арность не может быть меньше или равна 0." + + +def test_wrong_arity_errors2(): + try: + + def summ(a, b, c): + return a + b + c + + curry(summ, 5) + assert False + except MyError as e: + assert isinstance(e, MyError) + assert str(e) == "Переданная арность больше действительной." + + +def test_wrong_arity_errors3(): + try: + + def mul(a, b, c): + return a * b * c + + curry(mul, 1.0) + assert False + except MyError as e: + assert isinstance(e, MyError) + assert str(e) == "Переданная арность функции обязана быть целым числом." + + +@given(args=st.lists(st.integers(), min_size=4)) +def test_wrong_quantity_of_arguments(args): + try: + + def summ(a, b, c): + return a + b + c + + func = curry(summ, 3) + uncarried_func = uncurry(func, 3) + uncarried_func(args) + assert False + except MyError as e: + assert isinstance(e, MyError) + assert str(e) == "Передано неверное кол-во аргументов."