From 02ff00d24730a9a1bdf16da3f74d2f34e9680ec3 Mon Sep 17 00:00:00 2001 From: Nikolay Baboshin <231540704+shknoko@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:09:26 +0300 Subject: [PATCH 1/6] Currying and uncurrying functions --- 23.10/src/curry.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 23.10/src/curry.py diff --git a/23.10/src/curry.py b/23.10/src/curry.py new file mode 100644 index 0000000..f80a0dd --- /dev/null +++ b/23.10/src/curry.py @@ -0,0 +1,39 @@ +def curry(f: callable, arg_count: int) -> callable: + if arg_count < 0 or arg_count != f.__code__.co_argcount: + raise ValueError("Некорректное значение арности") + + def curried(*collected_args): + if len(collected_args) < arg_count: + + def next_arg(new_arg): + return curried(*(list(collected_args) + [new_arg])) + + return next_arg + elif len(collected_args) == arg_count: + return f(*collected_args) + else: + raise ValueError( + "Общее количество аргументов больше нужного \ + (например, если передано слишком много аргументов в каком-то из вызовов)" + ) + + return curried + + +def uncurry(f: callable) -> callable: + if not callable(f): + raise ValueError("Передана не функция") + + def uncurried(*args): + res = f + for i in args: + if not callable(res): + raise ValueError("Передано слишком много аргументов") + res = res(i) + + if callable(res): + raise ValueError("Передано недостаточно аргументов") + + return res + + return uncurried From e63b474d8e731b8b090733c381b9e23d0b1a9f56 Mon Sep 17 00:00:00 2001 From: Nikolay Baboshin <231540704+shknoko@users.noreply.github.com> Date: Sat, 18 Oct 2025 00:17:47 +0300 Subject: [PATCH 2/6] Added test checker in CI --- .github/workflows/pytest.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/pytest.yml diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 0000000..aa74d4c --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,22 @@ +name: Run tests with pytest +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + pip install pytest-repeat + + - name: Run tests + run: pytest \ No newline at end of file From 4ccda5aede4c21971e7acec3717482011b35cb6d Mon Sep 17 00:00:00 2001 From: Nikolay Baboshin <231540704+shknoko@users.noreply.github.com> Date: Sat, 18 Oct 2025 00:24:36 +0300 Subject: [PATCH 3/6] Updated config for pytest in CI --- .github/workflows/pytest.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index aa74d4c..059a0a7 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -1,5 +1,6 @@ name: Run tests with pytest on: + push: pull_request: jobs: From 41b90f86c34677e3774c52ab5181271c530b8a4b Mon Sep 17 00:00:00 2001 From: Nikolay Baboshin <231540704+shknoko@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:40:37 +0300 Subject: [PATCH 4/6] Extended error handling in uncurry --- 23.10/src/curry.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/23.10/src/curry.py b/23.10/src/curry.py index f80a0dd..25f63ae 100644 --- a/23.10/src/curry.py +++ b/23.10/src/curry.py @@ -14,7 +14,7 @@ def next_arg(new_arg): else: raise ValueError( "Общее количество аргументов больше нужного \ - (например, если передано слишком много аргументов в каком-то из вызовов)" +(например, если передано слишком много аргументов в каком-то из вызовов)" ) return curried @@ -26,6 +26,12 @@ def uncurry(f: callable) -> callable: def uncurried(*args): res = f + if len(args) == 0: + try: + res = res() + except TypeError: + raise TypeError from TypeError + for i in args: if not callable(res): raise ValueError("Передано слишком много аргументов") From a0128d2df19687d4b7b90a66b57c8772c2af4e0f Mon Sep 17 00:00:00 2001 From: Nikolay Baboshin <231540704+shknoko@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:50:39 +0300 Subject: [PATCH 5/6] Added tests for curry --- 23.10/tests/test_curry.py | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 23.10/tests/test_curry.py diff --git a/23.10/tests/test_curry.py b/23.10/tests/test_curry.py new file mode 100644 index 0000000..a0268e9 --- /dev/null +++ b/23.10/tests/test_curry.py @@ -0,0 +1,49 @@ +import sys +from pathlib import Path + +import pytest + +sys.path.append(f"{Path(__file__).parent.parent}") + +from src.curry import curry + + +def test_curry_zero_args(): + def f(): + return range(10) + + curried = curry(f, 0) + assert curried() == f() + + +def test_curry_one_arg(): + def f(a): + return a + + curried = curry(f, 1) + assert curried(2435234534252) == f(2435234534252) + + +def test_curry_two_args(): + def f(a, b): + return a + b + + curried = curry(f, 2) + assert curried(5)(10) == f(5, 10) + + +def test_curry_three_args(): + def f(a, b, c): + return a - b & c + + curried = curry(f, 3) + assert curried(2)(3)(4) == f(2, 3, 4) + + +def test_curry_insufficient_args(): + def add(a, b): + return a + b + + curried = curry(add, 2) + with pytest.raises(TypeError): + curried(5)() From 818de47418398b8a7d806a68aa2ab8027521a9b6 Mon Sep 17 00:00:00 2001 From: Nikolay Baboshin <231540704+shknoko@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:55:52 +0300 Subject: [PATCH 6/6] Added tests for uncurry --- 23.10/tests/test_uncurry.py | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 23.10/tests/test_uncurry.py diff --git a/23.10/tests/test_uncurry.py b/23.10/tests/test_uncurry.py new file mode 100644 index 0000000..6236cbe --- /dev/null +++ b/23.10/tests/test_uncurry.py @@ -0,0 +1,70 @@ +import sys +from pathlib import Path + +import pytest + +sys.path.append(f"{Path(__file__).parent.parent}") + +from src.curry import curry, uncurry + + +def test_uncurry_zero_args(): + def f(): + return range(10) + + curried = curry(f, 0) + uncurried = uncurry(curried) + + assert uncurried() == f() + + +def test_uncurry_one_arg(): + def f(a): + return a + + curried = curry(f, 1) + uncurried = uncurry(curried) + + assert uncurried(2435234534252) == f(2435234534252) + + +def test_uncurry_two_args(): + def f(a, b): + return a + b + + curried = curry(f, 2) + uncurried = uncurry(curried) + + assert uncurried(5, 10) == f(5, 10) + + +def test_uncurry_three_args(): + def f(a, b, c): + return a - b & c + + curried = curry(f, 3) + uncurried = uncurry(curried) + + assert uncurried(2, 3, 4) == f(2, 3, 4) + + +def test_uncurry_insufficient_args(): + def add(a, b): + return a + b + + curried = curry(add, 2) + uncurried = uncurry(curried) + + with pytest.raises(ValueError): + uncurried(5) + + +def test_uncurry_excessive_args(): + def f(a, b): + return a + b + + curried = curry(f, 2) + uncurried_add = uncurry(curried) + + with pytest.raises(ValueError): + uncurried_add(1, 2, 3)