Подпрограммы в Python: Учимся писать свой код как профи
Привет! Сегодня мы научимся разбивать программы на маленькие кусочки — подпрограммы. Это как собирать LEGO: у тебя есть готовые детали, и ты просто соединяешь их по-разному. Готов стать мастером кода? Поехали! 🚀
Зачем это вообще нужно?
Представь: ты пишешь программу для крутого бота в Telegram или делаешь игру. Код растёт, становится огромным, запутанным — как наушники в кармане. Найти ошибку? Невозможно. Добавить новую фишку? Кошмар.
💡 Решение
Разбить программу на маленькие кусочки — подпрограммы. Это как собирать конструктор: у тебя есть готовые детали, и ты просто соединяешь их по-разному.
📋 В Python есть два типа подпрограмм
- Процедуры — делают какие-то действия (например, рисуют что-то на экране)
- Функции — делают действия И возвращают результат (например, вычисляют что-то)
1️⃣ Процедуры — действуй!
Процедура — как кнопка: нажал и получил результат
💡 Что это такое?
Процедура — это мини-программа внутри твоей программы. Она выполняет какие-то команды, когда ты её вызываешь по имени.
Думай о ней как о кнопке на пульте: нажал — и телевизор включился. Ты не думаешь, как именно это происходит, тебе важен результат.
📝 Как написать процедуру?
Описание процедуры имеет вид:
def имя_процедуры():
# здесь твои команды
print("Что-то делаю!")
Обрати внимание:
- Начинается со слова
def(от английского define — определить) - После имени обязательно
()и: - Все команды внутри пишутся с отступом (обычно 4 пробела или Tab)
🎯 Пример 1: Строки из единичек
Задача: Вывести 4 строки, каждая из которых состоит из семи единиц: 1111111
❌ Плохой вариант — копипаста
print(1111111)
print(1111111)
print(1111111)
print(1111111)
✅ Крутой вариант — с процедурой
def digit():
print(1111111)
print('Четыре строки из семи единиц')
digit()
digit()
digit()
digit()
💡 Почему это круто?
Мы написали команду print(1111111) всего один раз, а вызвали её четыре раза. Если захочешь изменить на восемь единиц — поменяешь в одном месте, а не в четырёх!
📌 Процедуры с параметрами
А что если нам нужно выводить не 7 единиц, а разное количество? Тогда добавим параметр — переменную, которая влияет на работу процедуры.
🔧 Процедура с параметром
def digit(n):
print('1' * n)
Теперь можем вызывать так:
digit(7) # выведет: 1111111
digit(10) # выведет: 1111111111
digit(3) # выведет: 111
💡 Объяснение
Параметр n — это как регулятор громкости на колонке: крутишь влево-вправо, получаешь разную громкость. Здесь меняешь число — получаешь разную длину строки.
📝 Улучшенная версия с двумя параметрами
Давай сделаем так, чтобы можно было изменять не только длину строки, но и цифры, из которых эта строка строится:
def digit(d, n):
print(d * n)
Примеры вызова:
digit('1', 7) # выведет: 1111111
digit('5', 3) # выведет: 555
digit('*', 10) # выведет: **********
🎯 Пример 2: Алгоритм Евклида (НОД)
Допустим, тебе нужно найти НОД (наибольший общий делитель) двух чисел. Это нужно, например, для сокращения дробей в калькуляторе.
Алгоритм Евклида: вычитаем меньшее из большего, пока не получим ответ
📜 Алгоритм Евклида
Один из древнейших алгоритмов в мире (придуман ещё в Древней Греции!):
def nod(a, b):
global x
while a != b:
if a > b:
a = a - b
else:
b = b - a
x = a
Как это работает?
- Берём два числа
aиb - Вычитаем меньшее из большего
- Повторяем, пока числа не станут равными
- Это и есть НОД!
🔧 Полная программа с использованием процедуры
# Подпрограмма
def nod(a, b):
global x
while a != b:
if a > b:
a = a - b
else:
b = b - a
x = a
# Основная программа
k = int(input('k='))
x = int(input())
for i in range(1, k):
y = int(input())
nod(x, y)
print('НОД=', x)
🌍 Глобальные и локальные переменные
💡 Важно понимать!
Переменные d и n внутри процедуры — локальные. Они введены и используются внутри процедуры digit. Обращаться к ним вне этой процедуры нельзя.
Как только работа процедуры будет закончена, все локальные переменные удаляются из памяти (как персонаж в игре, когда уровень закончился).
🌐 Глобальные переменные
В тех случаях, когда значение переменной, полученное в подпрограмме, должно быть использовано в основной программе, эту переменную следует объявить как глобальную.
Заметил global x в коде алгоритма Евклида? Это глобальная переменная — она живёт во всей программе, а не только внутри процедуры.
🎯 Пример 3: Простые множители числа
Рассмотрим программу, которая выводит все простые множители произвольного натурального числа a > 1 (если число простое, то выводится оно само).
Программа находит все простые множители числа
💻 Код программы
# Подпрограмма
def ppd(n):
global d
d = 2
while n % d > 0:
d = d + 1
print(d)
# Основная программа
a = int(input('a='))
while a > 1:
ppd(a)
a = a / d
Как работает программа:
- Процедура
ppd(n)находит наименьший делитель числа n - В основной программе мы делим исходное число на найденный делитель
- Повторяем, пока число не станет равным 1
📊 Пример работы
Протестируй программу на числах 121, 135 и 847. В результате её выполнения ты должны получить соответствующие наборы чисел, записанных в столбик:
- 121: 11, 11
- 135: 3, 3, 3, 5
- 847: 7, 11, 11
2️⃣ Функции — вычисляй и возвращай!
Функция принимает данные, обрабатывает их и возвращает результат
💡 Чем функция отличается от процедуры?
Функция — подпрограмма, имеющая единственный результат, записываемый в ячейку памяти.
В отличие от процедуры, функция не только выполняет какие-то команды, но и возвращает результат в виде числа, символьной строки или др.
📝 Описание функции имеет вид
def имя_функции():
# операторы
return результат
Ключевое слово return — это как кнопка "отправить" в чате. Функция "отправляет" тебе ответ.
💭 Представь калькулятор
Ты вводишь 5 + 3, жмёшь =, и получаешь 8. Это функция! Она приняла два числа, вычислила сумму и вернула результат.
🎯 Пример 4: Функция max()
В Python есть встроенная функция max(), которая находит максимум из двух чисел. Давай сделаем свою!
💻 Код функции
def max(a, b):
if a > b:
m = a
else:
m = b
return m
Теперь можем использовать её:
print(max(6, 8)) # выведет: 8
x = max(6, 8) # x станет равен 8
✨ Магия функций!
Результат функции можно:
- Сразу вывести:
print(max(6, 8)) - Сохранить в переменную:
x = max(6, 8) - Передать в другую функцию!
🎯 Пример 5: Максимум из четырёх чисел
А что если нам нужно найти максимум не из двух, а из четырёх чисел?
💡 Крутая идея: использовать функцию несколько раз!
def max(a, b):
if a > b:
m = a
else:
m = b
return m
a, b, c, d = map(int, input().split())
f = max(max(a, b), max(c, d))
print('f=', f)
Разбор:
max(a, b)— находим максимум из первых двух чиселmax(c, d)— находим максимум из вторых двухmax(результат1, результат2)— находим максимум из максимумов!
Это как турнир: сначала четвертьфиналы (попарно), потом финал.
🎯 Усложнённая задача
Измени программу так, чтобы с её помощью можно было найти:
- а) максимальное из чисел a, b, c
- б) максимальное из чисел b, c, a
- в) минимальное из четырёх чисел
- г) разность максимального и минимального из четырёх чисел
🐰 Пример 6: Задача про кроликов (Последовательность Фибоначчи)
В январе Саше подарили пару новорождённых кроликов. Через два месяца они дали первый приплод — новую пару кроликов. А затем давали приплод по паре кроликов каждый месяц. Каждая новая пара также через два месяца даёт первый приплод (пару кроликов), а затем по паре кроликов каждый месяц. Сколько пар кроликов будет у Саши в декабре?
Рекурсия: функция вызывает сама себя, создавая "дерево" вычислений
📊 Анализ задачи
Обозначим через f(n) количество пар кроликов в месяце с номером n. По условию задачи, f(1) = 1, f(2) = 1, f(3) = 2.
| Месяц | Январь | Февраль | Март | Апрель | Май | Июнь |
|---|---|---|---|---|---|---|
| Пар | 1 | 1 | 2 | 3 | 5 | 8 |
Из двух пар, имеющихся в марте, дать приплод в апреле сможет только одна: f(4) = 3. Из пар, имеющихся в апреле, дать приплод в мае смогут только те пары, родившиеся в марте и ранее: f(5) = f(4) + f(3) = 3 + 2 = 5.
В общем случае:
f(n) = f(n - 1) + f(n - 2), n ⩾ 3
💡 Последовательность Фибоначчи
Числа 1, 1, 2, 3, 5, 8... образуют так называемую последовательность Фибоначчи, названную в честь итальянского математика, впервые решившего соответствующую задачу ещё в начале XIII века.
💻 Рекурсивная функция
Оформим в виде функции вычисление члена последовательности Фибоначчи:
def f(n):
if n == 1 or n == 2:
rez = 1
else:
rez = f(n - 1) + f(n - 2)
return rez
Это рекурсивная функция — она вызывает сама себя! Как зеркала, отражающие друг друга.
Рекурсивная функция — это функция, которая вызывает сама себя, напрямую или через другие процедуры и функции.
📋 Полная программа
Напиши программу, вычисляющую и выводящую 12 первых членов последовательности Фибоначчи.
def f(n):
if n == 1 or n == 2:
rez = 1
else:
rez = f(n - 1) + f(n - 2)
return rez
# Выводим первые 12 членов
for i in range(1, 13):
print(f(i))
📚 Самое главное
Давайте подведём итоги нашего путешествия в мир подпрограмм:
def
return
🤔 Проверь себя
Проверьте, как хорошо вы усвоили материал!
1. Для чего используются подпрограммы?
Подпрограммы используются для разбиения большой программы на логические части, которые можно использовать многократно. Это делает код более структурированным, понятным и удобным для отладки.
2. Напишите процедуру с параметрами n (целое число) и a (символ), выводящую на экран n строк, каждая из которых содержит n символов a.
Подсказка: используй вложенные циклы или умножение строки на число
def print_square(n, a):
for i in range(n):
print(a * n)
3. Напишите процедуру с параметрами w (ширина), h (высота), a (символ), выводящую на экран «прямоугольник» из символов a, ширина которого равна w, а высота — h.
def print_rectangle(w, h, a):
for i in range(h):
print(a * w)
4. В чём основное различие процедур и функций?
Процедура выполняет действия, но не возвращает результат (или возвращает результат через глобальные переменные).
Функция не только выполняет действия, но и возвращает единственный результат через оператор return, который можно использовать в выражениях.
5. Напишите функцию kdn(), которая вычисляет количество цифр вводимого целого числа.
def kdn(n):
count = 0
n = abs(n) # берём модуль числа
if n == 0:
return 1
while n > 0:
count += 1
n = n // 10
return count
6. Напишите функцию kbah(), которая вычисляет количество цифр в двоичной записи вводимого десятичного числа.
def kbah(n):
if n == 0:
return 1
count = 0
while n > 0:
count += 1
n = n // 2
return count
7. Как известно, наименьшее общее кратное (НОК) и наибольший общий делитель двух чисел связаны соотношением: НОК(a, b) = (a · b) / НОД(a, b).
Напишите программу вычисления НОК следующих четырёх чисел: 36, 54, 18 и 15. Используйте процедуру вычисления НОД двух чисел.
def nod(a, b):
while a != b:
if a > b:
a = a - b
else:
b = b - a
return a
def nok(a, b):
return (a * b) // nod(a, b)
# Вычисляем НОК четырёх чисел
result = nok(nok(nok(36, 54), 18), 15)
print('НОК =', result)
8. Напишите программу обмена значений переменных a, b, c в порядке возрастания, т. е. так, чтобы a < b < c. Используйте функцию swap().
Исходные данные вводятся с клавиатуры.
Смотри таблицу с примерами входных и выходных данных в учебнике.
9. Напишите программу вычисления выражения s = 1! + 2! + 3! + ... + n!
Здесь n! — факториал числа n. n! = 1 · 2 · ... · (n - 1) · n. Используйте функцию вычисления факториала.
def factorial(n):
if n == 0 or n == 1:
return 1
result = 1
for i in range(2, n + 1):
result *= i
return result
n = int(input('Введите n: '))
s = 0
for i in range(1, n + 1):
s += factorial(i)
print('s =', s)
10. Напишите программу вычисления выражения s = x³ + x⁵ + xⁿ
Где x и n вводятся с клавиатуры. Используйте подпрограмму вычисления степени.
def power(base, exp):
result = 1
for i in range(exp):
result *= base
return result
x = int(input('Введите x: '))
n = int(input('Введите n: '))
s = power(x, 3) + power(x, 5) + power(x, n)
print('s =', s)
11. Напишите функцию, вычисляющую длину отрезка по координатам его концов. Напишите программу, вычисляющую периметр треугольника по координатам его вершин с помощью этой функции.
import math
def distance(x1, y1, x2, y2):
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
# Ввод координат вершин треугольника
x1, y1 = map(float, input('Координаты A (x y): ').split())
x2, y2 = map(float, input('Координаты B (x y): ').split())
x3, y3 = map(float, input('Координаты C (x y): ').split())
# Вычисление периметра
perimeter = distance(x1, y1, x2, y2) + distance(x2, y2, x3, y3) + distance(x3, y3, x1, y1)
print('Периметр =', perimeter)
12. Напишите функцию, вычисляющую площадь треугольника по координатам его вершин. Напишите программу вычисления площади четырёхугольника по координатам его вершин с помощью этой функции.
Подсказка: используй формулу площади через координаты или раздели четырёхугольник на два треугольника
def triangle_area(x1, y1, x2, y2, x3, y3):
# Формула площади треугольника через координаты
return abs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) / 2
# Площадь четырёхугольника = сумма площадей двух треугольников
x1, y1 = map(float, input('A (x y): ').split())
x2, y2 = map(float, input('B (x y): ').split())
x3, y3 = map(float, input('C (x y): ').split())
x4, y4 = map(float, input('D (x y): ').split())
area = triangle_area(x1, y1, x2, y2, x3, y3) + triangle_area(x1, y1, x3, y3, x4, y4)
print('Площадь четырёхугольника =', area)
🎯 Практические задания
Попробуй применить полученные знания на практике!
✍️ Задание 1: Тёплая разминка
Напиши процедуру star(n), которая выводит строку из n звёздочек *. Вызови её несколько раз с разными значениями.
Пример вывода:
***
*****
**
🔢 Задание 2: Средняя сложность
Напиши функцию digit_count(n), которая считает количество цифр в числе n. Например, digit_count(12345) должна вернуть 5.
Подсказка: используй цикл и деление нацело (//).
💪 Задание 3: Для смелых
Напиши функцию binary_digits(n), которая считает количество цифр в двоичной записи числа n. Например, binary_digits(10) должна вернуть 4, потому что 10 в двоичной системе = 1010.
Подсказка: преобразуй число в двоичную систему через bin() или используй деление на 2 в цикле.
🏆 Задание 4: Челлендж!
Используя алгоритм Евклида из примера, напиши программу, которая вычисляет НОК (наименьшее общее кратное) двух чисел.
Вспомни формулу:
НОК(a, b) = (a × b) / НОД(a, b)
🎨 Задание 5: Креатив
Придумай свою задачу из жизни, которую можно решить с помощью функции. Например:
- Функция, которая переводит рубли в другую валюту
- Функция, которая считает, сколько времени осталось до конца урока
- Функция, которая генерирует случайный никнейм для игры
Опиши её в комментариях к коду и реализуй!
🧮 Задание 6: Математика
Напиши рекурсивную функцию для вычисления суммы цифр числа. Например, для числа 12345 результат должен быть 15.
Подсказка: последняя цифра = n % 10, остальные = n // 10
💡 Лайфхак для программиста
🤔 Золотое правило
Когда пишешь код, спроси себя: "Не буду ли я это повторять?"
Если ответ "Да" — пора создавать подпрограмму! Это сэкономит тебе часы отладки и сделает код понятным даже через год.
✨ Преимущества подпрограмм
- Код легче читать и понимать
- Проще искать и исправлять ошибки
- Можно использовать один код многократно
- Легко добавлять новые возможности
⚡ Когда использовать процедуры
- Нужно выполнить действие (вывод, рисование)
- Не требуется возвращать результат
- Работаем с глобальными переменными
🎯 Когда использовать функции
- Нужно вычислить и вернуть значение
- Результат используется в выражениях
- Создаём "чистые" вычисления