Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Run tests with pytest
on:
push:
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
45 changes: 45 additions & 0 deletions 23.10/src/curry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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
if len(args) == 0:
try:
res = res()
except TypeError:
raise TypeError from TypeError

for i in args:
if not callable(res):
raise ValueError("Передано слишком много аргументов")
res = res(i)

if callable(res):
raise ValueError("Передано недостаточно аргументов")

return res

return uncurried
49 changes: 49 additions & 0 deletions 23.10/tests/test_curry.py
Original file line number Diff line number Diff line change
@@ -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)()
70 changes: 70 additions & 0 deletions 23.10/tests/test_uncurry.py
Original file line number Diff line number Diff line change
@@ -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)