-
Notifications
You must be signed in to change notification settings - Fork 0
Kalsina Yana Curry task #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1e2a7c1
fc09b58
95a4978
8b1b229
c178557
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
yaprogrammer18-yanchi marked this conversation as resolved.
Show resolved
Hide resolved
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Я не до конца уловил вашу идею про универсальный тест. Вы могли бы сделать функцию, которая на случайных входах проверяет, что каррированная функция отрабатывает так же, как и изначальная. Проблема тут в типах, потому что генерировать случайные числа просто, а вот что-то более сложное -- надо постараться import random
def fully_apply(f, args):
res = f
for arg in args:
res = res(arg)
return res
def generate_int_input(func):
[random.randint(1, 10**6) for _ in range(func.__code__.co_argcount)]
def curried_equiv(func):
func_c = curry(func, func.__code__.co_argcount)
input = generate_int_input(func)
assert fully_apply(func_c, input) == func(*input)
def test_summ():
def summ(a, b, c):
return a + b + c
curried_equiv(summ)Но функции должны работать только с int-ми (возвращать могут, впрочем, любой тип, главное, чтобы можно было два элемента сравнивать), и придумывать их вы должны тоже сами |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
|
Comment on lines
+13
to
+15
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А почему не просто |
||
| 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." | ||
|
Comment on lines
+33
to
+42
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Для таких вещей есть |
||
|
|
||
|
|
||
| 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) == "Передано неверное кол-во аргументов." | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А чем вам не угодила нулевая арность?