diff --git a/circle.py b/circle.py index c3eb8647c9..e856a32418 100644 --- a/circle.py +++ b/circle.py @@ -1,10 +1,64 @@ import math - def area(r): + """ + Вычисляет площадь круга по заданному радиусу. + + Параметры: + r (float): Радиус круга. + + Возвращаемое значение: + float: Площадь круга. + + Исключения: + ValueError: Если радиус не является числом (int или float) или радиус отрицательный. + + Пример: + >>> area(10) + 314.1592653589793 + >>> area(7.5) + 176.71458676442586 + >>> area("10") + ValueError: Ожидаются числовые значения для радиуса. + >>> area(-10) + ValueError: Радиус не может быть отрицательным. + """ + + if not isinstance(r, (int, float)): + raise ValueError("Ожидаются числовые значения для радиуса.") + if r < 0: + raise ValueError("Радиус не может быть отрицательным.") + return math.pi * r * r def perimeter(r): - return 2 * math.pi * r + """ + Вычисляет периметр (длину окружности) круга по заданному радиусу. + + Параметры: + r (float): Радиус круга. + + Возвращаемое значение: + float: Периметр круга. + + Исключения: + ValueError: Если радиус не является числом (int или float) или радиус отрицательный. + Пример: + >>> perimeter(10) + 62.83185307179586 + >>> perimeter(7.5) + 47.12388980384689 + >>> perimeter("10") + ValueError: Ожидаются числовые значения для радиуса. + >>> perimeter(-10) + ValueError: Радиус не может быть отрицательным. + """ + + if not isinstance(r, (int, float)): + raise ValueError("Ожидаются числовые значения для радиуса.") + if r < 0: + raise ValueError("Радиус не может быть отрицательным.") + + return 2 * math.pi * r diff --git a/docs/README.md b/docs/README.md index 63f8727939..35f3aba1f4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,287 @@ # Math formulas ## Area -- Circle: S = πR² -- Rectangle: S = ab -- Square: S = a² ++ [Circle](#модуль-circlepy): S = πR² ++ [Rectangle](#модуль-rectanglepy): S = ab ++ [Square](#модуль-squarepy): S = a² ++ [Triangle](#модуль-trianglepy): S = (a*h)/2 ## Perimeter -- Circle: P = 2πR -- Rectangle: P = 2a + 2b -- Square: P = 4a \ No newline at end of file +- [Circle](#модуль-circlepy): P = 2πR +- [Rectangle](#модуль-rectanglepy): P = 2a + 2b +- [Square](#модуль-squarepy): P = 4a +- [Triangle](#модуль-trianglepy): P = a + b + c + +## Общее описание решения + +Этот проект предоставляет функции для вычисления площади и периметра различных геометрических фигур: круга, квадрата, прямоугольника и треугольника. Каждая функция снабжена подробной документацией и примерами использования. + +## Описание функций с примерами вызова + +### Модуль `circle.py` + +#### Функция `area(r)` + +Вычисляет площадь круга по заданному радиусу. + +**Параметры:** +- `r` (float): Радиус круга. + +**Возвращает:** +- `float`: Площадь круга. + +**Пример использования:** + +```python +from circle import area + +result = area(5) +print(result) + +``` + +##### Вывод: 78.53981633974483 + + +#### Функция `perimeter(r)` + +Вычисляет периметр (длину окружности) круга по заданному радиусу. + +**Параметры:** +- `r` (float): Радиус круга. + +**Возвращает:** +- `float`: Периметр круга. + +**Пример использования:** + +```python +from circle import perimeter + +result = perimeter(5) +print(result) +``` + +##### Вывод: 31.41592653589793 + + +### Модуль `square.py` + +#### Функция `area(a)` + +Вычисляет площадь квадрата по заданной стороне. + +**Параметры:** +- `a` (float): сторона квадрата. + +**Возвращает:** +- `float`: Площадь квадрата. + +**Пример использования:** + +```python +from square import area + +result = area(5) +print(result) +``` +##### Вывод: 25 + +#### Функция `perimeter(a)` + +Вычисляет периметр квадрата по заданной стороне. + +**Параметры:** +- `a` (float): Сторона квадрата. + +**Возвращает:** +- `float`: Периметр квадрата. + +```python +from square import perimeter + +result = perimeter(5) +print(result) +``` +##### Вывод: 20 + + +### Модуль `rectangle.py` + +#### Функция `area(a, b)` + +Вычисляет площадь прямоугольника по его длине и ширине. + +**Параметры:** +- `a` (float): Длина прямоугольника. +- `b` (float): Ширина прямоугольника. + +**Возвращает:** +- `float`: Площадь прямоугльника. + +```python +from rectangle import area + +result = area(5, 6) +print(result) +``` +##### Вывод: 30 + +#### Функция `perimeter(r)` + +Вычисляет периметр прямоугольника по его длине и ширине. + +**Параметры:** +- `a` (float): Длина прямоугольника. +- `b` (float): Ширина прямоугольника. + +**Возвращает:** +- `float`: Периметр прямоугольника. + +**Пример использования:** + +```python +from rectangle import perimeter + +result = perimeter(5, 6) +print(result) +``` +##### Вывод: 22 + + +### Модуль `triangle.py` + +#### Функция `area(a, h)` + +Вычисляет площадь треугольника по основанию и высоте. + +**Параметры:** +- `a` (float): Основание треугольника. +- `h` (float): Высота треугольника. + +**Возвращает:** +- `float`: Площадь треугольника. + +**Пример использования:** + +```python +from triangle import area + +result = area(5, 2) +print(result) +``` +##### Вывод: 5 + +#### Функция `perimeter(r)` + +Вычисляет периметр площадь треугольника по 3 сторонам. + +**Параметры:** +- `a` (float): Первая сторона треугольника. +- `b` (float): Вторая сторона треугольника. +- `с` (float): Третья сторона треугольника. + +**Возвращает:** +- `float`: Периметр треугольника. + +**Пример использования:** + +```python +from triangle import perimeter + +result = perimeter(5, 4, 3) +print(result) +``` +##### Вывод: 12 + +## Тестирование + +В проекте добавлены автоматизированные тесты для проверки функциональности основных вычислений площади и периметра фигур, включая треугольник. Тесты используют фреймворк **unittest** и покрывают следующие аспекты: + +- Правильность вычислений площади и периметра. +- Проверка обработки некорректных данных (строки, отрицательные числа, нули). +- Проверка граничных значений. + +### Запуск тестов + +Для запуска тестов используйте следующую команду: +```bash +python -m unittest discover tests +``` + +### Реализация автоматического теста на примере triangle.py + +Тесты покрывают различные сценарии работы с треугольниками: + +#### 1. Корректные данные: +- Проверка вычисления площади с положительными значениями основания и высоты. +- Проверка вычисления периметра с корректными длинами сторон. + +#### 2. Некорректные данные: +- Проверка на строки вместо чисел. +- Проверка на отрицательные значения и нули. + +#### 3. Граничные значения: +- Проверка невалидных длин сторон для периметра (например, длина одной стороны больше суммы двух других). + +#### Пример тестов для треугольника + +```python +import unittest +from geometric_lib.triangle import area, perimeter + +class TestTriangle(unittest.TestCase): + + # Тестируем правильность вычисления площади треугольника + def test_area_valid(self): + self.assertEqual(area(10, 5), 25) # Площадь = 10 * 5 / 2 = 25 + self.assertEqual(area(7.5, 3.2), 12.0) # Площадь = 7.5 * 3.2 / 2 = 12.0 + + # Тестируем корректность периметра + def test_perimeter_valid(self): + self.assertEqual(perimeter(3, 4, 5), 12) # Периметр = 3 + 4 + 5 = 12 + self.assertEqual(perimeter(10.5, 7.5, 6), 24.0) # Периметр = 10.5 + 7.5 + 6 = 24.0 + + # Тестируем, когда передаются некорректные данные для площади + def test_area_invalid(self): + with self.assertRaises(ValueError): + area("10", 5) # Ожидается ошибка, строка вместо числа + with self.assertRaises(ValueError): + area(10, "5") # Ожидается ошибка, строка вместо числа + with self.assertRaises(ValueError): + area("10", "5") # Ожидается ошибка, строки вместо чисел + + # Тестируем, когда передаются некорректные данные для периметра + def test_perimeter_invalid(self): + with self.assertRaises(ValueError): + perimeter("3", 4, 5) # Ожидается ошибка, строка вместо числа + with self.assertRaises(ValueError): + perimeter(3, "4", 5) # Ожидается ошибка, строка вместо числа + with self.assertRaises(ValueError): + perimeter(3, 4, "5") # Ожидается ошибка, строка вместо числа + with self.assertRaises(ValueError): + perimeter(-3, 4, 5) # Ожидается ошибка, отрицательная длина стороны + + # Тестируем, когда одна из сторон треугольника не удовлетворяет неравенству треугольника + def test_perimeter_invalid_triangle(self): + with self.assertRaises(ValueError): + perimeter(1, 2, 10) # Сумма двух сторон 1 + 2 должна быть больше 10 + with self.assertRaises(ValueError): + perimeter(5, 3, 1) # Сумма двух сторон 5 + 3 должна быть больше 1 +``` +#### Ввод невалидных данных + +```python +from triangle import perimeter + +result = perimeter("5", 4, 3) +print(result) +``` +Вывод : ValueError: Ожидаются числовые значения для сторон треугольника. + +# История изменений + +- `ba7d4fd` - Исправлено вычисление периметра в rectangle.py +- `b52d087` - Добавлены вычисления для треугольника +- `730dc10` - Добавлены вычисления для прямоугольника +- `d078c8d` - Добавлена документация в проект +- `8ba9aeb` - Добавлены функции для вычисления площади и периметра квадрата и круга. \ No newline at end of file diff --git a/docs/cd b/docs/cd new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rectangle.py b/rectangle.py new file mode 100644 index 0000000000..c201cc9373 --- /dev/null +++ b/rectangle.py @@ -0,0 +1,70 @@ +def area(a, b): + """ + Вычисляет площадь прямоугольника. + + Параметры: + a (float): Длина прямоугольника. + b (float): Ширина прямоугольника. + + Возвращаемое значение: + float: Площадь прямоугольника. + + Исключения: + ValueError: Если хотя бы один из параметров не является числом или если параметры не положительные. + + Пример: + >>> area(10, 5) + 50 + >>> area(7.5, 3.2) + 24.0 + >>> area("10", 5) + ValueError: Ожидаются числовые значения для длины и ширины. + >>> area(0, 5) + ValueError: Длина и ширина не могут быть равны нулю или отрицательными. + >>> area(-10, 5) + ValueError: Длина и ширина не могут быть равны нулю или отрицательными. + """ + + if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): + raise ValueError("Ожидаются числовые значения для длины и ширины.") + + if a <= 0 or b <= 0: + raise ValueError("Длина и ширина не могут быть равны нулю или отрицательными.") + + return a * b + + +def perimeter(a, b): + """ + Вычисляет периметр прямоугольника. + + Параметры: + a (float): Длина прямоугольника. + b (float): Ширина прямоугольника. + + Возвращаемое значение: + float: Периметр прямоугольника. + + Исключения: + ValueError: Если хотя бы один из параметров не является числом или если параметры не положительные. + + Пример: + >>> perimeter(10, 5) + 30 + >>> perimeter(7.5, 3.2) + 21.4 + >>> perimeter("10", 5) + ValueError: Ожидаются числовые значения для длины и ширины. + >>> perimeter(0, 5) + ValueError: Длина и ширина не могут быть равны нулю или отрицательными. + >>> perimeter(-10, 5) + ValueError: Длина и ширина не могут быть равны нулю или отрицательными. + """ + + if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): + raise ValueError("Ожидаются числовые значения для длины и ширины.") + + if a <= 0 or b <= 0: + raise ValueError("Длина и ширина не могут быть равны нулю или отрицательными.") + + return 2 * (a + b) \ No newline at end of file diff --git a/square.py b/square.py index 0f98724205..a5584a2d12 100644 --- a/square.py +++ b/square.py @@ -1,7 +1,62 @@ - def area(a): + """ + Вычисляет площадь квадрата. + + Параметры: + a (float): Длина стороны квадрата. + + Возвращаемое значение: + float: Площадь квадрата. + + Исключения: + ValueError: Если длина стороны не является числом (int или float), длина стороны отрицательная или равна нулю. + + Пример: + >>> area(10) + 100 + >>> area(7.5) + 56.25 + >>> area("10") + ValueError: Ожидаются числовые значения для длины стороны. + >>> area(-10) + ValueError: Длина стороны не может быть отрицательной. + >>> area(0) + ValueError: Длина стороны не может быть равна нулю. + """ + if not isinstance(a, (int, float)): + raise ValueError("Ожидаются числовые значения для длины стороны.") + if a <= 0: + raise ValueError("Длина стороны не может быть равна нулю или отрицательной.") return a * a def perimeter(a): - return 4 * a + """ + Вычисляет периметр квадрата. + + Параметры: + a (float): Длина стороны квадрата. + + Возвращаемое значение: + float: Периметр квадрата. + + Исключения: + ValueError: Если длина стороны не является числом (int или float), длина стороны отрицательная или равна нулю. + + Пример: + >>> perimeter(10) + 40 + >>> perimeter(7.5) + 30 + >>> perimeter("10") + ValueError: Ожидаются числовые значения для длины стороны. + >>> perimeter(-10) + ValueError: Длина стороны не может быть отрицательной. + >>> perimeter(0) + ValueError: Длина стороны не может быть равна нулю. + """ + if not isinstance(a, (int, float)): + raise ValueError("Ожидаются числовые значения для длины стороны.") + if a <= 0: + raise ValueError("Длина стороны не может быть равна нулю или отрицательной.") + return 4 * a \ No newline at end of file diff --git a/test_circle.py b/test_circle.py new file mode 100644 index 0000000000..06b5ec9fbf --- /dev/null +++ b/test_circle.py @@ -0,0 +1,44 @@ +import unittest +import math +from circle import area, perimeter + +class TestCircleFunctions(unittest.TestCase): + + # Тест для функции area + def test_area_valid(self): + # Проверим правильность вычислений для площади круга + self.assertAlmostEqual(area(10), math.pi * 10 * 10) # Площадь круга с радиусом 10 + self.assertAlmostEqual(area(7.5), math.pi * 7.5 * 7.5) # Площадь круга с радиусом 7.5 + + def test_area_invalid(self): + # Тестируем случай, когда радиус не является числом + with self.assertRaises(ValueError): + area("10") # Передаем строку вместо числа + with self.assertRaises(ValueError): + area([10]) # Передаем список вместо числа + with self.assertRaises(ValueError): + area(None) # Передаем None вместо числа + # Тестируем случай с отрицательным значением радиуса + with self.assertRaises(ValueError): + area(-10) # Передаем отрицательное значение + + # Тест для функции perimeter + def test_perimeter_valid(self): + # Проверим правильность вычислений для периметра круга + self.assertAlmostEqual(perimeter(10), 2 * math.pi * 10) # Периметр круга с радиусом 10 + self.assertAlmostEqual(perimeter(7.5), 2 * math.pi * 7.5) # Периметр круга с радиусом 7.5 + + def test_perimeter_invalid(self): + # Тестируем случай, когда радиус не является числом + with self.assertRaises(ValueError): + perimeter("10") # Передаем строку вместо числа + with self.assertRaises(ValueError): + perimeter([10]) # Передаем список вместо числа + with self.assertRaises(ValueError): + perimeter(None) # Передаем None вместо числа + # Тестируем случай с отрицательным значением радиуса + with self.assertRaises(ValueError): + perimeter(-10) # Передаем отрицательное значение + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/test_rectangle.py b/test_rectangle.py new file mode 100644 index 0000000000..24f7920334 --- /dev/null +++ b/test_rectangle.py @@ -0,0 +1,39 @@ +import unittest +from rectangle import area, perimeter + +class TestRectangleFunctions(unittest.TestCase): + + # Тестируем корректность вычисления площади прямоугольника + def test_area_valid(self): + self.assertEqual(area(10, 5), 50) # Площадь прямоугольника с длиной 10 и шириной 5 + self.assertEqual(area(7.5, 3.2), 24.0) # Площадь прямоугольника с такими размерами + + # Тестируем некорректные входные значения для площади + def test_area_invalid(self): + with self.assertRaises(ValueError): + area("10", 5) # Строка вместо числа + + with self.assertRaises(ValueError): + area(0, 5) # Нулевая длина + + with self.assertRaises(ValueError): + area(-10, 5) # Отрицательная длина + + # Тестируем корректность вычисления периметра прямоугольника + def test_perimeter_valid(self): + self.assertEqual(perimeter(10, 5), 30) # Периметр прямоугольника с длиной 10 и шириной 5 + self.assertEqual(perimeter(7.5, 3.2), 21.4) # Периметр прямоугольника с такими размерами + + # Тестируем некорректные входные значения для периметра + def test_perimeter_invalid(self): + with self.assertRaises(ValueError): + perimeter("10", 5) # Строка вместо числа + + with self.assertRaises(ValueError): + perimeter(0, 5) # Нулевая длина + + with self.assertRaises(ValueError): + perimeter(-10, 5) # Отрицательная длина + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/test_square.py b/test_square.py new file mode 100644 index 0000000000..436e64058d --- /dev/null +++ b/test_square.py @@ -0,0 +1,65 @@ +import unittest +from square import area, perimeter + +class TestSquareFunctions(unittest.TestCase): + + # Тестируем корректность вычисления площади квадрата + def test_area_valid(self): + # Проверяем стандартные значения + self.assertEqual(area(10), 100) # Площадь квадрата со стороной 10 + self.assertEqual(area(7.5), 56.25) # Площадь квадрата со стороной 7.5 + self.assertEqual(area(1), 1) # Площадь квадрата со стороной 1 + + # Тестируем некорректные входные значения для площади + def test_area_invalid(self): + # Тестируем, когда передается строка + with self.assertRaises(ValueError): + area("10") # Передаем строку вместо числа + + # Тестируем, когда передается список + with self.assertRaises(ValueError): + area([10]) # Передаем список вместо числа + + # Тестируем, когда передается None + with self.assertRaises(ValueError): + area(None) # Передаем None вместо числа + + # Тестируем, когда передается отрицательное значение + with self.assertRaises(ValueError): + area(-10) # Длина стороны не может быть отрицательной + + # Тестируем, когда передается нулевая длина стороны + with self.assertRaises(ValueError): + area(0) # Длина стороны не может быть равна нулю + + # Тестируем корректность вычисления периметра квадрата + def test_perimeter_valid(self): + # Проверяем стандартные значения + self.assertEqual(perimeter(10), 40) # Периметр квадрата со стороной 10 + self.assertEqual(perimeter(7.5), 30) # Периметр квадрата со стороной 7.5 + self.assertEqual(perimeter(1), 4) # Периметр квадрата со стороной 1 + + # Тестируем некорректные входные значения для периметра + def test_perimeter_invalid(self): + # Тестируем, когда передается строка + with self.assertRaises(ValueError): + perimeter("10") # Передаем строку вместо числа + + # Тестируем, когда передается список + with self.assertRaises(ValueError): + perimeter([10]) # Передаем список вместо числа + + # Тестируем, когда передается None + with self.assertRaises(ValueError): + perimeter(None) # Передаем None вместо числа + + # Тестируем, когда передается отрицательное значение + with self.assertRaises(ValueError): + perimeter(-10) # Длина стороны не может быть отрицательной + + # Тестируем, когда передается нулевая длина стороны + with self.assertRaises(ValueError): + perimeter(0) # Длина стороны не может быть равна нулю + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/test_triangle.py b/test_triangle.py new file mode 100644 index 0000000000..b0e061e359 --- /dev/null +++ b/test_triangle.py @@ -0,0 +1,55 @@ +import unittest + +from triangle import area, perimeter + +class TestTriangleFunctions(unittest.TestCase): + + # Тестируем корректность вычисления площади треугольника + def test_area_valid(self): + # Проверяем стандартные значения + self.assertEqual(area(10, 5), 25.0) # Площадь треугольника с основанием 10 и высотой 5 + self.assertEqual(area(7.5, 4), 15.0) # Площадь треугольника с основанием 7.5 и высотой 4 + + # Тестируем некорректные входные значения для площади + def test_area_invalid(self): + # Тестируем, когда передается строка вместо числа + with self.assertRaises(ValueError): + area("10", 5) # Передаем строку вместо числа + + with self.assertRaises(ValueError): + area(10, "5") # Передаем строку вместо числа + + with self.assertRaises(ValueError): + area("10", "5") # Передаем строку вместо числа + + # Тестируем, когда передается отрицательное значение + with self.assertRaises(ValueError): + area(10, -5) # Основание и высота должны быть положительными числами + + # Тестируем, когда передается нулевая высота + with self.assertRaises(ValueError): + area(10, 0) # Основание и высота не могут быть равны нулю + + # Тестируем корректность вычисления периметра треугольника + def test_perimeter_valid(self): + # Проверяем стандартные значения + self.assertEqual(perimeter(3, 4, 5), 12) # Периметр прямоугольного треугольника + self.assertEqual(perimeter(10, 5, 7), 22) # Периметр треугольника с такими сторонами + + # Тестируем некорректные входные значения для периметра + def test_perimeter_invalid(self): + # Тестируем, когда передается строка вместо числа + with self.assertRaises(ValueError): + perimeter(3, 4, "5") # Передаем строку вместо числа + + # Тестируем, когда одна из сторон отрицательная + with self.assertRaises(ValueError): + perimeter(-3, 4, 5) # Стороны должны быть положительными числами + + # Тестируем, когда стороны не могут составить треугольник + with self.assertRaises(ValueError): + perimeter(1, 2, 3) # Стороны не могут составлять треугольник + +if __name__ == '__main__': + unittest.main() + diff --git a/triangle.py b/triangle.py new file mode 100644 index 0000000000..ea48c38b94 --- /dev/null +++ b/triangle.py @@ -0,0 +1,65 @@ +def area(a, h): + """ + Вычисляет площадь треугольника по основанию и высоте. + + Параметры: + a (float): Основание треугольника. + h (float): Высота треугольника. + + Возвращаемое значение: + float: Площадь треугольника. + + Исключения: + ValueError: Если основание или высота не являются числами, или если они меньше или равны нулю. + + Пример: + >>> area(10, 5) + 25.0 + >>> area(7.5, 4) + 15.0 + >>> area("10", 5) + ValueError: Ожидаются числовые значения для основания и высоты. + >>> area(10, -5) + ValueError: Основание и высота должны быть положительными числами. + >>> area(0, 5) + ValueError: Основание и высота не могут быть равны нулю. + """ + if not isinstance(a, (int, float)) or not isinstance(h, (int, float)): + raise ValueError("Ожидаются числовые значения для основания и высоты.") + if a <= 0 or h <= 0: + raise ValueError("Основание и высота должны быть положительными числами.") + return a * h / 2 + + +def perimeter(a, b, c): + """ + Вычисляет периметр треугольника по его сторонам. + + Параметры: + a (float): Первая сторона треугольника. + b (float): Вторая сторона треугольника. + c (float): Третья сторона треугольника. + + Возвращаемое значение: + float: Периметр треугольника. + + Исключения: + ValueError: Если одна из сторон не является числом, или если стороны не составляют правильный треугольник (не выполняется неравенство треугольника). + + Пример: + >>> perimeter(3, 4, 5) + 12 + >>> perimeter(10, 5, 7) + 22 + >>> perimeter(3, 4, "5") + ValueError: Ожидаются числовые значения для сторон треугольника. + >>> perimeter(1, 2, 3) + ValueError: Стороны не могут составлять треугольник (неравенство треугольника). + """ + if not all(isinstance(side, (int, float)) for side in [a, b, c]): + raise ValueError("Ожидаются числовые значения для сторон треугольника.") + if a <= 0 or b <= 0 or c <= 0: + raise ValueError("Стороны треугольника должны быть положительными числами.") + if a + b <= c or a + c <= b or b + c <= a: + raise ValueError("Стороны не могут составлять треугольник (неравенство треугольника).") + return a + b + c