Kruchinin
← К списку материалов
🐍 Блок 0 · Авторская разработка

Основы программирования на Python

Интерактивный самоучитель к первым пяти занятиям курса подготовки к ЕГЭ по информатике. Здесь собрана вся теория блока, разобранные примеры с пояснением каждой строчки кода и задачи с раскрывающимся решением. Возвращайся сюда, когда нужно быстро всё вспомнить.

5 занятий
20 разборов кода
10 задач с решением
Python 3 язык курса
Kruchinin
Кручинин Святослав Станиславович
преподаватель информатики · подготовка к ОГЭ и ЕГЭ

Как пользоваться самоучителем

Материал повторяет структуру занятий: одно занятие — один раздел. Внутри раздела всегда одинаковый порядок: сначала определения, потом разобранные примеры, затем типичные ошибки и в конце две задачи для самостоятельной работы.

  • Клик по строке разбора подсвечивает соответствующую строку в коде — и наоборот.
  • Кнопка «Показать решение» раскрывает готовый код задачи с построчным пояснением.
  • Кнопка «Копировать» переносит код в буфер обмена, чтобы запустить его у себя.
  • Отметка «Изучено» сохраняется в браузере — прогресс виден в панели навигации.
📌 Главное правило

Программирование не выучивается чтением. Каждый пример из этого конспекта нужно набрать руками в редакторе и запустить, а потом намеренно сломать: изменить число, убрать отступ, поменять знак. Понимание рождается именно там.

1

Основы алгоритмов. Переменные и типы данных

60 минут
  • Что такое алгоритм и какими свойствами он обладает
  • Как устроена переменная и что делает присваивание
  • Четыре базовых типа данных и преобразование между ними
  • Все арифметические операции, включая //, % и **
  • Как считать данные с клавиатуры несколькими способами

Теория

📖 Определение

Алгоритм — точное и понятное описание последовательности действий, которое из исходных данных за конечное число шагов получает нужный результат.

У любого алгоритма есть пять обязательных свойств. Их спрашивают в теоретической части и они же объясняют, почему компьютер требует такой дотошности:

СвойствоЧто означает
ДискретностьАлгоритм разбит на отдельные завершённые шаги, которые выполняются по очереди.
ОпределённостьКаждый шаг понимается однозначно, без «на твоё усмотрение».
РезультативностьЗа конечное число шагов получается результат или сообщение о его отсутствии.
МассовостьАлгоритм работает не с одним числом, а с целым классом похожих задач.
ПонятностьИспользуются только те команды, которые исполнитель умеет выполнять.

Записать алгоритм можно словами, блок-схемой, псевдокодом или программой. На экзамене и на наших занятиях последний способ — программа на Python.

📖 Определение

Переменная — именованная ячейка памяти, в которой хранится значение. Присваивание (знак =) кладёт значение в эту ячейку, затирая предыдущее.

ℹ️ Важно

Знак = в программировании — это не «равно» из математики, а команда «положи справа в то, что слева». Запись x = x + 1 математически абсурдна, а в программе совершенно нормальна: взять текущее значение, прибавить единицу, положить обратно.

Разбор кода

01_первая_программа.py
# Стоимость покупки: цена умножается на количество
price = 149.50
count = int(input())
total = price * count
print("Итого:", total, "руб.")
Вывод при вводе 3Итого: 448.5 руб.
    🔍 Разбор по строкам
  • Комментарий. Всё, что идёт после # до конца строки, интерпретатор пропускает. Комментарии пишутся для человека.
  • Создаём переменную price и кладём в неё дробное число. Разделитель дробной части — точка, а не запятая.
  • Функция input() читает строку с клавиатуры, а int() превращает её в целое число. Без int() в переменной оказался бы текст.
  • Вычисляем произведение. Справа от = сначала считается выражение, и только потом результат попадает в total.
  • Выводим результат. Аргументы print перечисляются через запятую и в выводе разделяются пробелом автоматически.
📖 Определение

Тип данных определяет, какие значения может хранить переменная и какие операции с ней допустимы. Базовых типов четыре: int — целые числа, float — вещественные, str — строки, bool — логический тип со значениями True и False.

