diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 00000000..75a2e367 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,31 @@ +name: Run Tests + +on: + [ push, pull_request ] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.8' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Install mypy + run: | + python -m pip install mypy + - name: Run mypy + run: | + mypy . + - name: Run tests + run: | + python ./scripts/run_tests.py diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000..624cd195 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,2 @@ +[mypy] +exclude = venv/ diff --git a/project/generators.py b/project/generators.py new file mode 100644 index 00000000..24ec79ef --- /dev/null +++ b/project/generators.py @@ -0,0 +1,52 @@ +from itertools import product +from typing import Generator, Callable, List + + +def get_rgba_element(index: int): + """Генераторное выражение для четырехмерного набора векторов RGBA, где A - четное.""" + rgba_space = ( + (r, g, b, a) + for r, g, b, a in product(range(256), range(256), range(256), range(0, 101, 2)) + ) + + for i, value in enumerate(rgba_space): + if i == index: + return value + raise IndexError("Index out of range") + + +def prime_generator() -> Generator[int, None, None]: + """Генератор простых чисел.""" + primes: List[int] = [] + num = 2 + while True: + if all(num % p != 0 for p in primes): + primes.append(num) + yield num + num += 1 + + +def prime_decorator( + gen: Callable[[], Generator[int, None, None]] +) -> Callable[[int], int]: + """Декоратор, превращающий генератор в функцию, возвращающую k-е простое число.""" + cache: List[int] = [] + generator = gen() + + def wrapper(k: int) -> int: + if k < 1: + raise ValueError("Index must be greater than or equal to 1") + while len(cache) < k: + cache.append(next(generator)) + return cache[k - 1] + + return wrapper + + +def get_rgba(index: int): + return get_rgba_element(index) + + +@prime_decorator +def get_prime(): + return prime_generator() diff --git a/tests/test_basic.py b/tests/test_basic.py deleted file mode 100644 index 4811167b..00000000 --- a/tests/test_basic.py +++ /dev/null @@ -1,18 +0,0 @@ -import pytest -import project # on import will print something from __init__ file - - -def setup_module(module): - print("basic setup module") - - -def teardown_module(module): - print("basic teardown module") - - -def test_1(): - assert 1 + 1 == 2 - - -def test_2(): - assert "1" + "1" == "11" diff --git a/tests/test_generators.py b/tests/test_generators.py new file mode 100644 index 00000000..41b43497 --- /dev/null +++ b/tests/test_generators.py @@ -0,0 +1,33 @@ +from itertools import product + +import pytest + +from project.generators import get_rgba, get_prime + + +@pytest.mark.parametrize( + "index, expected", + [ + (0, (0, 0, 0, 0)), + (1, (0, 0, 0, 2)), + (10, (0, 0, 0, 20)), + (255, (0, 0, 5, 0)), + ], +) +def test_rgba(index, expected): + assert get_rgba(index) == expected + + +@pytest.mark.parametrize("k, expected", [(1, 2), (2, 3), (3, 5), (10, 29), (20, 71)]) +def test_prime(k, expected): + assert get_prime(k) == expected + + +def test_rgba_out_of_range(): + with pytest.raises(IndexError): + get_rgba(10**9) + + +def test_prime_invalid_index(): + with pytest.raises(ValueError): + get_prime(0)