diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..77add9612 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: Tests Workflow + +on: + push : + branches: + - master + - release + pull_request: + branches: + - master + - release + - develop + +jobs: + test: + runs-on: ubuntu-latest + env: + FULL_NAME: "Сафарян Элен" + GROUP_NUMBER: "M3110" + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Print information + run: | + echo "DO: ${{ env. FULL_NAME }}" + echo "Номер группы: ${{ env.GROUP_NUMBER }}" + echo "Ник на Github: ${{ github.actor }}" + + - name: Set up Python 3.13 + uses: actions/setup-python@v4 + with: + python-version: '3.13' + + - name: Run unit tests + run: | + python -m unittest discover -s /home/runner/work/geometric_lib/geometric_lib/tests + + - name: Lint code with flake8 + run: | + pip install flake8 + flake8 --ignore=F401 . \ No newline at end of file diff --git a/__pycache__/calculate.cpython-313.pyc b/__pycache__/calculate.cpython-313.pyc new file mode 100644 index 000000000..42383443b Binary files /dev/null and b/__pycache__/calculate.cpython-313.pyc differ diff --git a/__pycache__/circle.cpython-313.pyc b/__pycache__/circle.cpython-313.pyc new file mode 100644 index 000000000..7ddedcb00 Binary files /dev/null and b/__pycache__/circle.cpython-313.pyc differ diff --git a/__pycache__/square.cpython-313.pyc b/__pycache__/square.cpython-313.pyc new file mode 100644 index 000000000..2445ed0d3 Binary files /dev/null and b/__pycache__/square.cpython-313.pyc differ diff --git a/__pycache__/triangle.cpython-313.pyc b/__pycache__/triangle.cpython-313.pyc new file mode 100644 index 000000000..f6f717390 Binary files /dev/null and b/__pycache__/triangle.cpython-313.pyc differ diff --git a/calculate.py b/calculate.py index 6dc22cf12..b3d494404 100644 --- a/calculate.py +++ b/calculate.py @@ -1,33 +1,64 @@ import circle import square +import triangle - -figs = ['circle', 'square'] +figs = ['circle', 'square', 'triangle'] funcs = ['perimeter', 'area'] -sizes = {} +sizes = { + 'circle-area': 1, + 'circle-perimeter': 1, + 'square-area': 1, + 'square-perimeter': 1, + 'triangle-area': 3, + 'triangle-perimeter': 3 +} + def calc(fig, func, size): - assert fig in figs - assert func in funcs - - result = eval(f'{fig}.{func}(*{size})') - print(f'{func} of {fig} is {result}') - -if __name__ == "__main__": - func = '' - fig = '' - size = list() - - while fig not in figs: - fig = input(f"Enter figure name, avaliable are {figs}:\n") - - while func not in funcs: - func = input(f"Enter function name, avaliable are {funcs}:\n") - - while len(size) != sizes.get(f"{func}-{fig}", 1): - size = list(map(int, input("Input figure sizes separated by space, 1 for circle and square\n").split(' '))) - - calc(fig, func, size) + # Проверка наличия передаваемого аргумента fig в figs + assert fig in figs + + # Проверка наличия передаваемого аргумента func в funcs + assert func in funcs + + # Проверка на количество аргументов + key = f'{fig}-{func}' + expected_args = sizes.get(key) + assert expected_args is not None + assert len(size) == expected_args + + # Проверка на неотрицательность аргументов + assert all(s >= 0 for s in size) + + # Проверка на существование треугольника + if fig == 'triangle': + a, b, c = size + assert a + b > c and a + c > b and b + c > a + + try: + # Вызов функции из соответствующего модуля + result = getattr(globals()[fig], func)(*size) + except ValueError as e: + print(f"Ошибка: {e}") # Обработка исключения ValueError + return None + + return result + + +if __name__ == "main": + func = '' + fig = '' + size = list() + + while fig not in figs: + fig = input(f"Enter figure name, avaliable are {figs}:\n") + while func not in funcs: + func = input(f"Enter function name, avaliable are {funcs}:\n") + while len(size) != sizes.get(f"{func}-{fig}", 1): + size = list(map(int, input( + "Input figure sizes separated by space, 1 for circle and square\n" + ).split(' '))) + calc(fig, func, size) diff --git a/circle.py b/circle.py index c3eb8647c..21e9a1779 100644 --- a/circle.py +++ b/circle.py @@ -7,4 +7,3 @@ def area(r): def perimeter(r): return 2 * math.pi * r - diff --git a/tests/__pycache__/test_calculate.cpython-313.pyc b/tests/__pycache__/test_calculate.cpython-313.pyc new file mode 100644 index 000000000..ed71f22c9 Binary files /dev/null and b/tests/__pycache__/test_calculate.cpython-313.pyc differ diff --git a/tests/__pycache__/test_circle.cpython-313.pyc b/tests/__pycache__/test_circle.cpython-313.pyc new file mode 100644 index 000000000..a7cc765f1 Binary files /dev/null and b/tests/__pycache__/test_circle.cpython-313.pyc differ diff --git a/tests/__pycache__/test_square.cpython-313.pyc b/tests/__pycache__/test_square.cpython-313.pyc new file mode 100644 index 000000000..f0a8f5989 Binary files /dev/null and b/tests/__pycache__/test_square.cpython-313.pyc differ diff --git a/tests/__pycache__/test_triangle.cpython-313.pyc b/tests/__pycache__/test_triangle.cpython-313.pyc new file mode 100644 index 000000000..438794ba4 Binary files /dev/null and b/tests/__pycache__/test_triangle.cpython-313.pyc differ diff --git a/tests/test_calculate.py b/tests/test_calculate.py new file mode 100644 index 000000000..fadcb8a52 --- /dev/null +++ b/tests/test_calculate.py @@ -0,0 +1,101 @@ +import unittest +from calculate import calc +import math + + +class TestCalculate(unittest.TestCase): + + def test_circle_area(self): + # Arrange (given) + fig = 'circle' + func = 'area' + size = [1] + + # Act (when) + result = calc(fig, func, size) + + # Assert (then) + self.assertAlmostEqual(result, math.pi, places=7) + + def test_square_area(self): + fig = 'square' + func = 'area' + size = [1] + + result = calc(fig, func, size) + + self.assertEqual(result, 1) + + def test_triangle_area(self): + fig = 'triangle' + func = 'area' + size = [3, 4, 5] + + result = calc(fig, func, size) + + self.assertEqual(result, 6) + + def test_circle_perimeter(self): + fig = 'circle' + func = 'perimeter' + size = [1] + + result = calc(fig, func, size) + + self.assertAlmostEqual(result, 2 * math.pi, places=7) + + def test_square_perimeter(self): + fig = 'square' + func = 'perimeter' + size = [1] + + result = calc(fig, func, size) + + self.assertEqual(result, 4) + + def test_triangle_perimeter(self): + fig = 'triangle' + func = 'perimeter' + size = [3, 4, 5] + + result = calc(fig, func, size) + + self.assertEqual(result, 12) + + def test_invalid_figure(self): + # Arrange (given) + fig = 'hexagon' + func = 'area' + size = [1] + + # Act & Assert (when & then) + with self.assertRaises(AssertionError): + calc(fig, func, size) + + def test_invalid_function(self): + fig = 'circle' + func = 'volume' + size = [1] + + with self.assertRaises(AssertionError): + calc(fig, func, size) + + def test_invalid_size_count(self): + fig = 'circle' + func = 'area' + size = [1, 2] + + with self.assertRaises(AssertionError): + calc(fig, func, size) + + def test_invalid_triangle(self): + fig = 'triangle' + func = 'area' + size = [1, 2, 10] + + with self.assertRaises(AssertionError): + calc(fig, func, size) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_circle.py b/tests/test_circle.py new file mode 100644 index 000000000..e4efd3379 --- /dev/null +++ b/tests/test_circle.py @@ -0,0 +1,50 @@ +import unittest +from circle import area, perimeter +import math + + +class TestCircle(unittest.TestCase): + + def test_area(self): + # Arrange (given) + radius = 1 + + # Act (when) + result = area(radius) + + # Assert (then) + self.assertAlmostEqual(result, math.pi, places=7) + + def test_area_zero(self): + # Arrange (given) + radius = 0 + + # Act (when) + result = area(radius) + + # Assert (then) + self.assertEqual(result, 0) + + def test_perimeter(self): + # Arrange (given) + radius = 1 + + # Act (when) + result = perimeter(radius) + + # Assert (then) + self.assertAlmostEqual(result, 2 * math.pi, places=7) + + def test_perimeter_zero(self): + # Arrange (given) + radius = 0 + + # Act (when) + result = perimeter(radius) + + # Assert (then) + self.assertEqual(result, 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_square.py b/tests/test_square.py new file mode 100644 index 000000000..32eb69f1c --- /dev/null +++ b/tests/test_square.py @@ -0,0 +1,49 @@ +import unittest +from square import area, perimeter + + +class TestSquare(unittest.TestCase): + + def test_area(self): + # Arrange (given) + side = 1 + + # Act (when) + result = area(side) + + # Assert (then) + self.assertEqual(result, 1) + + def test_area_zero(self): + # Arrange (given) + side = 0 + + # Act (when) + result = area(side) + + # Assert (then) + self.assertEqual(result, 0) + + def test_perimeter(self): + # Arrange (given) + side = 1 + + # Act (when) + result = perimeter(side) + + # Assert (then) + self.assertEqual(result, 4) + + def test_perimeter_zero(self): + # Arrange (given) + side = 0 + + # Act (when) + result = perimeter(side) + + # Assert (then) + self.assertEqual(result, 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_triangle.py b/tests/test_triangle.py new file mode 100644 index 000000000..b38a2eeda --- /dev/null +++ b/tests/test_triangle.py @@ -0,0 +1,29 @@ +import unittest +from triangle import area, perimeter + + +class TestTriangle(unittest.TestCase): + + def test_area(self): + # Arrange (given) + a, b, c = 3, 4, 5 + + # Act (when) + result = area(a, b, c) + + # Assert (then) + self.assertEqual(result, 6) + + def test_perimeter(self): + # Arrange (given) + a, b, c = 3, 4, 5 + + # Act (when) + result = perimeter(a, b, c) + + # Assert (then) + self.assertEqual(result, 12) + + +if __name__ == '__main__': + unittest.main() diff --git a/triangle.py b/triangle.py index fb41f60a5..0d6336828 100644 --- a/triangle.py +++ b/triangle.py @@ -1,5 +1,6 @@ def area(a, b, c): - return (a + b + c) / 2 + p = (a + b + c) / 2 + return (p * (p - a) * (p - b) * (p - c)) ** 0.5 def perimeter(a, b, c):