02_типы_данных.py
a = 7
b = 2.5
name = "Илья"
is_ready = True
print(type(a))
print(a + int(b))
print(name * 2)
print(int(is_ready) + 5)
Вывод<class 'int'> 9 ИльяИлья 6
    🔍 Разбор по строкам
  • Целое число. Тип int Python определяет сам — объявлять его не нужно.
  • Есть точка и дробная часть — значит, тип float.
  • Текст в кавычках — тип str. Кавычки можно брать любые, главное открыть и закрыть одинаковыми.
  • Логическое значение. True и False пишутся с заглавной буквы и без кавычек.
  • Функция type() показывает тип значения. Полезна, когда программа ведёт себя странно.
  • int(2.5) даёт 2: дробная часть отбрасывается, а не округляется. Поэтому 7 + 2 = 9.
  • Умножение строки на число повторяет её. Это законная операция, в отличие от сложения строки с числом.
  • True при преобразовании к числу равен 1, а False — 0. Отсюда 1 + 5 = 6.
03_арифметика.py
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)
Вывод22 12 85 3.4 3 2 1419857
    🔍 Разбор по строкам
  • Первое число — делимое.
  • Второе число — делитель.
  • Сложение — привычная операция.
  • Вычитание.
  • Умножение обозначается звёздочкой.
  • Обычное деление. Запомни: результат всегда float, даже если делится нацело.
  • Целочисленное деление // — сколько раз делитель полностью помещается в делимое. Главный инструмент при работе с цифрами числа.
  • Остаток от деления %. Ключевая операция: проверка чётности, кратности, получение последней цифры.
  • Возведение в степень **. Именно две звёздочки, а не знак ^.
⚡ Приём

Пара // 10 и % 10 — это «разборка» числа на цифры. n % 10 даёт последнюю цифру, а n // 10 отрезает её. На этой паре построена половина задач про числа.

Порядок действий тот же, что в математике: сначала **, затем унарный минус, потом *, /, //, %, и в самом конце + и -. Скобки меняют порядок и почти всегда делают код понятнее.

04_ввод_данных.py
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,5 Python поймёт как два отдельных значения.
  • Тип float хранит числа приблизительно: 149.90 * 3 даст 449.70000000000005. Поэтому в задачах ЕГЭ везде, где можно, работают с целыми числами.

Задачи для самостоятельной работы

Задача 1

Обмен значений двух переменных

С клавиатуры вводятся два числа. Выведи их в обратном порядке, обменяв значения переменных местами.

решение_1_1.py
a = int(input())
b = int(input())
a, b = b, a
print(a, b)
    🔍 Разбор по строкам
  • Читаем первое число и сразу превращаем его в целое.
  • Читаем второе число тем же способом.
  • Ключевая строка. Python сначала вычисляет правую часть — пару значений (b, a) — и только потом раскладывает её по переменным слева. Поэтому третья временная переменная не нужна.
  • Выводим результат: значения поменялись местами.
Задача 2

Сумма цифр двузначного числа

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

решение_1_2.py
n = int(input())
d1 = n // 10
d2 = n % 10
print(d1 + d2)
    🔍 Разбор по строкам
  • Читаем двузначное число, например 47.
  • Целочисленное деление на 10 отбрасывает последнюю цифру и оставляет первую: 47 // 10 = 4.
  • Остаток от деления на 10 даёт последнюю цифру: 47 % 10 = 7.
  • Складываем и выводим: 4 + 7 = 11.
2

Условные конструкции if, elif, else, match

60 минут
  • Как программа принимает решения и что такое ветвление
  • Операторы сравнения и логические операции 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). Если сомневаешься — ставь скобки, это не ошибка, а хороший тон.

Разбор кода

05_максимум_из_трёх.py
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)
Вывод при вводе «4 19 7»Максимум: 19
    🔍 Разбор по строкам
  • Читаем три числа из одной строки и раскладываем по трём переменным.
  • Первое условие: a не меньше обоих остальных. Строка обязательно заканчивается двоеточием.
  • Тело ветки сдвинуто вправо на 4 пробела. Именно отступ, а не скобки, показывает Python, что строка относится к if.
  • elif — «иначе если». Проверяется только тогда, когда предыдущее условие оказалось ложным.
  • Тело второй ветки.
  • else срабатывает, когда все условия выше ложны. Условия после него не пишут — оно ловит все оставшиеся случаи.
  • Тело последней ветки: остаётся единственный вариант.
  • Вывод не имеет отступа, значит, выполняется всегда, независимо от выбранной ветки.
📖 Определение

match — case — конструкция сопоставления с образцом. Значение вычисляется один раз и последовательно сравнивается с вариантами. Она читается лучше, чем длинная цепочка elif, когда проверяется одна и та же величина.

