Как пользоваться самоучителем
Материал повторяет структуру занятий: одно занятие — один раздел. Внутри раздела всегда одинаковый порядок: сначала определения, потом разобранные примеры, затем типичные ошибки и в конце две задачи для самостоятельной работы.
- Клик по строке разбора подсвечивает соответствующую строку в коде — и наоборот.
- Кнопка «Показать решение» раскрывает готовый код задачи с построчным пояснением.
- Кнопка «Копировать» переносит код в буфер обмена, чтобы запустить его у себя.
- Отметка «Изучено» сохраняется в браузере — прогресс виден в панели навигации.
Программирование не выучивается чтением. Каждый пример из этого конспекта нужно набрать руками в редакторе и запустить, а потом намеренно сломать: изменить число, убрать отступ, поменять знак. Понимание рождается именно там.
Основы алгоритмов. Переменные и типы данных
- Что такое алгоритм и какими свойствами он обладает
- Как устроена переменная и что делает присваивание
- Четыре базовых типа данных и преобразование между ними
- Все арифметические операции, включая
//,%и** - Как считать данные с клавиатуры несколькими способами
Теория
Алгоритм — точное и понятное описание последовательности действий, которое из исходных данных за конечное число шагов получает нужный результат.
У любого алгоритма есть пять обязательных свойств. Их спрашивают в теоретической части и они же объясняют, почему компьютер требует такой дотошности:
| Свойство | Что означает |
|---|---|
| Дискретность | Алгоритм разбит на отдельные завершённые шаги, которые выполняются по очереди. |
| Определённость | Каждый шаг понимается однозначно, без «на твоё усмотрение». |
| Результативность | За конечное число шагов получается результат или сообщение о его отсутствии. |
| Массовость | Алгоритм работает не с одним числом, а с целым классом похожих задач. |
| Понятность | Используются только те команды, которые исполнитель умеет выполнять. |
Записать алгоритм можно словами, блок-схемой, псевдокодом или программой. На экзамене и на наших занятиях последний способ — программа на Python.
Переменная — именованная ячейка памяти, в которой хранится значение.
Присваивание (знак =) кладёт значение в эту ячейку,
затирая предыдущее.
Знак = в программировании — это не «равно» из математики, а команда «положи
справа в то, что слева». Запись x = x + 1 математически абсурдна, а в программе
совершенно нормальна: взять текущее значение, прибавить единицу, положить обратно.
Разбор кода
# Стоимость покупки: цена умножается на количество
price = 149.50
count = int(input())
total = price * count
print("Итого:", total, "руб.")
- Комментарий. Всё, что идёт после
#до конца строки, интерпретатор пропускает. Комментарии пишутся для человека. - Создаём переменную
priceи кладём в неё дробное число. Разделитель дробной части — точка, а не запятая. - Функция
input()читает строку с клавиатуры, аint()превращает её в целое число. Безint()в переменной оказался бы текст. - Вычисляем произведение. Справа от
=сначала считается выражение, и только потом результат попадает вtotal. - Выводим результат. Аргументы
printперечисляются через запятую и в выводе разделяются пробелом автоматически.
Тип данных определяет, какие значения может хранить переменная и
какие операции с ней допустимы. Базовых типов четыре: int — целые числа,
float — вещественные, str — строки, bool — логический
тип со значениями True и False.
a = 7
b = 2.5
name = "Илья"
is_ready = True
print(type(a))
print(a + int(b))
print(name * 2)
print(int(is_ready) + 5)
- Целое число. Тип
intPython определяет сам — объявлять его не нужно. - Есть точка и дробная часть — значит, тип
float. - Текст в кавычках — тип
str. Кавычки можно брать любые, главное открыть и закрыть одинаковыми. - Логическое значение.
TrueиFalseпишутся с заглавной буквы и без кавычек. - Функция
type()показывает тип значения. Полезна, когда программа ведёт себя странно. int(2.5)даёт2: дробная часть отбрасывается, а не округляется. Поэтому7 + 2 = 9.- Умножение строки на число повторяет её. Это законная операция, в отличие от сложения строки с числом.
Trueпри преобразовании к числу равен1, аFalse—0. Отсюда1 + 5 = 6.
a = 17
b = 5
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a // b)
print(a % b)
print(a ** b)
- Первое число — делимое.
- Второе число — делитель.
- Сложение — привычная операция.
- Вычитание.
- Умножение обозначается звёздочкой.
- Обычное деление. Запомни: результат всегда
float, даже если делится нацело. - Целочисленное деление
//— сколько раз делитель полностью помещается в делимое. Главный инструмент при работе с цифрами числа. - Остаток от деления
%. Ключевая операция: проверка чётности, кратности, получение последней цифры. - Возведение в степень
**. Именно две звёздочки, а не знак^.
Пара // 10 и % 10 — это «разборка» числа на цифры.
n % 10 даёт последнюю цифру, а n // 10 отрезает её.
На этой паре построена половина задач про числа.
Порядок действий тот же, что в математике: сначала **, затем унарный минус, потом *, /, //, %, и в самом конце + и -. Скобки меняют порядок и почти всегда делают код понятнее.
n = int(input())
x, y = int(input()), int(input())
a, b = map(int, input().split())
nums = list(map(int, input().split()))
print(n, x, y, a, b, nums)
- Одно число на отдельной строке — базовый случай.
- Два числа на разных строках. Слева от
=перечисляем две переменные, справа — два значения. - Два числа в одной строке через пробел.
split()режет строку по пробелам,map(int, ...)применяетintк каждому куску. - Неизвестно сколько чисел в строке — оборачиваем в
list()и получаем список. Этот приём понадобится в заданиях с массивами. - Выводим всё сразу, чтобы убедиться, что данные прочитаны верно.
input()всегда возвращает строку. Забылint()— и вместо5 + 3 = 8получишь"53"."5" + 5вызывает ошибкуTypeError: строку и число складывать нельзя.- Регистр важен:
Countиcount— две разные переменные. - Имя переменной не может начинаться с цифры и не может совпадать с ключевым словом языка.
- Дробная часть отделяется точкой.
2,5Python поймёт как два отдельных значения. - Тип
floatхранит числа приблизительно:149.90 * 3даст449.70000000000005. Поэтому в задачах ЕГЭ везде, где можно, работают с целыми числами.
Задачи для самостоятельной работы
Обмен значений двух переменных
С клавиатуры вводятся два числа. Выведи их в обратном порядке, обменяв значения переменных местами.
a = int(input())
b = int(input())
a, b = b, a
print(a, b)
- Читаем первое число и сразу превращаем его в целое.
- Читаем второе число тем же способом.
- Ключевая строка. Python сначала вычисляет правую часть — пару значений
(b, a)— и только потом раскладывает её по переменным слева. Поэтому третья временная переменная не нужна. - Выводим результат: значения поменялись местами.
Сумма цифр двузначного числа
Дано двузначное число. Найди сумму его цифр, не используя циклы и строки.
n = int(input())
d1 = n // 10
d2 = n % 10
print(d1 + d2)
- Читаем двузначное число, например
47. - Целочисленное деление на 10 отбрасывает последнюю цифру и оставляет первую:
47 // 10 = 4. - Остаток от деления на 10 даёт последнюю цифру:
47 % 10 = 7. - Складываем и выводим:
4 + 7 = 11.
Условные конструкции if, elif, else, match
- Как программа принимает решения и что такое ветвление
- Операторы сравнения и логические операции
and,or,not - Полная конструкция
if — elif — else - Конструкция
match — caseи когда она удобнее цепочкиelif - Вложенные условия и роль отступов
Теория
Ветвление — конструкция, при которой программа выбирает одну из
нескольких последовательностей действий в зависимости от истинности условия.
Условие — это выражение, значение которого либо True,
либо False.
| Оператор | Смысл | Пример истинного выражения |
|---|---|---|
== | равно | 5 == 5 |
!= | не равно | 5 != 3 |
> < | больше, меньше | 7 > 2 |
>= <= | больше или равно, меньше или равно | 4 >= 4 |
and | истинно, когда истинны оба условия | 3 > 1 and 2 < 5 |
or | истинно, когда истинно хотя бы одно | 3 > 9 or 2 < 5 |
not | меняет значение на противоположное | not (3 > 9) |
Сначала выполняется not, затем and, и только потом or.
То есть a or b and c означает a or (b and c). Если сомневаешься —
ставь скобки, это не ошибка, а хороший тон.
Разбор кода
a, b, c = map(int, input().split())
if a >= b and a >= c:
m = a
elif b >= a and b >= c:
m = b
else:
m = c
print("Максимум:", m)
- Читаем три числа из одной строки и раскладываем по трём переменным.
- Первое условие:
aне меньше обоих остальных. Строка обязательно заканчивается двоеточием. - Тело ветки сдвинуто вправо на 4 пробела. Именно отступ, а не скобки, показывает Python, что строка относится к
if. elif— «иначе если». Проверяется только тогда, когда предыдущее условие оказалось ложным.- Тело второй ветки.
elseсрабатывает, когда все условия выше ложны. Условия после него не пишут — оно ловит все оставшиеся случаи.- Тело последней ветки: остаётся единственный вариант.
- Вывод не имеет отступа, значит, выполняется всегда, независимо от выбранной ветки.
match — case — конструкция сопоставления с образцом. Значение
вычисляется один раз и последовательно сравнивается с вариантами. Она читается лучше, чем
длинная цепочка elif, когда проверяется одна и та же величина.
command = input()
match command:
case "старт":
print("Запускаю программу")
case "стоп":
print("Останавливаю программу")
case "пауза" | "ждать":
print("Ставлю на паузу")
case _:
print("Неизвестная команда")
- Читаем команду. Здесь
int()не нужен: работаем с текстом. - Открываем конструкцию. Значение
commandвычисляется один раз и дальше только сравнивается. - Первый образец. Если строка совпала — выполняется тело этой ветки, остальные пропускаются.
- Тело первой ветки со сдвигом на восемь пробелов: это уже второй уровень вложенности.
- Второй образец.
- Тело второй ветки.
- Вертикальная черта означает «или». Ветка сработает и на «пауза», и на «ждать».
- Тело третьей ветки.
- Подчёркивание — образец «что угодно». Это аналог
elseи ставится последним. - Тело ветки по умолчанию.
age = int(input())
is_student = input() == "да"
if age < 7:
price = 0
else:
if is_student:
price = 150
else:
price = 300
print("Билет стоит", price)
- Читаем возраст.
- Сравнение
==само по себе даётTrueилиFalse, поэтому вis_studentсразу попадает логическое значение. Отдельныйifздесь не нужен. - Внешнее условие: дошкольникам билет бесплатный.
- Тело внешнего
if. - Ветка «иначе» для всех, кому 7 лет и больше.
- Вложенный
ifвнутриelse. Он проверяется только для тех, кто прошёл внешнюю проверку. - Второй уровень вложенности — отступ 8 пробелов.
- Вложенный
elseна том же уровне, что и вложенныйif. - Цена для взрослого.
- Вывод без отступа выполняется в любом случае.
x = int(input())
print(0 < x < 100)
print(not (x % 2 == 0))
print(x % 3 == 0 or x % 5 == 0)
print(x % 3 == 0 and x % 5 == 0)
- Читаем число.
- Python разрешает двойное неравенство — так же, как в математике. Это короче, чем
x > 0 and x < 100. - Проверка на нечётность: остаток от деления на 2 не равен нулю.
notпереворачивает результат. - Число кратно 3 или 5 — достаточно одного совпадения.
- Число кратно 3 и 5 одновременно, то есть кратно 15. Нужны оба совпадения.
- Одиночное
=вместо==в условии. Первое присваивает, второе сравнивает. - Забытое двоеточие в конце строки с
if,elif,else. - Смешение табуляции и пробелов в отступах — Python выдаст ошибку отступа.
- Цепочка независимых
ifвместоelif: тогда проверятся все условия, и результат перезапишется последним подходящим. - Сравнение дробных чисел через
==ненадёжно из-за погрешности:0.1 + 0.2 == 0.3даётFalse.
Задачи для самостоятельной работы
Високосный год
Год високосный, если он делится на 4, но не делится на 100, либо делится на 400. Определи тип введённого года.
y = int(input())
if y % 400 == 0:
print("Високосный")
elif y % 100 == 0:
print("Обычный")
elif y % 4 == 0:
print("Високосный")
else:
print("Обычный")
- Читаем год.
- Проверки идут от самого строгого условия к самому общему. Кратность 400 — сильнейшее правило, оно перекрывает все остальные.
- Например, 2000 год високосный именно по этому правилу.
- Сюда попадают года, кратные 100, но не 400. Например, 1900 — обычный.
- Вывод для этого случая.
- Остались года, не кратные 100. Для них работает простое правило кратности четырём.
- Например, 2024 год.
- Все прочие года.
- Обычный год. Если поменять порядок проверок местами, ответ для 1900 станет неверным — в этом вся суть задачи.
Четверть координатной плоскости
Даны координаты точки. Определи номер четверти или сообщи, что точка лежит на оси.
x, y = map(int, input().split())
if x > 0 and y > 0:
print(1)
elif x < 0 and y > 0:
print(2)
elif x < 0 and y < 0:
print(3)
elif x > 0 and y < 0:
print(4)
else:
print("Точка лежит на оси")
- Читаем две координаты из одной строки.
- Первая четверть: обе координаты строго положительны. Строгое неравенство здесь принципиально — иначе точки на осях попадут в четверти.
- Выводим номер четверти.
- Вторая четверть: слева и сверху.
- Вывод.
- Третья четверть: слева и снизу.
- Вывод.
- Четвёртая четверть: справа и снизу.
- Вывод.
- Все случаи разобраны, поэтому в
elseостаётся единственная ситуация. - Хотя бы одна координата равна нулю — точка на оси.
Циклы for и while
- Чем цикл
forотличается от циклаwhile - Все три формы функции
range - Счётчики и накопители — основа почти всех задач ЕГЭ
- Операторы
breakиcontinue - Вложенные циклы и их трудоёмкость
Теория
Цикл — конструкция, повторяющая группу команд. Одно повторение
называется итерацией. Цикл for используют, когда
количество повторений известно заранее, а while — когда повторять нужно
«пока выполняется условие».
| Запись | Что перебирает | Результат |
|---|---|---|
range(5) | от 0 до 4 | 0 1 2 3 4 |
range(1, 6) | от 1 до 5 | 1 2 3 4 5 |
range(2, 9, 3) | от 2 до 8 с шагом 3 | 2 5 8 |
range(10, 0, -2) | от 10 вниз с шагом −2 | 10 8 6 4 2 |
Правая граница в range не входит в перебор. Чтобы дойти до числа
n включительно, пишут range(1, n + 1). Это источник примерно
половины ошибок начинающих.
Разбор кода
total = 0
for i in range(1, 11):
total = total + i
print("Сумма чисел от 1 до 10:", total)
- Создаём накопитель и обнуляем его до цикла. Если объявить его внутри, он будет сбрасываться на каждой итерации.
- Переменная
iпо очереди принимает значения от 1 до 10. Она создаётся автоматически. - Тело цикла: прибавляем текущее значение к накопителю. Краткая форма записи —
total += i. - Вывод стоит после цикла, без отступа. Если сдвинуть его вправо, результат напечатается десять раз.
for i in range(5):
print(i, end=" ")
print()
for i in range(2, 9, 3):
print(i, end=" ")
print()
for i in range(10, 0, -2):
print(i, end=" ")
- Один аргумент — перебор от нуля. Пятёрка не выводится, потому что правая граница не включается.
- Параметр
end=" "заменяет перевод строки на пробел, поэтому числа печатаются в одну строку. - Пустой
print()просто переводит курсор на новую строку. - Два аргумента задают начало и конец, третий — шаг. Получаем 2, 5 и 8.
- Тело второго цикла.
- Снова перевод строки.
- Отрицательный шаг даёт обратный отсчёт. Начало больше конца — это обязательное условие для убывания.
- Тело третьего цикла.
n = int(input())
s = 0
k = 0
while n > 0:
s = s + n % 10
k = k + 1
n = n // 10
print("Сумма цифр:", s)
print("Количество цифр:", k)
- Читаем число. Количество его цифр заранее неизвестно, поэтому
forне подходит — нуженwhile. - Накопитель для суммы цифр.
- Счётчик количества цифр.
- Условие продолжения: пока в числе осталась хотя бы одна цифра. Как только
nстанет нулём, цикл прекратится. - Берём последнюю цифру через остаток и добавляем её к сумме.
- Увеличиваем счётчик на единицу.
- Самая важная строка. Отрезаем последнюю цифру. Если её забыть, условие никогда не станет ложным и программа зациклится навсегда.
- Выводим сумму цифр.
- Выводим их количество. Обрати внимание: исходное значение
nпотеряно — цикл его «съел». Если оно нужно дальше, сохрани копию до цикла.
for i in range(2, 100):
if i % 7 != 0:
continue
print("Первое число, кратное 7:", i)
break
- Перебираем числа от 2 до 99.
- Проверяем, что число не кратно семи.
continueдосрочно завершает текущую итерацию и переходит к следующему числу. Всё, что ниже, пропускается.- Сюда программа доберётся только для чисел, кратных семи.
breakполностью прерывает цикл. Без него вывелись бы все числа, кратные семи, а нам нужно только первое.
for i in range(1, 4):
for j in range(1, 4):
print(i, "x", j, "=", i * j)
print("---")
- Внешний цикл. Он сделает три итерации.
- Внутренний цикл. Он полностью проходит все свои три итерации на каждом шаге внешнего. Итого 3 × 3 = 9 строк вывода.
- Тело внутреннего цикла, отступ 8 пробелов.
- Разделитель с отступом 4 пробела: он относится к внешнему циклу и печатается трижды, после каждой группы.
Вложенные циклы перемножают количество шагов. Два цикла по миллиону — это триллион операций, программа не успеет никогда. На экзамене, если решение «в лоб» требует двух вложенных циклов по большому массиву, почти всегда существует решение в один проход.
- Бесконечный цикл: забыли изменить переменную, от которой зависит условие
while. - Накопитель объявлен внутри цикла и обнуляется на каждой итерации.
- Ошибка на единицу: написали
range(1, n)вместоrange(1, n + 1). - Вывод внутри цикла вместо вывода после него — печатается лишнее.
- Использование переменной цикла после его окончания: значение будет последним, а не тем, которое ожидалось.
Задачи для самостоятельной работы
Сумма чётных цифр числа
Дано натуральное число. Найди сумму только тех его цифр, которые чётные.
n = int(input())
s = 0
while n > 0:
d = n % 10
if d % 2 == 0:
s = s + d
n = n // 10
print(s)
- Читаем число.
- Обнуляем накопитель до цикла.
- Работаем, пока в числе остаются цифры.
- Сохраняем последнюю цифру в отдельную переменную — так код читается лучше, чем с повторным
n % 10. - Условие внутри цикла: цифра чётная, если остаток от деления на 2 равен нулю.
- Прибавляем только подходящие цифры. Отступ 8 пробелов — строка относится к
if. - Отрезаем обработанную цифру. Отступ 4 пробела: строка относится к циклу и выполняется всегда, а не только для чётных.
- Выводим результат после завершения цикла.
Проверка числа на простоту
Определи, является ли введённое число простым. Напомним: простое число делится только на единицу и на само себя.
n = int(input())
is_prime = n > 1
for d in range(2, int(n ** 0.5) + 1):
if n % d == 0:
is_prime = False
break
print("Простое" if is_prime else "Составное")
- Читаем число.
- Заводим «флаг» и сразу учитываем, что числа 0 и 1 простыми не считаются. Сравнение даёт готовое логическое значение.
- Ищем делители. Проверять достаточно до квадратного корня: если у числа есть делитель больше корня, то парный ему обязательно меньше.
n ** 0.5— это и есть корень. - Нашли делитель без остатка.
- Опускаем флаг: число составное.
- Прерываем цикл — искать дальше бессмысленно. Для больших чисел это сильно ускоряет программу.
- Условное выражение в одну строку: значение перед
ifберётся при истинном условии, послеelse— при ложном.
Массивы, списки, кортежи
- Список как основной способ хранить набор значений
- Индексы, в том числе отрицательные, и срезы
- Встроенные функции
len,sum,min,max,sortedи методы списка - Генераторы списков — короткая запись цикла
- Кортежи и чтение данных из файла
Теория
Список (в задачах ЕГЭ его называют массивом) — упорядоченный набор значений, хранящийся под одним именем. Каждый элемент имеет индекс — свой порядковый номер. Нумерация начинается с нуля.
Кортеж — такой же упорядоченный набор, но неизменяемый: после создания в него нельзя добавить элемент или заменить существующий. Записывается круглыми скобками.
Разбор кода
a = [5, 3, 9, 1, 7]
print(len(a))
print(a[0], a[4], a[-1])
for x in a:
print(x, end=" ")
print()
for i in range(len(a)):
print(i, a[i])
- Создаём список из пяти чисел. Квадратные скобки — признак списка.
len()возвращает количество элементов. Индексы при этом идут от 0 доlen(a) - 1.- Первый элемент имеет индекс 0, последний — индекс 4. Отрицательный индекс
-1тоже указывает на последний элемент, и это удобнее, когда длина заранее неизвестна. - Перебор по значениям: переменная
xпоочерёдно получает сам элемент. Так пишут, когда индекс не нужен. - Печатаем элементы в строку.
- Перевод строки.
- Перебор по индексам. Эта форма нужна, когда требуется знать номер элемента или сравнивать соседние элементы.
- Выводим пару «индекс — значение».
a = [10, 20, 30, 40, 50, 60]
print(a[1:4])
print(a[:3])
print(a[3:])
print(a[::2])
print(a[::-1])
- Исходный список из шести элементов.
- Срез от индекса 1 до индекса 4, причём правая граница не включается — точно так же, как в
range. - Левая граница опущена — значит, срез начинается с начала списка.
- Правая граница опущена — срез идёт до конца списка.
- Третье число — шаг. Берём каждый второй элемент.
- Шаг
-1разворачивает список задом наперёд. Самый короткий способ сделать реверс.
a = [5, 3, 9, 1, 7]
a.append(4)
print(sum(a), max(a), min(a))
print(a.count(3), a.index(9))
b = sorted(a)
print(b)
a.sort(reverse=True)
print(a)
- Исходный список.
- Метод
appendдобавляет элемент в конец. Метод вызывается через точку и меняет сам список. - Три встроенные функции: сумма, максимум и минимум. Их не нужно писать вручную циклом.
countсчитает, сколько раз значение встречается,indexвозвращает индекс первого вхождения.- Функция
sortedсоздаёт новый отсортированный список, оставляя исходный нетронутым. - Выводим копию: она упорядочена по возрастанию.
- Метод
sort, наоборот, сортирует список на месте. Параметрreverse=Trueзадаёт убывание. - Теперь изменился сам список
a. Различие междуsortedиsortнужно чувствовать твёрдо.
squares = [i * i for i in range(1, 8)]
print(squares)
evens = [x for x in squares if x % 2 == 0]
print(evens)
nums = list(map(int, input().split()))
print(sum(nums))
- Генератор списка. Читается справа налево: «для каждого
iот 1 до 7 вычислиi * iи собери результаты в список». Это компактная замена циклу сappend. - Проверяем результат.
- В генератор добавлено условие: в новый список попадут только элементы, прошедшие фильтр.
- Выводим отфильтрованный список.
- Читаем произвольное количество чисел из одной строки — заготовка для задач с массивами.
- Сумма всех прочитанных чисел.
with open("17.txt") as f:
a = [int(line) for line in f]
print(len(a), max(a))
point = (3, 8)
x, y = point
print(x + y)
- Открываем файл. Конструкция
withсама закроет его после работы — именно так читают данные в заданиях ЕГЭ. - Генератор списка по строкам файла: каждая строка превращается в целое число. Функция
intсама отбрасывает символ перевода строки. - Проверяем, что данные прочитаны: количество элементов и максимум.
- Создаём кортеж из двух чисел. Круглые скобки вместо квадратных.
- Распаковка: элементы кортежа раскладываются по переменным. Точно так же работает
a, b = b, aиз первого занятия. - Пользуемся полученными значениями. Попытка написать
point[0] = 5вызвала бы ошибку: кортеж изменять нельзя.
- Обращение к
a[len(a)]— выход за границу списка. Последний индекс равенlen(a) - 1. b = aне создаёт копию: обе переменные указывают на один и тот же список. Копия делается срезомb = a[:].- Путаница между
sorted(a)(возвращает новый список) иa.sort()(возвращаетNoneи меняет исходный). - Удаление элементов из списка прямо во время его перебора — часть элементов будет пропущена.
- Забытый
list()вокругmap(): без него объект нельзя вывести и перебрать дважды.
Задачи для самостоятельной работы
Максимум и его номер
Найди в списке наибольший элемент и индекс его первого вхождения, не используя готовые функции max и index.
a = [4, 17, 9, 17, 2]
best = a[0]
pos = 0
for i in range(1, len(a)):
if a[i] > best:
best = a[i]
pos = i
print(best, pos)
- Исходный список. Обрати внимание: максимум встречается дважды.
- За начальный максимум берём первый элемент, а не ноль. Иначе алгоритм сломается на списке из отрицательных чисел.
- Его индекс равен нулю.
- Перебор начинаем с индекса 1: нулевой элемент уже учтён.
- Строгое сравнение
>обеспечивает первое вхождение. Если поставить>=, запомнится последнее. - Обновляем максимум.
- Одновременно запоминаем его позицию. Обе строки должны быть внутри
if. - Выводим ответ: значение 17 и индекс 1.
Подсчёт по двум условиям
В списке найди количество и сумму элементов, которые больше 100 и при этом кратны трём. Это типовая постановка задания 17 на ЕГЭ.
a = [120, 305, 99, 450, 78, 600]
count = 0
total = 0
for x in a:
if x > 100 and x % 3 == 0:
count = count + 1
total = total + x
print(count, total)
- Исходные данные. В реальном задании этот список читается из файла.
- Счётчик подходящих элементов.
- Накопитель их суммы. Оба обнуляются до цикла.
- Перебираем по значениям: индексы здесь не нужны.
- Оба условия соединены через
and— элемент должен удовлетворять им одновременно. - Увеличиваем счётчик.
- Прибавляем элемент к сумме. Обе строки на одном отступе внутри
if. - Выводим оба числа. Подходят 120, 450 и 600.
Функции. Вложенные конструкции и рекурсия
- Как объявить функцию и вернуть из неё результат
- Параметры, аргументы и значения по умолчанию
- Область видимости: почему переменная «не видна» снаружи
- Вложенные функции, циклы и условия внутри функции
- Рекурсия: базовый случай и рекурсивный шаг
Теория
Функция — именованный блок кода, который выполняется при вызове.
Параметры — переменные в заголовке функции,
аргументы — конкретные значения, переданные при вызове.
Оператор return возвращает результат и немедленно завершает работу функции.
Рекурсия — приём, при котором функция вызывает саму себя. Рекурсивная функция обязана содержать базовый случай — условие, при котором вызовы прекращаются. Без него программа завершится ошибкой переполнения стека.
Разбор кода
def rectangle_area(width, height):
return width * height
print(rectangle_area(3, 4))
print(rectangle_area(10, 2))
- Ключевое слово
def, имя функции и параметры в скобках. Строка заканчивается двоеточием. - Тело функции с отступом.
returnотдаёт результат туда, откуда функцию вызвали. - Вызов функции: значения 3 и 4 подставляются вместо
widthиheightпо порядку. - Повторный вызов с другими аргументами. В этом весь смысл функции: код написан один раз, а используется многократно.
def grade(score, pass_mark=40):
if score >= 80:
return "отлично"
if score >= pass_mark:
return "зачёт"
return "не сдано"
print(grade(92))
print(grade(55))
print(grade(30, 25))
- У второго параметра есть значение по умолчанию. Если при вызове его не передать, будет использовано 40.
- Первая проверка.
returnне только возвращает значение, но и сразу выходит из функции. Остальные строки уже не выполнятся.- Вторая проверка. Сюда попадаем, только если первая оказалась ложной, поэтому
elifне нужен. - Возврат второго варианта.
- Строка без условия: если ни одна проверка не сработала, возвращается этот результат.
- Вызов с одним аргументом — порог берётся по умолчанию.
- Ещё один вызов: 55 меньше 80, но не меньше 40.
- Здесь порог передан явно и равен 25, поэтому 30 баллов дают зачёт.
count = 0
def add(x):
count = x
return count
print(add(5))
print(count)
- Глобальная переменная, созданная вне функций.
- Объявляем функцию с одним параметром.
- Присваивание внутри функции создаёт новую, локальную переменную с тем же именем. Глобальная при этом не меняется.
- Возвращаем локальное значение.
- Функция отработала и вернула 5.
- А глобальная переменная так и осталась нулём. Это не ошибка языка, а защита: функция не должна незаметно портить внешние данные. Передавай значения через параметры и забирай через
return.
def digits_sum(n):
s = 0
while n > 0:
s = s + n % 10
n = n // 10
return s
for number in [123, 4567, 9]:
print(number, "->", digits_sum(number))
- Заворачиваем в функцию алгоритм из третьего занятия.
- Накопитель — локальная переменная, она создаётся заново при каждом вызове. Это и хорошо: результаты вызовов не влияют друг на друга.
- Цикл внутри функции: отступ 4 пробела.
- Тело цикла — уже 8 пробелов. Уровни вложенности складываются.
- Отрезаем цифру. Изменение параметра
nвнутри функции не затрагивает переменную снаружи. returnстоит на уровне тела функции, а не цикла. Если сдвинуть его вправо, функция вернёт результат после первой же итерации.- Перебираем список чисел.
- Вызываем функцию прямо внутри
print. Готовый инструмент можно применять сколько угодно раз.
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5))
- Объявляем функцию вычисления факториала.
- Базовый случай. Он обязан быть первым: именно он останавливает цепочку вызовов.
- Факториал единицы равен единице — дальше спускаться некуда.
- Рекурсивный шаг. Функция вызывает саму себя с меньшим аргументом. Цепочка раскручивается так: 5 × 4 × 3 × 2 × 1.
- Запускаем вычисление. Всего произойдёт пять вложенных вызовов, и результаты «схлопнутся» обратно снизу вверх.
Рекурсия — это ключ к заданию 16 и к теории игр в заданиях 19–21. Читая рекурсивную функцию, всегда задавай два вопроса: «где здесь остановка?» и «как задача уменьшается на каждом шаге?». Ответив на них, ты понял функцию целиком.
from itertools import product
def has_double(word):
for i in range(len(word) - 1):
if word[i] == word[i + 1]:
return True
return False
count = 0
for w in product("АБВ", repeat=3):
if not has_double(w):
count = count + 1
print(count)
- Подключаем готовый инструмент перебора из стандартной библиотеки. Именно так решаются задания на комбинаторику.
- Вспомогательная функция: проверяет, есть ли в слове две одинаковые буквы подряд.
- Идём до предпоследнего символа, потому что внутри обращаемся к следующему.
- Сравниваем соседние символы.
- Нашли повтор — сразу выходим, дальше проверять незачем.
- Строка выполнится, только если цикл прошёл полностью и повторов не нашлось.
- Счётчик подходящих слов.
productперебирает все слова длины 3 из букв А, Б и В — всего 27 вариантов.- Отбираем те, в которых нет повторов.
notпереворачивает результат функции. - Увеличиваем счётчик.
- Выводим ответ. Перебор сделал всю работу за нас — считать вручную не пришлось.
- Забытый
return: функция отработала, но вернулаNone. - Путаница между
printвнутри функции иreturn. Печать показывает значение, но не отдаёт его в программу. - Рекурсия без базового случая или с условием, до которого аргумент никогда не доходит.
- Попытка изменить глобальную переменную простым присваиванием внутри функции.
- Вызов функции до её объявления: определение
defдолжно стоять выше по тексту.
Задачи для самостоятельной работы
Функция проверки простоты
Оформи проверку числа на простоту в виде функции и выведи с её помощью все простые числа от 10 до 30.
def is_prime(n):
if n < 2:
return False
for d in range(2, int(n ** 0.5) + 1):
if n % d == 0:
return False
return True
for x in range(10, 31):
if is_prime(x):
print(x, end=" ")
- Функция принимает число и возвращает логическое значение. Имя с вопросительным смыслом — хороший стиль.
- Отсекаем 0, 1 и отрицательные числа.
- Сразу выходим с ответом «не простое».
- Ищем делители до квадратного корня включительно.
- Нашли делитель.
- Выходим из функции. Здесь
returnудобнее, чемbreakс флагом: код короче и читается лучше. - Если цикл завершился без выхода, делителей нет — число простое.
- Перебираем числа от 10 до 30 включительно.
- Функция подставляется прямо в условие: она ведь возвращает
TrueилиFalse. - Печатаем подходящие числа в одну строку.
Рекурсивная функция в стиле задания 16
Функция задана правилами: F(1) = 1, а при n > 1 значение равно F(n − 1) + 2n. Вычисли несколько её значений.
def F(n):
if n == 1:
return 1
return F(n - 1) + 2 * n
print(F(1), F(2), F(3), F(10))
- Имя функции берём прямо из условия задачи. В задании 16 правила даны точно в таком же виде — их достаточно переписать на Python почти дословно.
- Базовый случай из условия.
- Возвращаем заданное значение и останавливаем рекурсию.
- Рекурсивный шаг: точная копия формулы
F(n − 1) + 2n. Аргумент уменьшается, значит, цепочка вызовов рано или поздно дойдёт до базового случая. - Проверяем на нескольких значениях. Например,
F(3)раскрывается так:F(2) + 6 = (F(1) + 4) + 6 = 1 + 4 + 6 = 11.
Шпаргалка по всему блоку
Эту часть удобно распечатать и держать рядом с клавиатурой первые пару месяцев.
Операции и их смысл
| Запись | Что делает | Пример |
|---|---|---|
// | целочисленное деление | 17 // 5 → 3 |
% | остаток от деления | 17 % 5 → 2 |
** | возведение в степень | 2 ** 10 → 1024 |
n ** 0.5 | квадратный корень | 49 ** 0.5 → 7.0 |
x % 2 == 0 | проверка чётности | True для 8 |
n % 10 | последняя цифра числа | 407 % 10 → 7 |
n // 10 | число без последней цифры | 407 // 10 → 40 |
Заготовки, которые стоит помнить наизусть
| Задача | Код |
|---|---|
| Прочитать числа из одной строки | a = list(map(int, input().split())) |
| Прочитать числа из файла | a = [int(s) for s in open("17.txt")] |
| Перебор цифр числа | while n > 0: d = n % 10; n = n // 10 |
| Счётчик по условию | if условие: count += 1 |
| Поиск максимума | if a[i] > best: best = a[i] |
| Перебор всех слов | for w in product("АБВ", repeat=3): |
| Развернуть список | a[::-1] |
Отступы — синтаксис, а не оформление
В Python вложенность задаётся только отступом. Четыре пробела — один уровень. Строка без отступа выполняется всегда; строка с отступом — только когда выполняется условие или идёт итерация цикла. Большинство ошибок первых недель — это неверный отступ, а не незнание теории.
Чек-лист самопроверки
Блок 0 усвоен, если ты можешь без подсказок сделать всё перечисленное. Отметки сохраняются в браузере.
Со следующего занятия начинается разбор заданий ЕГЭ. Сначала идут задания, которые решаются без программирования, — они дают первые двенадцать первичных баллов. Но всё, что разобрано в этом блоке, будет использоваться до самого экзамена.