From 3c84ec0420f8a79f12829227b6810e2feb7abbf3 Mon Sep 17 00:00:00 2001 From: Ilya Gubernator Date: Fri, 17 Oct 2025 19:39:37 +0300 Subject: [PATCH 01/41] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20CI=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..46cf5a0 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,26 @@ +name: Python CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Получаем код из репозитория + uses: actions/checkout@v3 + + - name: Устанавливаем Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Проверяем, что код запускается + run: | + echo "Запуск проверки Python..." + python --version + echo "✅ CI успешно выполнен!" From 22a83d3c7f5e1959b96db07fa4e7c7a20cc48f79 Mon Sep 17 00:00:00 2001 From: Ilya Gubernator Date: Fri, 17 Oct 2025 20:09:58 +0300 Subject: [PATCH 02/41] =?UTF-8?q?test:=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BA=D0=B0=20CI=20=D0=BD=D0=B0=20=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D0=BA=D0=B5=20development?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 21e2350..e6a766a 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,4 @@ YouTube: [YouTube](http://www.youtube.com/allaboutpython?sub_confirmation=1)\ Instagram: [Instagram](https://www.instagram.com/itsallaboutpython)\ Blog Site: [Site](https://itsallaboutpython.blogspot.com/)\ GitHub: [GitHub](https://github.com/visheshdvivedi/) +# Тест CI на ветке development From c1062bf0478bd379cf8902995116d6c6d610d5ca Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 17:42:17 +0300 Subject: [PATCH 03/41] unit test for calculator Add unit tests for the addition function in calculator. --- tests/test_calculator.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/test_calculator.py diff --git a/tests/test_calculator.py b/tests/test_calculator.py new file mode 100644 index 0000000..7d0aee3 --- /dev/null +++ b/tests/test_calculator.py @@ -0,0 +1,8 @@ +import pytest +from calculator import add + +def test_addition(): + """Проверяем базовую работу функции сложения""" + assert add(2, 3) == 5 + assert add(-1, 1) == 0 + assert add(0, 0) == 0 From 4df28c4e00b8d0e0090285c68d9b221dd93e8a28 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 17:47:19 +0300 Subject: [PATCH 04/41] Refactor calculator to include add function --- calculator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calculator.py b/calculator.py index c4cfd16..2224b1b 100644 --- a/calculator.py +++ b/calculator.py @@ -1,3 +1,6 @@ +def add(a, b): + """Функция сложения для тестов""" + return a + b print("===== Welcome to Calculator App =====\n") while 1: print("What would you like to do:-") @@ -21,3 +24,4 @@ print("Exiting...") break print() + From f5fe865863138b9d6966553bd131137ed555742c Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 17:52:08 +0300 Subject: [PATCH 05/41] Refactor CI/CD pipeline for multiple branches and docs Updated CI/CD pipeline to include development and release branches, and improved documentation generation steps. --- .github/workflows/main.yml | 56 ++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 46cf5a0..d755ae1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,26 +1,60 @@ -name: Python CI +name: CI/CD Pipeline on: push: - branches: [ "main" ] + branches: + - main + - development + - release pull_request: - branches: [ "main" ] + branches: + - main jobs: - build: + build-and-test: runs-on: ubuntu-latest + steps: + - name: 🧩 Checkout repository + uses: actions/checkout@v3 + + - name: 🐍 Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: 📦 Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + - name: 🧪 Run unit tests + run: | + pytest -v || exit 1 + + generate-docs: + runs-on: ubuntu-latest + needs: build-and-test steps: - - name: Получаем код из репозитория + - name: 📂 Checkout repository uses: actions/checkout@v3 - - name: Устанавливаем Python + - name: 🐍 Set up Python uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: '3.10' - - name: Проверяем, что код запускается + - name: 🧰 Install tools run: | - echo "Запуск проверки Python..." - python --version - echo "✅ CI успешно выполнен!" + python -m pip install --upgrade pip + pip install pdoc3 + + - name: 📝 Generate documentation + run: | + mkdir -p docs + pdoc --output-dir docs . || echo "Docs generated" + + - name: 📤 Upload docs as artifact + uses: actions/upload-artifact@v3 + with: + name: project-docs + path: docs/ From e414415c591eb3ac71c54eb2c596ba83eb414fd8 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 17:56:13 +0300 Subject: [PATCH 06/41] Fix indentation in test_addition function --- tests/test_calculator.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 7d0aee3..d81da0c 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -1,6 +1,11 @@ +import sys +import os +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + import pytest from calculator import add + def test_addition(): """Проверяем базовую работу функции сложения""" assert add(2, 3) == 5 From aeb23ca066008bfe86eff36dcd0992234d47cf9c Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 17:59:05 +0300 Subject: [PATCH 07/41] Refactor calculator app to use main guard --- calculator.py | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/calculator.py b/calculator.py index 2224b1b..202f4d9 100644 --- a/calculator.py +++ b/calculator.py @@ -1,27 +1,30 @@ def add(a, b): """Функция сложения для тестов""" return a + b -print("===== Welcome to Calculator App =====\n") -while 1: - print("What would you like to do:-") - print("1. Addition") - print("2. Subtraction") - print("3 Multiplication") - print("4. Division") - print("5. Exit") - choice = int(input("Enter your choice: ")) - num1 = int(input("Enter first number: ")) - num2 = int(input("Enter second number: ")) - if choice == 1: - print("Output: ", num1+num2) - elif choice == 2: - print("Output: ", num1-num2) - elif choice == 3: - print("Output: ", num1*num2) - elif choice == 4: - print("Output: ", num1/num2) - elif choice == 5: - print("Exiting...") - break - print() + +if __name__ == "__main__": + print("===== Welcome to Calculator App =====\n") + while True: + print("What would you like to do:-") + print("1. Addition") + print("2. Subtraction") + print("3 Multiplication") + print("4. Division") + print("5. Exit") + choice = int(input("Enter your choice: ")) + num1 = int(input("Enter first number: ")) + num2 = int(input("Enter second number: ")) + + if choice == 1: + print("Output:", num1 + num2) + elif choice == 2: + print("Output:", num1 - num2) + elif choice == 3: + print("Output:", num1 * num2) + elif choice == 4: + print("Output:", num1 / num2) + elif choice == 5: + print("Exiting...") + break + print() From 94622493a1feaf55fbb483d80c357f7fb709c28a Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 18:02:35 +0300 Subject: [PATCH 08/41] Update main.yml From 9b292444d6dd4d52fcb0325931e41e36a3b20f14 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 18:04:58 +0300 Subject: [PATCH 09/41] Update upload-artifact action to version 4 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d755ae1..2e5bcc7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -54,7 +54,7 @@ jobs: pdoc --output-dir docs . || echo "Docs generated" - name: 📤 Upload docs as artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: project-docs path: docs/ From e5186de8a729a775c4b70ddfa50eec402e308c07 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 18:08:08 +0300 Subject: [PATCH 10/41] Enhance calculator.py with module description Added a module description and improved formatting. --- calculator.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/calculator.py b/calculator.py index 202f4d9..4e78127 100644 --- a/calculator.py +++ b/calculator.py @@ -1,3 +1,8 @@ +""" +Calculator module for CI/CD demo. + +This module provides basic arithmetic operations. +""" def add(a, b): """Функция сложения для тестов""" return a + b @@ -28,3 +33,4 @@ def add(a, b): print("Exiting...") break print() + From ffb030ad86d37cc9b29f2a29df9441afd87dbe7d Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 18 Oct 2025 18:12:49 +0300 Subject: [PATCH 11/41] Update documentation generation command in workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2e5bcc7..b82165f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,7 +51,7 @@ jobs: - name: 📝 Generate documentation run: | mkdir -p docs - pdoc --output-dir docs . || echo "Docs generated" + pdoc calculator.py --output-dir docs || echo "Docs generated" - name: 📤 Upload docs as artifact uses: actions/upload-artifact@v4 From 83177394243f0f15b67c495ba3f43acc9c4d48ac Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 16:31:32 +0300 Subject: [PATCH 12/41] Add test for multiply function in test_calculator.py --- tests/test_calculator.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index d81da0c..ed1848e 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -11,3 +11,9 @@ def test_addition(): assert add(2, 3) == 5 assert add(-1, 1) == 0 assert add(0, 0) == 0 + + +def test_multiply(): + """Проверяем умножение (ожидаем ошибку, функции пока нет)""" + from calculator import multiply + assert multiply(2, 3) == 6 From 3635d622bc9059992e473b25593ded4506112cf5 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 16:37:42 +0300 Subject: [PATCH 13/41] Refactor calculator.py to include multiply function Added a multiply function for multiplying two numbers. --- calculator.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/calculator.py b/calculator.py index 4e78127..9ad96da 100644 --- a/calculator.py +++ b/calculator.py @@ -34,3 +34,8 @@ def add(a, b): break print() +def multiply(a, b): + """Умножение двух чисел.""" + return a * b + + From e7b004a3dbcf594e21f762a0d4da472b972b692e Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 17:02:33 +0300 Subject: [PATCH 14/41] Expand test coverage for calculator functions Added comprehensive tests for various calculator functions including addition, subtraction, multiplication, division, power, absolute value, rounding, list addition, type checking, safe division, percentage calculation, square root, and combined operations. --- tests/test_calculator.py | 90 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index ed1848e..0da7f58 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -3,17 +3,93 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import pytest -from calculator import add - +import pytest +from calculator import ( + add, + subtract, + multiply, + divide, + power, + absolute, + round_value, + add_list, + check_number_type, + safe_divide, + percentage, + square_root +) -def test_addition(): - """Проверяем базовую работу функции сложения""" +# 1. Сложение +def test_add(): assert add(2, 3) == 5 assert add(-1, 1) == 0 assert add(0, 0) == 0 +# 2. Вычитание +def test_subtract(): + assert subtract(10, 4) == 6 + assert subtract(0, 5) == -5 +# 3. Умножение def test_multiply(): - """Проверяем умножение (ожидаем ошибку, функции пока нет)""" - from calculator import multiply - assert multiply(2, 3) == 6 + assert multiply(3, 3) == 9 + assert multiply(-2, 4) == -8 + +# 4–5. Деление и деление на ноль +def test_divide(): + assert divide(8, 2) == 4 + +def test_divide_by_zero(): + with pytest.raises(ZeroDivisionError): + divide(5, 0) + +# 6. Возведение в степень +def test_power(): + assert power(2, 3) == 8 + assert power(5, 0) == 1 + +# 7. Абсолютное значение +def test_absolute(): + assert absolute(-10) == 10 + assert absolute(5) == 5 + +# 8. Округление +def test_round_value(): + assert round_value(3.14159) == 3.14 + assert round_value(3.14159, 3) == 3.142 + +# 9. Сумма элементов списка +def test_add_list(): + assert add_list([1, 2, 3]) == 6 + assert add_list([]) == 0 + +# 10. Проверка типа данных +def test_check_number_type(): + assert check_number_type(5) + assert check_number_type(5.5) + assert not check_number_type("string") + +# 11. Безопасное деление +def test_safe_divide(): + assert safe_divide(10, 2) == 5 + assert safe_divide(10, 0) is None + +# 12. Проценты +def test_percentage(): + assert percentage(50, 200) == 25 + assert percentage(1, 4) == 25 + +# 13. Квадратный корень +def test_square_root(): + assert square_root(9) == 3 + assert round(square_root(2), 3) == 1.414 + +# 14. Комбинированная операция +def test_combined_operations(): + result = multiply(add(2, 3), power(2, 2)) + assert result == 20 + +# 15. Проверка округления в сложных выражениях +def test_round_combined(): + result = round_value(divide(10, 3), 2) + assert result == 3.33 From 85a925b3439f7c74d4c3bdeb7fbe685dd01a1d51 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 17:11:14 +0300 Subject: [PATCH 15/41] Revise calculator module for TDD RED phase Refactor calculator for TDD demo with intentional errors. --- calculator.py | 121 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 31 deletions(-) diff --git a/calculator.py b/calculator.py index 9ad96da..a8a3af0 100644 --- a/calculator.py +++ b/calculator.py @@ -1,41 +1,100 @@ """ -Calculator module for CI/CD demo. - -This module provides basic arithmetic operations. +Calculator module for TDD demo (RED phase). +Фаза RED — все функции либо содержат ошибки, либо не реализованы. +Цель: чтобы тесты упали и показать процесс RED → GREEN. """ + +# 🔴 Итерация 1: add() — неправильное сложение def add(a, b): - """Функция сложения для тестов""" - return a + b + """Функция сложения (ошибка намеренно)""" + return a - b # ❌ должно быть a + b -if __name__ == "__main__": - print("===== Welcome to Calculator App =====\n") - while True: - print("What would you like to do:-") - print("1. Addition") - print("2. Subtraction") - print("3 Multiplication") - print("4. Division") - print("5. Exit") - choice = int(input("Enter your choice: ")) - num1 = int(input("Enter first number: ")) - num2 = int(input("Enter second number: ")) - - if choice == 1: - print("Output:", num1 + num2) - elif choice == 2: - print("Output:", num1 - num2) - elif choice == 3: - print("Output:", num1 * num2) - elif choice == 4: - print("Output:", num1 / num2) - elif choice == 5: - print("Exiting...") - break - print() +# 🔴 Итерация 2: subtract() — не реализована +def subtract(a, b): + """Функция вычитания (не реализована)""" + pass + +# 🔴 Итерация 3: multiply() — ошибка логики def multiply(a, b): - """Умножение двух чисел.""" + """Функция умножения (ошибка намеренно)""" + return a + b + + +# 🔴 Итерация 4: divide() — без обработки нуля +def divide(a, b): + """Функция деления (ошибка при b = 0)""" + return a / b + + +# 🔴 Итерация 5: power() — возвращает строку +def power(a, b): + """Возведение в степень (ошибка — возвращает строку)""" + return str(a ** b) + + +# 🔴 Итерация 6: absolute() — неверное поведение +def absolute(a): + """Модуль числа (ошибка — не берёт abs)""" + return a + + +# 🔴 Итерация 7: percentage() — неверная формула +def percentage(a, b): + """Процент от числа (ошибка намеренно)""" return a * b +# 🔴 Итерация 8: round_value() — не округляет +def round_value(a, digits=2): + """Округление числа (ошибка намеренно)""" + return a + + +# 🔴 Итерация 9: square_root() — не проверяет отрицательные +def square_root(a): + """Квадратный корень числа (ошибка для отрицательных)""" + import math + return math.sqrt(a) # ❌ при отрицательном — ошибка + + +# 🔴 Итерация 10: mod() — неверная формула +def mod(a, b): + """Остаток от деления (ошибка)""" + return a / b # ❌ вместо % + + +# 🔴 Итерация 11: max_value() — возвращает min +def max_value(a, b): + """Максимум из двух чисел (ошибка)""" + return min(a, b) + + +# 🔴 Итерация 12: min_value() — возвращает max +def min_value(a, b): + """Минимум из двух чисел (ошибка)""" + return max(a, b) + + +# 🔴 Итерация 13: safe_divide() — падает при делении на ноль +def safe_divide(a, b): + """Безопасное деление (ошибка — без проверки на 0)""" + return a / b + + +# 🔴 Итерация 14: average() — неверная логика +def average(numbers): + """Среднее значение (ошибка — не делит на длину)""" + return sum(numbers) + + +# 🔴 Итерация 15: factorial() — возвращает 0 +def factorial(n): + """Факториал числа (ошибка — всегда возвращает 0)""" + return 0 + + +if __name__ == "__main__": + print("===== Calculator RED Phase =====") + print("This version intentionally contains 15 errors.") From 4ea454b14a87f297b4860af0cf7e670ae9100653 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 17:16:47 +0300 Subject: [PATCH 16/41] Refactor calculator for TDD GREEN phase --- calculator.py | 117 +++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/calculator.py b/calculator.py index a8a3af0..0f389ec 100644 --- a/calculator.py +++ b/calculator.py @@ -1,100 +1,119 @@ """ -Calculator module for TDD demo (RED phase). -Фаза RED — все функции либо содержат ошибки, либо не реализованы. -Цель: чтобы тесты упали и показать процесс RED → GREEN. +Calculator module for TDD demo (GREEN phase). +Фаза GREEN — все функции реализованы корректно и проходят тесты. +Цель: все тесты должны завершаться успешно. """ -# 🔴 Итерация 1: add() — неправильное сложение +import math + + + def add(a, b): - """Функция сложения (ошибка намеренно)""" - return a - b # ❌ должно быть a + b + """Функция сложения""" + return a + b -# 🔴 Итерация 2: subtract() — не реализована +# 🟢 Итерация 2: subtract() — реализовано def subtract(a, b): - """Функция вычитания (не реализована)""" - pass + """Функция вычитания""" + return a - b -# 🔴 Итерация 3: multiply() — ошибка логики +# 🟢 Итерация 3: multiply() — исправлено def multiply(a, b): - """Функция умножения (ошибка намеренно)""" - return a + b + """Функция умножения""" + return a * b -# 🔴 Итерация 4: divide() — без обработки нуля +# 🟢 Итерация 4: divide() — с обработкой деления на ноль def divide(a, b): - """Функция деления (ошибка при b = 0)""" + """Функция деления с проверкой деления на 0""" + if b == 0: + raise ZeroDivisionError("Division by zero is not allowed.") return a / b -# 🔴 Итерация 5: power() — возвращает строку +# 🟢 Итерация 5: power() — исправлено def power(a, b): - """Возведение в степень (ошибка — возвращает строку)""" - return str(a ** b) + """Возведение в степень""" + return a ** b -# 🔴 Итерация 6: absolute() — неверное поведение +# 🟢 Итерация 6: absolute() — исправлено def absolute(a): - """Модуль числа (ошибка — не берёт abs)""" - return a + """Модуль числа""" + return abs(a) -# 🔴 Итерация 7: percentage() — неверная формула +# 🟢 Итерация 7: percentage() — исправлено def percentage(a, b): - """Процент от числа (ошибка намеренно)""" - return a * b + """Вычисление процента a от b""" + if b == 0: + return 0 + return (a / b) * 100 -# 🔴 Итерация 8: round_value() — не округляет +# 🟢 Итерация 8: round_value() — исправлено def round_value(a, digits=2): - """Округление числа (ошибка намеренно)""" - return a + """Округление числа""" + return round(a, digits) -# 🔴 Итерация 9: square_root() — не проверяет отрицательные +# 🟢 Итерация 9: square_root() — исправлено def square_root(a): - """Квадратный корень числа (ошибка для отрицательных)""" - import math - return math.sqrt(a) # ❌ при отрицательном — ошибка + """Квадратный корень (возвращает None для отрицательных чисел)""" + if a < 0: + return None + return math.sqrt(a) -# 🔴 Итерация 10: mod() — неверная формула +# 🟢 Итерация 10: mod() — исправлено def mod(a, b): - """Остаток от деления (ошибка)""" - return a / b # ❌ вместо % + """Остаток от деления""" + return a % b -# 🔴 Итерация 11: max_value() — возвращает min +# 🟢 Итерация 11: max_value() — исправлено def max_value(a, b): - """Максимум из двух чисел (ошибка)""" - return min(a, b) + """Максимум из двух чисел""" + return max(a, b) -# 🔴 Итерация 12: min_value() — возвращает max +# 🟢 Итерация 12: min_value() — исправлено def min_value(a, b): - """Минимум из двух чисел (ошибка)""" - return max(a, b) + """Минимум из двух чисел""" + return min(a, b) -# 🔴 Итерация 13: safe_divide() — падает при делении на ноль +# 🟢 Итерация 13: safe_divide() — исправлено def safe_divide(a, b): - """Безопасное деление (ошибка — без проверки на 0)""" + """Безопасное деление (возвращает None при делении на 0)""" + if b == 0: + return None return a / b -# 🔴 Итерация 14: average() — неверная логика +# 🟢 Итерация 14: average() — исправлено def average(numbers): - """Среднее значение (ошибка — не делит на длину)""" - return sum(numbers) + """Среднее значение списка чисел""" + if not numbers: + return 0 + return sum(numbers) / len(numbers) -# 🔴 Итерация 15: factorial() — возвращает 0 +# 🟢 Итерация 15: factorial() — исправлено def factorial(n): - """Факториал числа (ошибка — всегда возвращает 0)""" - return 0 + """Факториал числа""" + if n < 0: + return None + if n == 0 or n == 1: + return 1 + result = 1 + for i in range(2, n + 1): + result *= i + return result if __name__ == "__main__": - print("===== Calculator RED Phase =====") - print("This version intentionally contains 15 errors.") + print("===== Calculator GREEN Phase =====") + print("All tests should now pass successfully ✅") From 98f28981fc266bc5cb296d1e1a08844ceae29f41 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 17:24:16 +0300 Subject: [PATCH 17/41] Refactor calculator functions for clarity and fixes --- calculator.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 0f389ec..be8ce95 100644 --- a/calculator.py +++ b/calculator.py @@ -7,7 +7,7 @@ import math - +# 🟢 Итерация 1: add() — исправлено def add(a, b): """Функция сложения""" return a + b @@ -114,6 +114,17 @@ def factorial(n): return result +# ✅ Доп. функции для тестов (чтобы CI не падал) +def add_list(numbers): + """Суммирует элементы списка.""" + return sum(numbers) if numbers else 0 + + +def check_number_type(value): + """Проверяет, что значение — число (int или float).""" + return isinstance(value, (int, float)) + + if __name__ == "__main__": print("===== Calculator GREEN Phase =====") print("All tests should now pass successfully ✅") From 926952fc57fa7c3e198f81df8b19f386b32d84e3 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 18:34:17 +0300 Subject: [PATCH 18/41] Fix add function to correctly perform addition --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index be8ce95..0b5afae 100644 --- a/calculator.py +++ b/calculator.py @@ -10,7 +10,7 @@ # 🟢 Итерация 1: add() — исправлено def add(a, b): """Функция сложения""" - return a + b + return a - b # 🟢 Итерация 2: subtract() — реализовано @@ -128,3 +128,4 @@ def check_number_type(value): if __name__ == "__main__": print("===== Calculator GREEN Phase =====") print("All tests should now pass successfully ✅") + From 113c5d148282d71753ac78bafecbd6bdb458ad1d Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 21:42:46 +0300 Subject: [PATCH 19/41] Simplify test_calculator.py to only test addition Removed multiple test cases and kept only the test for the add function. --- tests/test_calculator.py | 90 +--------------------------------------- 1 file changed, 2 insertions(+), 88 deletions(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 0da7f58..72ed3b8 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -3,93 +3,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import pytest -import pytest -from calculator import ( - add, - subtract, - multiply, - divide, - power, - absolute, - round_value, - add_list, - check_number_type, - safe_divide, - percentage, - square_root -) - -# 1. Сложение +from calculator import add + def test_add(): assert add(2, 3) == 5 - assert add(-1, 1) == 0 - assert add(0, 0) == 0 - -# 2. Вычитание -def test_subtract(): - assert subtract(10, 4) == 6 - assert subtract(0, 5) == -5 - -# 3. Умножение -def test_multiply(): - assert multiply(3, 3) == 9 - assert multiply(-2, 4) == -8 - -# 4–5. Деление и деление на ноль -def test_divide(): - assert divide(8, 2) == 4 - -def test_divide_by_zero(): - with pytest.raises(ZeroDivisionError): - divide(5, 0) - -# 6. Возведение в степень -def test_power(): - assert power(2, 3) == 8 - assert power(5, 0) == 1 - -# 7. Абсолютное значение -def test_absolute(): - assert absolute(-10) == 10 - assert absolute(5) == 5 - -# 8. Округление -def test_round_value(): - assert round_value(3.14159) == 3.14 - assert round_value(3.14159, 3) == 3.142 - -# 9. Сумма элементов списка -def test_add_list(): - assert add_list([1, 2, 3]) == 6 - assert add_list([]) == 0 - -# 10. Проверка типа данных -def test_check_number_type(): - assert check_number_type(5) - assert check_number_type(5.5) - assert not check_number_type("string") - -# 11. Безопасное деление -def test_safe_divide(): - assert safe_divide(10, 2) == 5 - assert safe_divide(10, 0) is None - -# 12. Проценты -def test_percentage(): - assert percentage(50, 200) == 25 - assert percentage(1, 4) == 25 - -# 13. Квадратный корень -def test_square_root(): - assert square_root(9) == 3 - assert round(square_root(2), 3) == 1.414 - -# 14. Комбинированная операция -def test_combined_operations(): - result = multiply(add(2, 3), power(2, 2)) - assert result == 20 - -# 15. Проверка округления в сложных выражениях -def test_round_combined(): - result = round_value(divide(10, 3), 2) - assert result == 3.33 From a719ceb1177756ba425dcbb4ac9db7e7e35f29a1 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 21:56:47 +0300 Subject: [PATCH 20/41] Refactor calculator functions for TDD compliance Updated calculator functions to pass tests and added docstrings. --- calculator.py | 123 +------------------------------------------------- 1 file changed, 1 insertion(+), 122 deletions(-) diff --git a/calculator.py b/calculator.py index 0b5afae..13ca87a 100644 --- a/calculator.py +++ b/calculator.py @@ -6,126 +6,5 @@ import math - -# 🟢 Итерация 1: add() — исправлено def add(a, b): - """Функция сложения""" - return a - b - - -# 🟢 Итерация 2: subtract() — реализовано -def subtract(a, b): - """Функция вычитания""" - return a - b - - -# 🟢 Итерация 3: multiply() — исправлено -def multiply(a, b): - """Функция умножения""" - return a * b - - -# 🟢 Итерация 4: divide() — с обработкой деления на ноль -def divide(a, b): - """Функция деления с проверкой деления на 0""" - if b == 0: - raise ZeroDivisionError("Division by zero is not allowed.") - return a / b - - -# 🟢 Итерация 5: power() — исправлено -def power(a, b): - """Возведение в степень""" - return a ** b - - -# 🟢 Итерация 6: absolute() — исправлено -def absolute(a): - """Модуль числа""" - return abs(a) - - -# 🟢 Итерация 7: percentage() — исправлено -def percentage(a, b): - """Вычисление процента a от b""" - if b == 0: - return 0 - return (a / b) * 100 - - -# 🟢 Итерация 8: round_value() — исправлено -def round_value(a, digits=2): - """Округление числа""" - return round(a, digits) - - -# 🟢 Итерация 9: square_root() — исправлено -def square_root(a): - """Квадратный корень (возвращает None для отрицательных чисел)""" - if a < 0: - return None - return math.sqrt(a) - - -# 🟢 Итерация 10: mod() — исправлено -def mod(a, b): - """Остаток от деления""" - return a % b - - -# 🟢 Итерация 11: max_value() — исправлено -def max_value(a, b): - """Максимум из двух чисел""" - return max(a, b) - - -# 🟢 Итерация 12: min_value() — исправлено -def min_value(a, b): - """Минимум из двух чисел""" - return min(a, b) - - -# 🟢 Итерация 13: safe_divide() — исправлено -def safe_divide(a, b): - """Безопасное деление (возвращает None при делении на 0)""" - if b == 0: - return None - return a / b - - -# 🟢 Итерация 14: average() — исправлено -def average(numbers): - """Среднее значение списка чисел""" - if not numbers: - return 0 - return sum(numbers) / len(numbers) - - -# 🟢 Итерация 15: factorial() — исправлено -def factorial(n): - """Факториал числа""" - if n < 0: - return None - if n == 0 or n == 1: - return 1 - result = 1 - for i in range(2, n + 1): - result *= i - return result - - -# ✅ Доп. функции для тестов (чтобы CI не падал) -def add_list(numbers): - """Суммирует элементы списка.""" - return sum(numbers) if numbers else 0 - - -def check_number_type(value): - """Проверяет, что значение — число (int или float).""" - return isinstance(value, (int, float)) - - -if __name__ == "__main__": - print("===== Calculator GREEN Phase =====") - print("All tests should now pass successfully ✅") - + pass From 3d7d4dd0675619189353dc85cf857d923dbc1e80 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 21:59:04 +0300 Subject: [PATCH 21/41] Implement add function to return a fixed value --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 13ca87a..0b957b0 100644 --- a/calculator.py +++ b/calculator.py @@ -7,4 +7,5 @@ import math def add(a, b): - pass + return 5 + From 03d58a1d61b85cad08c45b65080b4229b24f0e2e Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:07:18 +0300 Subject: [PATCH 22/41] Add test for adding negative and positive numbers --- tests/test_calculator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 72ed3b8..2d6713a 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -7,3 +7,7 @@ def test_add(): assert add(2, 3) == 5 + + +def test_add_negative(): + assert add(-1, 1) == 0 From 2b633ccfce4df42c32ef3ea9fd638de786514dcb Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:10:49 +0300 Subject: [PATCH 23/41] Refactor add function to return the sum of two numbers --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 0b957b0..15880c4 100644 --- a/calculator.py +++ b/calculator.py @@ -7,5 +7,6 @@ import math def add(a, b): - return 5 + return a + b + From b4e6404b8e3e7753b6ccba784e9197d17579c7c1 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:13:40 +0300 Subject: [PATCH 24/41] Update test_calculator.py --- tests/test_calculator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 2d6713a..290f9bf 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -11,3 +11,6 @@ def test_add(): def test_add_negative(): assert add(-1, 1) == 0 + +def test_subtract(): + assert subtract(10, 4) == 6 From 93d07dc8fa708b0524c76fd8af7f65c6377283ad Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:14:10 +0300 Subject: [PATCH 25/41] Add subtract function placeholder to calculator.py --- calculator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calculator.py b/calculator.py index 15880c4..b27190d 100644 --- a/calculator.py +++ b/calculator.py @@ -9,4 +9,8 @@ def add(a, b): return a + b +def subtract(a, b): + pass + + From b2796d31ac2a4413fecd96e2c8b4c68bb0731ea4 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:16:01 +0300 Subject: [PATCH 26/41] Implement subtract function in calculator module --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index b27190d..c80e515 100644 --- a/calculator.py +++ b/calculator.py @@ -10,7 +10,8 @@ def add(a, b): return a + b def subtract(a, b): - pass + return 6 + From 3668550cf66e99102507ae6d59cc4c5e0488847a Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:19:43 +0300 Subject: [PATCH 27/41] Import subtract function in test_calculator.py --- tests/test_calculator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 290f9bf..587d789 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -3,7 +3,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import pytest -from calculator import add +from calculator import add, subtract def test_add(): assert add(2, 3) == 5 From 0d755757a86ae24406a7d1e036275cd4e540cd1b Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:22:31 +0300 Subject: [PATCH 28/41] Add test for subtracting negative numbers --- tests/test_calculator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 587d789..ffbcee8 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -14,3 +14,6 @@ def test_add_negative(): def test_subtract(): assert subtract(10, 4) == 6 + +def test_subtract_negative(): + assert subtract(0, 5) == -5 From 1976072990d367ab4adda599eebbb2545d715b73 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:24:33 +0300 Subject: [PATCH 29/41] Fix subtract function to perform correct operation --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index c80e515..39a95d3 100644 --- a/calculator.py +++ b/calculator.py @@ -10,7 +10,8 @@ def add(a, b): return a + b def subtract(a, b): - return 6 + return a - b + From 707c5834513eab3df6a8e41b80347e5bd780e0c9 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:26:49 +0300 Subject: [PATCH 30/41] Add multiply test case to test_calculator.py --- tests/test_calculator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index ffbcee8..3c5bbb5 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -17,3 +17,6 @@ def test_subtract(): def test_subtract_negative(): assert subtract(0, 5) == -5 + +def test_multiply(): + assert multiply(3, 3) == 9 From c52780f4b42ca74f48bee96d951f1b4aac28a5e6 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:27:46 +0300 Subject: [PATCH 31/41] Add multiply function placeholder Added a placeholder for the multiply function. --- calculator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calculator.py b/calculator.py index 39a95d3..2e873f2 100644 --- a/calculator.py +++ b/calculator.py @@ -12,6 +12,10 @@ def add(a, b): def subtract(a, b): return a - b +def multiply(a, b): + pass + + From 98f92e2342c20f13674b008d5b294730a84fbec8 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:30:02 +0300 Subject: [PATCH 32/41] Add multiply function to test_calculator.py --- tests/test_calculator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 3c5bbb5..c70e8f5 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -3,7 +3,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import pytest -from calculator import add, subtract +from calculator import add, subtract, multiply def test_add(): assert add(2, 3) == 5 From 01d9331ce69c3805c18994e1c12c70932e8a260e Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:30:35 +0300 Subject: [PATCH 33/41] Implement multiply function in calculator module --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 2e873f2..b6ed7cc 100644 --- a/calculator.py +++ b/calculator.py @@ -13,7 +13,8 @@ def subtract(a, b): return a - b def multiply(a, b): - pass + return 9 + From 1070b47966768be781934453954e2c52f327b576 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:32:53 +0300 Subject: [PATCH 34/41] Add test for multiplying negative numbers --- tests/test_calculator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index c70e8f5..8d875da 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -20,3 +20,6 @@ def test_subtract_negative(): def test_multiply(): assert multiply(3, 3) == 9 + +def test_multiply_negative(): + assert multiply(-2, 4) == -8 From 00292dea6e1764f1769e966a5e71b96a5c88f1a2 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:35:04 +0300 Subject: [PATCH 35/41] Fix multiply function to return correct product --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index b6ed7cc..f74f44a 100644 --- a/calculator.py +++ b/calculator.py @@ -13,7 +13,8 @@ def subtract(a, b): return a - b def multiply(a, b): - return 9 + return a * b + From 04d5fd34e3589636c31a6216bd4febcc053b69a5 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:37:46 +0300 Subject: [PATCH 36/41] Add test for divide function in test_calculator.py Added test for the divide function in the calculator module. --- tests/test_calculator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 8d875da..4237227 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -3,7 +3,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import pytest -from calculator import add, subtract, multiply +from calculator import add, subtract, multiply, divide def test_add(): assert add(2, 3) == 5 @@ -23,3 +23,6 @@ def test_multiply(): def test_multiply_negative(): assert multiply(-2, 4) == -8 + +def test_divide(): + assert divide(8, 2) == 4 From 46941072fad3773edc94df808b0f3a0b1f384e9b Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:38:22 +0300 Subject: [PATCH 37/41] Add divide function placeholder to calculator module Added a placeholder for the divide function. --- calculator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calculator.py b/calculator.py index f74f44a..4ce6cc9 100644 --- a/calculator.py +++ b/calculator.py @@ -15,6 +15,10 @@ def subtract(a, b): def multiply(a, b): return a * b +def divide(a, b): + pass + + From 4f427234ca679510cced0127d81ff2813c32b59b Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:40:38 +0300 Subject: [PATCH 38/41] Add divide function implementation Implemented the divide function to return a fixed value. --- calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 4ce6cc9..1f46bd8 100644 --- a/calculator.py +++ b/calculator.py @@ -16,7 +16,8 @@ def multiply(a, b): return a * b def divide(a, b): - pass + return 4 + From 4c0e07e3160affa25a24d06ec968a26846fca9ad Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:45:46 +0300 Subject: [PATCH 39/41] Add divide by zero test case Add test for dividing by zero in the divide function. --- tests/test_calculator.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 4237227..8961660 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -24,5 +24,6 @@ def test_multiply(): def test_multiply_negative(): assert multiply(-2, 4) == -8 -def test_divide(): - assert divide(8, 2) == 4 +def test_divide_by_zero(): + with pytest.raises(ZeroDivisionError): + divide(5, 0) From 68c39cc3cc7853bd3e931703ca8240c84734a0a9 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:47:26 +0300 Subject: [PATCH 40/41] Enhance divide function with zero division check Updated divide function to handle division by zero. --- calculator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/calculator.py b/calculator.py index 1f46bd8..ce86537 100644 --- a/calculator.py +++ b/calculator.py @@ -16,7 +16,10 @@ def multiply(a, b): return a * b def divide(a, b): - return 4 + if b == 0: + raise ZeroDivisionError("Division by zero is not allowed") + return a / b + From ec43791fbc3eeb84477208e2ce99322d439b0525 Mon Sep 17 00:00:00 2001 From: whyshetsss Date: Sat, 25 Oct 2025 22:50:40 +0300 Subject: [PATCH 41/41] Refactor calculator.py for improved readability --- calculator.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/calculator.py b/calculator.py index ce86537..e5cb839 100644 --- a/calculator.py +++ b/calculator.py @@ -6,18 +6,12 @@ import math -def add(a, b): - return a + b - -def subtract(a, b): - return a - b - -def multiply(a, b): - return a * b - +def add(a, b): return a + b +def subtract(a, b): return a - b +def multiply(a, b): return a * b def divide(a, b): if b == 0: - raise ZeroDivisionError("Division by zero is not allowed") + raise ZeroDivisionError("Division by zero") return a / b @@ -29,4 +23,3 @@ def divide(a, b): -