06_match_case.py
command = input()
match command:
    case "старт":
        print("Запускаю программу")
    case "стоп":
        print("Останавливаю программу")
    case "пауза" | "ждать":
        print("Ставлю на паузу")
    case _:
        print("Неизвестная команда")
    🔍 Разбор по строкам
  • Читаем команду. Здесь int() не нужен: работаем с текстом.
  • Открываем конструкцию. Значение command вычисляется один раз и дальше только сравнивается.
  • Первый образец. Если строка совпала — выполняется тело этой ветки, остальные пропускаются.
  • Тело первой ветки со сдвигом на восемь пробелов: это уже второй уровень вложенности.
  • Второй образец.
  • Тело второй ветки.
  • Вертикальная черта означает «или». Ветка сработает и на «пауза», и на «ждать».
  • Тело третьей ветки.
  • Подчёркивание — образец «что угодно». Это аналог else и ставится последним.
  • Тело ветки по умолчанию.
07_вложенные_условия.py
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.
  • Цена для взрослого.
  • Вывод без отступа выполняется в любом случае.
08_логические_выражения.py
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)
Вывод при вводе 15True True True True
    🔍 Разбор по строкам
  • Читаем число.
  • 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.

Задачи для самостоятельной работы

Задача 1

Високосный год

Год високосный, если он делится на 4, но не делится на 100, либо делится на 400. Определи тип введённого года.

решение_2_1.py
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 станет неверным — в этом вся суть задачи.
Задача 2

Четверть координатной плоскости

Даны координаты точки. Определи номер четверти или сообщи, что точка лежит на оси.

решение_2_2.py
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 остаётся единственная ситуация.
  • Хотя бы одна координата равна нулю — точка на оси.
3

Циклы for и while

60 минут
  • Чем цикл for отличается от цикла while
  • Все три формы функции range
  • Счётчики и накопители — основа почти всех задач ЕГЭ
  • Операторы break и continue
  • Вложенные циклы и их трудоёмкость

Теория

📖 Определение

Цикл — конструкция, повторяющая группу команд. Одно повторение называется итерацией. Цикл for используют, когда количество повторений известно заранее, а while — когда повторять нужно «пока выполняется условие».

ЗаписьЧто перебираетРезультат
range(5)от 0 до 40 1 2 3 4
range(1, 6)от 1 до 51 2 3 4 5
range(2, 9, 3)от 2 до 8 с шагом 32 5 8
range(10, 0, -2)от 10 вниз с шагом −210 8 6 4 2
ℹ️ Запомни намертво

Правая граница в range не входит в перебор. Чтобы дойти до числа n включительно, пишут range(1, n + 1). Это источник примерно половины ошибок начинающих.

Разбор кода

09_накопитель_суммы.py
total = 0
for i in range(1, 11):
    total = total + i
print("Сумма чисел от 1 до 10:", total)
ВыводСумма чисел от 1 до 10: 55
    🔍 Разбор по строкам
  • Создаём накопитель и обнуляем его до цикла. Если объявить его внутри, он будет сбрасываться на каждой итерации.
  • Переменная i по очереди принимает значения от 1 до 10. Она создаётся автоматически.
  • Тело цикла: прибавляем текущее значение к накопителю. Краткая форма записи — total += i.
  • Вывод стоит после цикла, без отступа. Если сдвинуть его вправо, результат напечатается десять раз.
10_варианты_range.py
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=" ")
Вывод0 1 2 3 4 2 5 8 10 8 6 4 2
    🔍 Разбор по строкам
  • Один аргумент — перебор от нуля. Пятёрка не выводится, потому что правая граница не включается.
  • Параметр end=" " заменяет перевод строки на пробел, поэтому числа печатаются в одну строку.
  • Пустой print() просто переводит курсор на новую строку.
  • Два аргумента задают начало и конец, третий — шаг. Получаем 2, 5 и 8.
  • Тело второго цикла.
  • Снова перевод строки.
  • Отрицательный шаг даёт обратный отсчёт. Начало больше конца — это обязательное условие для убывания.
  • Тело третьего цикла.
11_перебор_цифр_while.py
n = int(input())
s = 0
k = 0
while n > 0:
    s = s + n % 10
    k = k + 1
    n = n // 10
