From 1b47977c4838f62b4fb587a3c020ba7ff9ed2d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A8=D0=B2=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B1?= Date: Mon, 3 Feb 2025 14:45:10 +0300 Subject: [PATCH 01/10] feat(generators): add RGBA generator and prime number sequence with decorator --- project/generators.py | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 project/generators.py diff --git a/project/generators.py b/project/generators.py new file mode 100644 index 00000000..a52d3e08 --- /dev/null +++ b/project/generators.py @@ -0,0 +1,48 @@ +from itertools import product +from typing import Generator, Callable + + +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 = [] + 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 = [] + 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 + + +@get_rgba_element +def get_rgba(index: int): + return get_rgba_element(index) + + +@prime_decorator +def get_prime(): + return prime_generator() \ No newline at end of file From ee9a44dfd936e46ffc9ef5c06d7ac8f4f8f9d185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A8=D0=B2=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B1?= Date: Mon, 3 Feb 2025 15:20:29 +0300 Subject: [PATCH 02/10] fix(generators): delete @get_rgba_element and add call of get_rgba_element into get_rgba --- project/generators.py | 5 +++-- tests/test_basic.py | 18 ------------------ tests/tests_generators.py | 0 3 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 tests/test_basic.py create mode 100644 tests/tests_generators.py diff --git a/project/generators.py b/project/generators.py index a52d3e08..da9d65a4 100644 --- a/project/generators.py +++ b/project/generators.py @@ -38,11 +38,12 @@ def wrapper(k: int) -> int: return wrapper -@get_rgba_element def get_rgba(index: int): return get_rgba_element(index) @prime_decorator def get_prime(): - return prime_generator() \ No newline at end of file + 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/tests_generators.py b/tests/tests_generators.py new file mode 100644 index 00000000..e69de29b From 99167803272a9c1c2cbd7c771dcf0493072ae48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D1=84=D0=B8=D1=8F=20=D0=A8=D0=B2=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B1?= Date: Mon, 3 Feb 2025 15:24:22 +0300 Subject: [PATCH 03/10] feat(tests): add unit tests for generator.py --- tests/tests_generators.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/tests_generators.py b/tests/tests_generators.py index e69de29b..593d3cc3 100644 --- a/tests/tests_generators.py +++ b/tests/tests_generators.py @@ -0,0 +1,34 @@ +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**8) + +def test_prime_invalid_index(): + with pytest.raises(ValueError): + get_prime(0) + From f79c88c0f5d67f49374690b4991af6dd4358b349 Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 18:22:15 +0300 Subject: [PATCH 04/10] feat(ci): ci added --- .github/workflows/ci.yaml | 31 +++++++++++++++++++++++++++++++ mypy.ini | 2 ++ 2 files changed, 33 insertions(+) create mode 100644 .github/workflows/ci.yaml create mode 100644 mypy.ini 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/ From 207a8b85a9711e05238d32d7c855e142c9503bcb Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 19:36:05 +0300 Subject: [PATCH 05/10] fix(mypy): annotation added --- project/generators.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/project/generators.py b/project/generators.py index da9d65a4..2278c624 100644 --- a/project/generators.py +++ b/project/generators.py @@ -14,7 +14,7 @@ def get_rgba_element(index: int): def prime_generator() -> Generator[int, None, None]: """Генератор простых чисел.""" - primes = [] + primes: list[int] = [] num = 2 while True: if all(num % p != 0 for p in primes): @@ -25,7 +25,7 @@ def prime_generator() -> Generator[int, None, None]: def prime_decorator(gen: Callable[[], Generator[int, None, None]]) -> Callable[[int], int]: """Декоратор, превращающий генератор в функцию, возвращающую k-е простое число.""" - cache = [] + cache: list[int] = [] generator = gen() def wrapper(k: int) -> int: @@ -44,6 +44,4 @@ def get_rgba(index: int): @prime_decorator def get_prime(): - return prime_generator() - - + return prime_generator() \ No newline at end of file From 10510705b5a8e77ef54141239f6d5c1ea3d4fa15 Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 19:37:40 +0300 Subject: [PATCH 06/10] fix(mypy): List instead of list --- project/generators.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project/generators.py b/project/generators.py index 2278c624..16670c0e 100644 --- a/project/generators.py +++ b/project/generators.py @@ -1,5 +1,5 @@ from itertools import product -from typing import Generator, Callable +from typing import Generator, Callable, List def get_rgba_element(index: int): @@ -14,7 +14,7 @@ def get_rgba_element(index: int): def prime_generator() -> Generator[int, None, None]: """Генератор простых чисел.""" - primes: list[int] = [] + primes: List[int] = [] num = 2 while True: if all(num % p != 0 for p in primes): @@ -25,7 +25,7 @@ def prime_generator() -> Generator[int, None, None]: def prime_decorator(gen: Callable[[], Generator[int, None, None]]) -> Callable[[int], int]: """Декоратор, превращающий генератор в функцию, возвращающую k-е простое число.""" - cache: list[int] = [] + cache: List[int] = [] generator = gen() def wrapper(k: int) -> int: From 476d2d4a4fb7e2340a382c0c6fe6276598f3f89c Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 19:41:57 +0300 Subject: [PATCH 07/10] fix(tests): test --- tests/{tests_generators.py => test_generators.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{tests_generators.py => test_generators.py} (100%) diff --git a/tests/tests_generators.py b/tests/test_generators.py similarity index 100% rename from tests/tests_generators.py rename to tests/test_generators.py From 75d4517b5c0a1ff267f5dcbdbaa0ff00930cc612 Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 19:46:16 +0300 Subject: [PATCH 08/10] chore(code): code beautify --- project/generators.py | 11 ++++++++--- tests/test_generators.py | 19 +++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/project/generators.py b/project/generators.py index 16670c0e..24ec79ef 100644 --- a/project/generators.py +++ b/project/generators.py @@ -4,7 +4,10 @@ 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))) + 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: @@ -23,7 +26,9 @@ def prime_generator() -> Generator[int, None, None]: num += 1 -def prime_decorator(gen: Callable[[], Generator[int, None, None]]) -> Callable[[int], int]: +def prime_decorator( + gen: Callable[[], Generator[int, None, None]] +) -> Callable[[int], int]: """Декоратор, превращающий генератор в функцию, возвращающую k-е простое число.""" cache: List[int] = [] generator = gen() @@ -44,4 +49,4 @@ def get_rgba(index: int): @prime_decorator def get_prime(): - return prime_generator() \ No newline at end of file + return prime_generator() diff --git a/tests/test_generators.py b/tests/test_generators.py index 593d3cc3..209c3cae 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -5,30 +5,29 @@ from project.generators import get_rgba, get_prime -@pytest.mark.parametrize("index, expected", [ +@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) -]) + +@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**8) + def test_prime_invalid_index(): with pytest.raises(ValueError): get_prime(0) - From 6523c4ef30dffbbbcaeef1413b0adb9028de0540 Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 19:49:07 +0300 Subject: [PATCH 09/10] chore(code): code beautify --- tests/test_generators.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_generators.py b/tests/test_generators.py index 209c3cae..3cbe87aa 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -8,17 +8,17 @@ @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)), + (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)]) +@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 From 8c0df39e3477ce2312b0adbeddbb9e9d96bdb07d Mon Sep 17 00:00:00 2001 From: Sem4kok Date: Sat, 5 Apr 2025 19:51:17 +0300 Subject: [PATCH 10/10] fix(test): out of range --- tests/test_generators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_generators.py b/tests/test_generators.py index 3cbe87aa..41b43497 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -25,7 +25,7 @@ def test_prime(k, expected): def test_rgba_out_of_range(): with pytest.raises(IndexError): - get_rgba(10**8) + get_rgba(10**9) def test_prime_invalid_index():