Перейти к содержанию

Урок 005: функции и границы ответственности

Цель

Разделить программу на небольшие именованные операции: получение данных, проверку, расчёт и показ результата.

Объявление и вызов

def calculate_subtotal(unit_price, quantity):
    return unit_price * quantity


subtotal = calculate_subtotal(125.50, 4)
print(f"Сумма: {subtotal:.2f} руб.")
  • def создаёт функцию.
  • unit_price и quantity — параметры.
  • 125.50 и 4 — аргументы конкретного вызова.
  • return возвращает результат вызывающему коду.

Функция не выполняется в момент объявления. Она выполняется при вызове calculate_subtotal(...).

return и print решают разные задачи

return передаёт значение другой части программы, поэтому его можно использовать в следующем расчёте или тесте. print показывает текст пользователю и обычно ничего полезного для вычисления не возвращает.

def calculate_discount(subtotal, discount_percent):
    return subtotal * discount_percent / 100


subtotal = 500
discount = calculate_discount(subtotal, 10)
total = subtotal - discount

Расчёт не печатает сообщения и не запрашивает ввод. Благодаря этому одну функцию легко проверить несколькими наборами аргументов.

Функция чтения числа

def read_nonnegative_float(prompt):
    while True:
        text = input(prompt).replace(",", ".")

        try:
            value = float(text)
        except ValueError:
            print("Ошибка: введите число")
            continue

        if value < 0:
            print("Ошибка: значение не может быть отрицательным")
            continue

        return value

return здесь одновременно возвращает корректное значение и завершает функцию. Пользовательский ввод и сообщение об ошибке находятся в одной функции, а математическая формула — в другой.

Полная минимальная программа

def calculate_total(unit_price, quantity, discount_percent):
    subtotal = unit_price * quantity
    discount = subtotal * discount_percent / 100
    total = subtotal - discount
    return subtotal, discount, total


subtotal, discount, total = calculate_total(100, 2, 10)

print(f"До скидки: {subtotal:.2f} руб.")
print(f"Скидка: {discount:.2f} руб.")
print(f"Итого: {total:.2f} руб.")

Функция возвращает три связанных результата. Для входа 100, 2, 10 ожидаются 200, 20, 180.

Признаки хорошей учебной функции

  • имя описывает действие;
  • параметры содержат все необходимые входные данные;
  • функция выполняет одну понятную ответственность;
  • расчёт не зависит от скрытого пользовательского ввода;
  • результат возвращается через return;
  • функцию можно вызвать повторно с другими аргументами.

Не разбивайте каждую строку в отдельную функцию. Граница полезна, когда часть программы имеет собственное правило, может быть переиспользована или отдельно проверена.

Упражнение

Создайте функции calculate_subtotal, calculate_discount и calculate_total. Проверьте их вручную на наборах (100, 2, 10), (100, 0, 10) и (99.90, 3, 0). Затем напишите отдельный блок, который печатает результаты.

Самопроверка

  • Почему расчётная функция не должна вызывать input?
  • Что произойдёт после выполнения return?
  • Чем параметр отличается от аргумента?
  • Как функция упрощает будущий автоматический тест?

← Предыдущий урок · Практика →