print("Сумма цифр:", s)
print("Количество цифр:", k)
Вывод при вводе 4071Сумма цифр: 12 Количество цифр: 4
    🔍 Разбор по строкам
  • Читаем число. Количество его цифр заранее неизвестно, поэтому for не подходит — нужен while.
  • Накопитель для суммы цифр.
  • Счётчик количества цифр.
  • Условие продолжения: пока в числе осталась хотя бы одна цифра. Как только n станет нулём, цикл прекратится.
  • Берём последнюю цифру через остаток и добавляем её к сумме.
  • Увеличиваем счётчик на единицу.
  • Самая важная строка. Отрезаем последнюю цифру. Если её забыть, условие никогда не станет ложным и программа зациклится навсегда.
  • Выводим сумму цифр.
  • Выводим их количество. Обрати внимание: исходное значение n потеряно — цикл его «съел». Если оно нужно дальше, сохрани копию до цикла.
12_break_и_continue.py
for i in range(2, 100):
    if i % 7 != 0:
        continue
    print("Первое число, кратное 7:", i)
    break
ВыводПервое число, кратное 7: 7
    🔍 Разбор по строкам
  • Перебираем числа от 2 до 99.
  • Проверяем, что число не кратно семи.
  • continue досрочно завершает текущую итерацию и переходит к следующему числу. Всё, что ниже, пропускается.
  • Сюда программа доберётся только для чисел, кратных семи.
  • break полностью прерывает цикл. Без него вывелись бы все числа, кратные семи, а нам нужно только первое.
13_вложенные_циклы.py
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).
  • Вывод внутри цикла вместо вывода после него — печатается лишнее.
  • Использование переменной цикла после его окончания: значение будет последним, а не тем, которое ожидалось.

Задачи для самостоятельной работы

Задача 1

Сумма чётных цифр числа

Дано натуральное число. Найди сумму только тех его цифр, которые чётные.

решение_3_1.py
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 пробела: строка относится к циклу и выполняется всегда, а не только для чётных.
  • Выводим результат после завершения цикла.
Задача 2

Проверка числа на простоту

Определи, является ли введённое число простым. Напомним: простое число делится только на единицу и на само себя.

решение_3_2.py
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 — при ложном.
4

Массивы, списки, кортежи

60 минут
  • Список как основной способ хранить набор значений
  • Индексы, в том числе отрицательные, и срезы
  • Встроенные функции len, sum, min, max, sorted и методы списка
  • Генераторы списков — короткая запись цикла
  • Кортежи и чтение данных из файла

Теория

📖 Определение

Список (в задачах ЕГЭ его называют массивом) — упорядоченный набор значений, хранящийся под одним именем. Каждый элемент имеет индекс — свой порядковый номер. Нумерация начинается с нуля.

📖 Определение

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

Разбор кода

14_список_и_перебор.py
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])
Вывод5 5 7 7 5 3 9 1 7 0 5 1 3 2 9 3 1 4 7
    🔍 Разбор по строкам
  • Создаём список из пяти чисел. Квадратные скобки — признак списка.
  • len() возвращает количество элементов. Индексы при этом идут от 0 до len(a) - 1.
  • Первый элемент имеет индекс 0, последний — индекс 4. Отрицательный индекс -1 тоже указывает на последний элемент, и это удобнее, когда длина заранее неизвестна.
  • Перебор по значениям: переменная x поочерёдно получает сам элемент. Так пишут, когда индекс не нужен.
  • Печатаем элементы в строку.
  • Перевод строки.
  • Перебор по индексам. Эта форма нужна, когда требуется знать номер элемента или сравнивать соседние элементы.
  • Выводим пару «индекс — значение».
15_срезы.py
a = [10, 20, 30, 40, 50, 60]
print(a[1:4])
print(a[:3])
print(a[3:])
print(a[::2])
print(a[::-1])
Вывод[20, 30, 40] [10, 20, 30] [40, 50, 60] [10, 30, 50] [60, 50, 40, 30, 20, 10]
    🔍 Разбор по строкам
  • Исходный список из шести элементов.
  • Срез от индекса 1 до индекса 4, причём правая граница не включается — точно так же, как в range.
  • Левая граница опущена — значит, срез начинается с начала списка.
  • Правая граница опущена — срез идёт до конца списка.
  • Третье число — шаг. Берём каждый второй элемент.
  • Шаг -1 разворачивает список задом наперёд. Самый короткий способ сделать реверс.
