В одной из первых лекций вы уже решали задачу о поиске корней уравнения. Давайте модернизируем её.
Напишите функцию find_roots
, принимающую три параметра: коэффициенты уравнения и возвращающую его корни в виде кортежа из двух значений.
Так же создайте два собственных исключения NoSolutionsError
и InfiniteSolutionsError
, которые будут вызваны в случае отсутствия и бесконечного количества решений уравнения соответственно.
Если переданные коэффициенты не являются рациональными числами, вызовите исключение TypeError
.
Примечание
В решении не должно быть вызовов требуемых функций.
Пример
Ввод
print(find_roots(0, 0, 1))
Вывод
Вызвано исключение NoSolutionsError
Ввод
print(find_roots(1, 2, 1))
Вывод
(-1.0, -1.0)
Решение
Чуть модифицированная версия задачи Q. Корень зла.
Нужно добавить вызов исключений, вместо вывода соответствующих сообщений и удваивать корень, если он оказался один.
Не забываем объявить класс исключений. Их можно сделать пустыми (pass).
Организовать проверку можно несколькими способами – в решении для этого используется функция type(). Можно воспользоваться isinstance(), но так будет чуть более громоздко.
В остальном это практически точная копия решения первой задачи.
Несмотря на то, что его можно слегка оптимизировать и “слить” условия, приводящие к одинаковому результату в одно, что сделает код короче, я, в угоду читабельности, и сохранения академичности решения оставляю его ровно в том же шаблоне, что был выбран для первого решения.
Посмотреть код
Решение
class InfiniteSolutionsError(Exception):
pass
class NoSolutionsError(Exception):
pass
def find_roots(a, b, c):
roots = ()
if not all(type(num) in (int, float) for num in (a, b, c)):
raise TypeError
if a == b == c == 0:
raise InfiniteSolutionsError('Infinite solutions')
elif a == 0 and b != 0 and c != 0:
roots = (-(c / b), -(c / b))
elif a == b == 0:
raise NoSolutionsError('No solution')
elif a == c == 0:
roots = (0, 0)
else:
disc = (b ** 2) - (4 * a * c)
if disc == 0:
roots = ((-b) / (2 * a), (-b) / (2 * a))
elif disc > 0:
x1 = (-b - (disc ** 0.5)) / (2 * a)
x2 = (-b + (disc ** 0.5)) / (2 * a)
roots = tuple(sorted([x1, x2]))
else:
raise NoSolutionsError('No solution')
return roots
Сергей, здравствуйте.
Скажите, пожалуйста, обязательна ли запись “roots = ()” в 11-й строке?
Не могу пока осознать ее функциональность…
Или дело не в функциональности, а в наглядности (потому что потом в условиях мы используем эту переменную и итогово возвращаем ее значение)?
Это привычка из других языков программирования. В большинстве языков переменная доступна только в том блоке, где объявлена. Поэтому я иногда (скорее часто) по привычке объявляю переменные явно.
Поняла, спасибо большое за пояснения.