16_функции_и_методы.py
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)
Вывод29 9 1 1 2 [1, 3, 4, 5, 7, 9] [9, 7, 5, 4, 3, 1]
    🔍 Разбор по строкам
  • Исходный список.
  • Метод append добавляет элемент в конец. Метод вызывается через точку и меняет сам список.
  • Три встроенные функции: сумма, максимум и минимум. Их не нужно писать вручную циклом.
  • count считает, сколько раз значение встречается, index возвращает индекс первого вхождения.
  • Функция sorted создаёт новый отсортированный список, оставляя исходный нетронутым.
  • Выводим копию: она упорядочена по возрастанию.
  • Метод sort, наоборот, сортирует список на месте. Параметр reverse=True задаёт убывание.
  • Теперь изменился сам список a. Различие между sorted и sort нужно чувствовать твёрдо.
17_генераторы_списков.py
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))
Вывод при вводе «3 5 8»[1, 4, 9, 16, 25, 36, 49] [4, 16, 36] 16
    🔍 Разбор по строкам
  • Генератор списка. Читается справа налево: «для каждого i от 1 до 7 вычисли i * i и собери результаты в список». Это компактная замена циклу с append.
  • Проверяем результат.
  • В генератор добавлено условие: в новый список попадут только элементы, прошедшие фильтр.
  • Выводим отфильтрованный список.
  • Читаем произвольное количество чисел из одной строки — заготовка для задач с массивами.
  • Сумма всех прочитанных чисел.
18_чтение_файла_и_кортежи.py
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(): без него объект нельзя вывести и перебрать дважды.

Задачи для самостоятельной работы

Задача 1

Максимум и его номер

Найди в списке наибольший элемент и индекс его первого вхождения, не используя готовые функции max и index.

решение_4_1.py
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.
Задача 2

Подсчёт по двум условиям

В списке найди количество и сумму элементов, которые больше 100 и при этом кратны трём. Это типовая постановка задания 17 на ЕГЭ.

решение_4_2.py
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)
Вывод3 1170
    🔍 Разбор по строкам
  • Исходные данные. В реальном задании этот список читается из файла.
  • Счётчик подходящих элементов.
  • Накопитель их суммы. Оба обнуляются до цикла.
  • Перебираем по значениям: индексы здесь не нужны.
  • Оба условия соединены через and — элемент должен удовлетворять им одновременно.
  • Увеличиваем счётчик.
  • Прибавляем элемент к сумме. Обе строки на одном отступе внутри if.
  • Выводим оба числа. Подходят 120, 450 и 600.
5

Функции. Вложенные конструкции и рекурсия

60 минут
  • Как объявить функцию и вернуть из неё результат
  • Параметры, аргументы и значения по умолчанию
  • Область видимости: почему переменная «не видна» снаружи
  • Вложенные функции, циклы и условия внутри функции
  • Рекурсия: базовый случай и рекурсивный шаг

Теория

📖 Определение

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

📖 Определение

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

Разбор кода

19_первая_функция.py
def rectangle_area(width, height):
    return width * height
print(rectangle_area(3, 4))
print(rectangle_area(10, 2))
Вывод12 20
    🔍 Разбор по строкам
  • Ключевое слово def, имя функции и параметры в скобках. Строка заканчивается двоеточием.
  • Тело функции с отступом. return отдаёт результат туда, откуда функцию вызвали.
  • Вызов функции: значения 3 и 4 подставляются вместо width и height по порядку.
  • Повторный вызов с другими аргументами. В этом весь смысл функции: код написан один раз, а используется многократно.
20_параметры_по_умолчанию.py
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 баллов дают зачёт.
21_область_видимости.py
count = 0
def add(x):
    count = x
    return count
print(add(5))
print(count)
Вывод5 0
    🔍 Разбор по строкам
  • Глобальная переменная, созданная вне функций.
  • Объявляем функцию с одним параметром.
  • Присваивание внутри функции создаёт новую, локальную переменную с тем же именем. Глобальная при этом не меняется.
  • Возвращаем локальное значение.
  • Функция отработала и вернула 5.
  • А глобальная переменная так и осталась нулём. Это не ошибка языка, а защита: функция не должна незаметно портить внешние данные. Передавай значения через параметры и забирай через return.
22_цикл_внутри_функции.py
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))
Вывод123 -> 6 4567 -> 22 9 -> 9
    🔍 Разбор по строкам
  • Заворачиваем в функцию алгоритм из третьего занятия.
  • Накопитель — локальная переменная, она создаётся заново при каждом вызове. Это и хорошо: результаты вызовов не влияют друг на друга.
  • Цикл внутри функции: отступ 4 пробела.
  • Тело цикла — уже 8 пробелов. Уровни вложенности складываются.
  • Отрезаем цифру. Изменение параметра n внутри функции не затрагивает переменную снаружи.
  • return стоит на уровне тела функции, а не цикла. Если сдвинуть его вправо, функция вернёт результат после первой же итерации.
  • Перебираем список чисел.
  • Вызываем функцию прямо внутри print. Готовый инструмент можно применять сколько угодно раз.
23_рекурсия.py
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)
print(factorial(5))
Вывод120
    🔍 Разбор по строкам
  • Объявляем функцию вычисления факториала.
  • Базовый случай. Он обязан быть первым: именно он останавливает цепочку вызовов.
  • Факториал единицы равен единице — дальше спускаться некуда.
  • Рекурсивный шаг. Функция вызывает саму себя с меньшим аргументом. Цепочка раскручивается так: 5 × 4 × 3 × 2 × 1.
  • Запускаем вычисление. Всего произойдёт пять вложенных вызовов, и результаты «схлопнутся» обратно снизу вверх.
⚡ Приём

Рекурсия — это ключ к заданию 16 и к теории игр в заданиях 19–21. Читая рекурсивную функцию, всегда задавай два вопроса: «где здесь остановка?» и «как задача уменьшается на каждом шаге?». Ответив на них, ты понял функцию целиком.

24_вложенная_функция_и_перебор.py
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)
Вывод12
    🔍 Разбор по строкам
  • Подключаем готовый инструмент перебора из стандартной библиотеки. Именно так решаются задания на комбинаторику.
  • Вспомогательная функция: проверяет, есть ли в слове две одинаковые буквы подряд.
  • Идём до предпоследнего символа, потому что внутри обращаемся к следующему.
  • Сравниваем соседние символы.
  • Нашли повтор — сразу выходим, дальше проверять незачем.
  • Строка выполнится, только если цикл прошёл полностью и повторов не нашлось.
  • Счётчик подходящих слов.
  • product перебирает все слова длины 3 из букв А, Б и В — всего 27 вариантов.
  • Отбираем те, в которых нет повторов. not переворачивает результат функции.
  • Увеличиваем счётчик.
  • Выводим ответ. Перебор сделал всю работу за нас — считать вручную не пришлось.
⚠️ Частые ошибки
  • Забытый return: функция отработала, но вернула None.
  • Путаница между print внутри функции и return. Печать показывает значение, но не отдаёт его в программу.
  • Рекурсия без базового случая или с условием, до которого аргумент никогда не доходит.
  • Попытка изменить глобальную переменную простым присваиванием внутри функции.
  • Вызов функции до её объявления: определение def должно стоять выше по тексту.

Задачи для самостоятельной работы

Задача 1

Функция проверки простоты

Оформи проверку числа на простоту в виде функции и выведи с её помощью все простые числа от 10 до 30.

решение_5_1.py
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=" ")
Вывод11 13 17 19 23 29
    🔍 Разбор по строкам
  • Функция принимает число и возвращает логическое значение. Имя с вопросительным смыслом — хороший стиль.
  • Отсекаем 0, 1 и отрицательные числа.
  • Сразу выходим с ответом «не простое».
  • Ищем делители до квадратного корня включительно.
  • Нашли делитель.
  • Выходим из функции. Здесь return удобнее, чем break с флагом: код короче и читается лучше.
  • Если цикл завершился без выхода, делителей нет — число простое.
  • Перебираем числа от 10 до 30 включительно.
  • Функция подставляется прямо в условие: она ведь возвращает True или False.
  • Печатаем подходящие числа в одну строку.
Задача 2

Рекурсивная функция в стиле задания 16

Функция задана правилами: F(1) = 1, а при n > 1 значение равно F(n − 1) + 2n. Вычисли несколько её значений.

решение_5_2.py
def F(n):
    if n == 1:
        return 1
    return F(n - 1) + 2 * n
print(F(1), F(2), F(3), F(10))
Вывод1 5 11 109
    🔍 Разбор по строкам
  • Имя функции берём прямо из условия задачи. В задании 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 усвоен, если ты можешь без подсказок сделать всё перечисленное. Отметки сохраняются в браузере.

🎯 Что дальше

Со следующего занятия начинается разбор заданий ЕГЭ. Сначала идут задания, которые решаются без программирования, — они дают первые двенадцать первичных баллов. Но всё, что разобрано в этом блоке, будет использоваться до самого экзамена.