КулЛиб - Классная библиотека! Скачать книги бесплатно 

Python для анализа данных: учебное пособие [Роберт Викторович Гарафутдинов] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]
Р. В. Гарафутдинов

PYTHON ДЛЯ АНАЛИЗА ДАННЫХ

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ
РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное автономное
образовательное учреждение высшего образования
«ПЕРМСКИЙ ГОСУДАРСТВЕННЫЙ
НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ»

Р. В. Гарафутдинов

PYTHON ДЛЯ АНАЛИЗА ДАННЫХ

Допущено методическим советом
Пермского государственного национального
исследовательского университета в качестве
учебного пособия для студентов, обучающихся
по направлениям подготовки бакалавров «Экономика»,
«Менеджмент», «Бизнес-информатика»,
«Торговое дело»

Пермь 2024

УДК 004.43(075.8)
ББК 32.973я73
Г20

Гарафутдинов Р. В.
Г20 Python для анализа данных [Электронный ресурс] : учебное пособие / Р. В. Гарафутдинов ; Пермский государственный национальный исследовательский университет. – Электронные данные. –
Пермь, 2024. – 9,19 Мб ; 276 с. – Режим доступа:
http://www.psu.ru/files/docs/science/books/uchebnie-posobiya/GarafutdinovPython-dlya-analiza-dannyh.pdf. – Заглавие с экрана.

ISBN 978-5-7944-4096-6
Цель учебного пособия – помочь студентам, изучающим курс «Python для
анализа данных», приобрести системные знания по основам программирования
на языке Python и освоить работу со стандартными возможностями языка и его
библиотеками на уровне, достаточном для решения задач обработки и анализа
данных. Рассматриваются базовые элементы и синтаксические конструкции
языка Python 3. Описываются основные методы и приемы работы с рядами и табличными данными с применением популярных Python-библиотек. Издание содержит тематический план, теорию с примерами программного кода, задания для
самостоятельной работы и список использованных источников.
Учебное пособие подготовлено на основе опыта преподавания дисциплины
студентам экономического факультета Пермского государственного национального исследовательского университета и факультета социально-экономических
и компьютерных наук Национального исследовательского университета «Высшая школа экономики» (Пермь).
УДК 004.43(075.8)
ББК 32.973я73
Издается по решению ученого совета экономического факультета
Пермского государственного национального исследовательского университета
Рецензенты: кафедра информационных технологий в бизнесе Пермского филиала Национального исследовательского университета «Высшая
школа экономики» (и.о. зав. кафедрой – д-р пед. наук, профессор
Е. Г. Плотникова);
начальник управления организации научных исследований Пермского национального исследовательского политехнического университета, канд. экон. наук, доцент А. О. Алексеев
© ПГНИУ, 2024
© Гарафутдинов Р. В., 2024

ISBN 978-5-7944-4096-6

2

ОГЛАВЛЕНИЕ
Введение .................................................................................................................. 6
Раздел 1. Основы программирования на Python ............................................... 9
Предисловие к первому разделу .......................................................................... 9
1. Введение в алгоритмизацию и программирование ....................................... 10
1.1. Высокоуровневые языки программирования .......................................... 10
1.2. Язык Python ............................................................................................... 15
1.3. Задания для самостоятельной работы ...................................................... 20
2. Среда разработки Google Colaboratory........................................................... 21
2.1. Общие сведения о платформе ................................................................... 21
2.2. Основы работы в Colab ............................................................................. 21
2.3. Задания для самостоятельной работы ...................................................... 30
3. Синтаксис Python и основные конструкции программы .............................. 31
3.1. Переменные ............................................................................................... 31
3.2. Оператор присваивания ............................................................................ 32
3.3. Комментарии ............................................................................................. 33
3.4. Типы данных.............................................................................................. 34
3.5. Функции ..................................................................................................... 38
3.6. Ввод-вывод данных ................................................................................... 40
3.7. Математические вычисления .................................................................... 44
3.8. Подключение функций из библиотек....................................................... 49
3.9. Операции сравнения чисел ....................................................................... 52
3.10. Особенности работы с вещественными числами .................................. 53
3.11. Исключительные ситуации (ошибки) .................................................... 56
3.12. Задания для самостоятельной работы .................................................... 62
4. Условия и циклы ............................................................................................. 64
4.1. Основные алгоритмические структуры ................................................... 64
4.2. Условный оператор if ................................................................................ 65
4.3. Оператор цикла while ................................................................................ 72
4.4. Задания для самостоятельной работы ...................................................... 79
5. Коллекции........................................................................................................ 81
5.1. Классы, объекты, методы.......................................................................... 81
5.2. Итерируемые объекты (коллекции) ......................................................... 82
5.3. Строка ........................................................................................................ 83
5.4. Диапазон .................................................................................................... 84
5.5. Кортеж ....................................................................................................... 85
5.6. Список ........................................................................................................ 87
5.7. Преобразование типов коллекций ............................................................ 89
5.8. Передача в функцию элементов коллекции как аргументов .................. 90
5.9. Оператор цикла for .................................................................................... 90
5.10. Задания для самостоятельной работы .................................................... 92
3

6. Вложенные коллекции .................................................................................... 93
6.1. Двумерные массивы в Python ................................................................... 93
6.2. Обращение к внутренним элементам вложенных коллекций ................ 97
6.3. Поэлементный обход вложенных коллекций .......................................... 99
6.4. Функция enumerate() и for с несколькими параметрами ....................... 102
6.5. Простое и глубокое копирование ........................................................... 104
6.6. Задания для самостоятельной работы .................................................... 105
7. Обработка строк ............................................................................................ 107
7.1. Срезы........................................................................................................ 107
7.2. Строковые методы .................................................................................. 110
7.3. Задания для самостоятельной работы .................................................... 114
8. Продвинутая обработка коллекций .............................................................. 115
8.1. Сортировка .............................................................................................. 115
8.2. Некоторые другие инструменты обработки коллекций ........................ 121
8.3. Модуль itertools ....................................................................................... 124
8.4. Функции map(), filter() и генерация списка ........................................... 126
8.5. Задания для самостоятельной работы .................................................... 128
9. Подробно о функциях ................................................................................... 129
9.1. Пользовательские функции .................................................................... 129
9.2. Значения аргументов по умолчанию ...................................................... 134
9.3. Позиционные и именованные аргументы .............................................. 135
9.4. Нефиксированное количество аргументов функции ............................. 136
9.5. Локальные и глобальные переменные ................................................... 139
9.6. Передача в функцию изменяемых и неизменяемых объектов .............. 141
9.7. Анонимные (лямбда) функции ............................................................... 142
9.8. Задания для самостоятельной работы .................................................... 143
10. Неиндексированные коллекции и файлы .................................................. 144
10.1. Множества ............................................................................................. 144
10.2. Словари .................................................................................................. 151
10.3. Работа с файлами ................................................................................... 156
10.4. Задания для самостоятельной работы .................................................. 166
11. Работа с интернет-данными ........................................................................ 168
11.1. Данные в сети Интернет ....................................................................... 168
11.2. REST API ............................................................................................... 169
11.3. Извлечение данных из веб-страниц ...................................................... 176
11.4. Задания для самостоятельной работы .................................................. 187
Раздел 2. Библиотеки для анализа данных .................................................... 188
Предисловие ко второму разделу ..................................................................... 188
12. Библиотека NumPy и векторизованные вычисления ................................ 189
12.1. Векторизованные операции .................................................................. 189
12.2. Операции с массивами .......................................................................... 192
12.3. Многомерные массивы ......................................................................... 195
12.4. Использование генератора случайных чисел ...................................... 201
4

12.5. Операции линейной алгебры над матрицами ...................................... 203
12.6. Задание для самостоятельной работы .................................................. 206
13. Библиотека pandas ....................................................................................... 207
13.1. Ряды (тип данных Series) ...................................................................... 207
13.2. Таблицы (тип данных DataFrame) ........................................................ 220
13.3. Загрузка и выгрузка наборов данных (датасетов) ............................... 242
13.4. Пример предварительной обработки датасета .................................... 246
13.5. Задания для самостоятельной работы .................................................. 249
14. Визуализация ............................................................................................... 250
14.1. Библиотека Matplotlib ........................................................................... 250
14.2. Библиотека seaborn ................................................................................ 267
14.3. Несколько диаграмм на холсте ............................................................. 271
14.4. Задания для самостоятельной работы .................................................. 272
Список использованных источников ............................................................. 274

5

ВВЕДЕНИЕ
Существует многообразие инструментов анализа данных. Они представляют собой различные программные решения, включая универсальные системы
(такие как табличный процессор Microsoft Excel и его аналоги), позволяющие
выполнять широкий круг задач обработки одномерных и табличных данных, и
специализированные прикладные пакеты, ориентированные на анализ данных
непосредственно (такие как Gretl, Statistica, EViews и т.п.). Особняком среди этих
инструментов стоят языки программирования высокого уровня, наиболее популярными из которых при решении задач такого рода являются R и Python. Оба
этих языка (которые зачастую незаслуженно именуют прикладными пакетами,
подразумевая не то сам интерпретатор, не то среду разработки, будь то RStudio
или PyCharm), будучи инструментами принципиально иного класса, нежели действительные прикладные пакеты, предоставляют фундаментально более широкие возможности обработки и анализа данных. Готовое приложение, пусть и
очень функциональное, учитывающее множество сценариев работы с данными,
ограничено фантазией и «представлениями о прекрасном» разработчиков этого
приложения. Навыки же алгоритмизации и программирования и знание какоголибо популярного в сфере наук о данных (Data Science) языка снимает практически все ограничения с исследователя: потолок его возможностей по манипуляции с данными устанавливается лишь его собственной квалификацией (и фантазией). Цель данного пособия – вручить читателю описанный ультимативный инструмент и обучить основам его использования.
Язык R широко популярен среди аналитиков данных и других специалистов по Data Science. Если сравнивать его с Python, можно сказать, что R является
более «высокоуровневым»: он рассчитан на специалистов, более близких к предметной области, в которой они работают, чем к информационным технологиям;
можно сказать, что R – это «язык программирования для непрограммистов».
Настоящее учебное пособие посвящено другому языку – Python, который
более универсален, в чем-то более традиционен в сравнении с R, но при этом не
менее прост в освоении и совершенно точно предлагает разработчику не меньше
возможностей. Более того, по мнению автора, навыки и знания, полученные при
изучении Python, универсальнее и позволяют с большей легкостью переходить
на использование других языков программирования, чем это позволяет знание
языка R, являющегося в достаточной мере специфическим. По данным рейтинга
языков программирования, ежегодно составляемого журналом IEEE Spectrum,
Python по состоянию на 2023 год является самым распространенным и востребованным языком [16]. Следует отметить, что в пособии рассматривается язык

6

Python актуальной версии 3 как наиболее современный и активно развивающийся на момент написания данного материала.
Пособие состоит из двух разделов. В первом разделе излагаются основы
программирования на языке Python. В нем в меру глубоко рассматриваются теоретические моменты, связанные с алгоритмизацией и программированием, и
приводится большое количество примеров программного кода с подробными пояснениями. Второй раздел посвящен библиотекам Python, широко применяемым
при анализе данных (NumPy – для векторизованной обработки многомерных
массивов; pandas – для работы с рядами и таблицами; Matplotlib и seaborn – для
визуализации). Он в меньшей степени ориентирован на теорию, в большей – на
практические примеры обработки данных с использованием инструментов,
предоставляемых этими библиотеками.
Пособие предназначено для студентов экономического факультета Пермского государственного национального исследовательского университета
направлений «Экономика», «Менеджмент», «Бизнес-информатика», «Торговое
дело», а также «Прикладная математика и информатика» всех форм обучения.
Издание может быть рекомендовано для широкого круга студентов, аспирантов и преподавателей, желающих овладеть языком программирования Python
как инструментом, позволяющим решать задачи обработки и анализа данных,
построения моделей машинного обучения и любые другие, исследовательские и
практические.
Для работы с данным пособием необходим достаточно высокий уровень
компьютерной грамотности. Желательно (но не является критически необходимым) знание некоторых разделов следующих учебных дисциплин: информатика,
высшая математика (в части линейной алгебры), теория вероятностей и математическая статистика.
Для достижения наилучшего результата пособие следует изучать последовательно, от главы к главе. Некоторые примеры и задания для самостоятельного
выполнения являются сквозными. Например, в примере (задании) могут использоваться данные, подготовленные в предыдущих параграфах (на это есть указания в тексте).
Все приведенные в пособии программные коды доступны в виде блокнотов
Google Colab по следующим ссылкам: глава 3, глава 4, глава 5, глава 6, глава 7,
глава 8, глава 9, глава 10, глава 11, глава 12, глава 13, глава 14. Эти блокноты
подготовлены автором для удобства читателя и не содержат дополнительного
материала. Если платформа Google Colaboratory в силу каких-либо причин перестанет функционировать, на доступность материалов пособия это не повлияет.
В тексте использованы следующие обозначения программного кода и различных элементов языка Python (табл. 1).
7

Таблица 1
Условные обозначения в тексте пособия
Описание
Программный код, который можно скопировать
и выполнить, вместе с отображаемым результатом его выполнения. Используются те же цвета,
что в редакторе Colab. Результат может отсутствовать в двух случаях: если код ничего не выводит; когда результирующее значение для экономии места приведено в комментарии. Если вывод кода слишком объемный и для понимания
примера не требуется приводить его целиком, используется сокращение вывода с помощью символа многоточия …
Описание формата вызова функции с перечислением наиболее важных аргументов. В треугольные скобки заключены текстовые описания
элементов команды

Описание формата сложного оператора (конструкции) языка. Ключевые слова выделены цветом
Фрагмент программного кода в основном тексте,
в том числе отдельные переменные и литералы,
функции, типы данных, атрибуты и методы объектов
Оператор языка
Название библиотеки или модуля
Тип исключения (ошибки)

8

Пример
# результат приведен в области
# вывода под ячейкой
print("Привет, мир!")
Привет, мир!
# результат приведен
# в комментарии
round(3.7) # 4

print(, ,
..., ,
sep=,
end=)

while :
команды тела цикла

x = 2 * 3
round()
True
str
continue

NumPy
TypeError

РАЗДЕЛ 1. ОСНОВЫ ПРОГРАММИРОВАНИЯ НА PYTHON
Предисловие к первому разделу
Прежде чем приступать к аналитике и формированию выводов на основе
исследования данных, следует освоить инструментарий – программные средства, предоставляющие необходимые возможности.
Программных решений для анализа данных существует много. Очевидно,
что читатель данного пособия уже сделал свой выбор в пользу языка программирования Python, и автором этот выбор горячо поддерживается. Действительно,
владение навыками программирования на самом популярном языке позволяет
реализовать любые задачи, связанные с обработкой данных, и не только применять существующие методы и методики, но и разрабатывать собственные. Есть,
однако, у данного инструментария недостаток: достаточно высокая сложность
использования. Если мы посмотрим на примеры программного кода для решения
какой-нибудь в меру типовой задачи (скажем, построение столбчатой диаграммы
с группировкой), которые в изобилии можно найти как в документации к библиотекам, так и на тематических ресурсах в интернете, велика вероятность того,
что объем и сложность этого кода нас неприятно удивят. Во всяком случае, состоять он будет не из одной строчки, а даже если из одной, прочитать эту строчку
и понять, что в ней происходит, без специальных знаний окажется задачей нетривиальной. Чем более универсален, менее «однокнопочен» инструмент, тем
сложнее его эффективное использование. Последний из «трех законов» фантаста
А. Кларка гласит: «Достаточно развитая технология неотличима от волшебства»
[20]. Но даже юному волшебнику Гарри Поттеру из одноименной серии романов
Дж. К. Роулинг пришлось несколько лет постигать искусство владения своей
волшебной палочкой. Язык Python и его библиотеки, несомненно, могут стать
«волшебной палочкой» для специалиста по наукам о данных, но для этого требуется время, определенная доля усилий и, конечно, желание.
Первый раздел пособия посвящен введению в программирование на языке
Python с нуля. Автор категорически рекомендует изучить этот раздел, прежде
чем переходить к инструментам, ориентированным на анализ данных непосредственно. Лишь после освоения основ языка программный код, приводящий к
нужному результату, не будет восприниматься как «магия» с неизвестным механизмом действия. Если разобраться в принципах написания кода и ознакомиться
с основными категориями программирования на Python, такими как объекты, методы, функции, коллекции и так далее, окажется, что все эти непонятные записи
далеко не так сложны и запутаны, как могло показаться на первый взгляд. Во
всем есть логика, код всегда составлен по определенным правилам. И тогда волшебная палочка заработает в полную силу.
9

1. Введение в алгоритмизацию и программирование
Первая глава знакомит читателя с основами работы компьютера, описывает процесс программирования как вид деятельности, пытается ответить на сакраментальный вопрос «а что здесь вообще происходит?». Также в ней излагаются общие сведения о языке программирования Python, его особенностях и достоинствах.
1.1. Высокоуровневые языки программирования
Алгоритм
Компьютер – это машина, обрабатывающая информацию. Обработка информации – это все, что она умеет делать.
Чтобы компьютер решил какую-то полезную задачу, необходимо ему эту
задачу доходчиво объяснить, то есть дать четкую инструкцию на понятном компьютеру языке.
Алгоритм – это последовательность команд, предназначенная для исполнителя, в результате выполнения которой он должен решить поставленную задачу. Исполнителем может быть человек или машина.
Примерами алгоритмов для исполнителя-человека являются: инструкция
по делению в столбик, рецепт варки борща, инструкция по ремонту холодильника.
Алгоритм для исполнителя-машины (компьютера), записанный на специальном языке, понятном исполнителю (компьютеру), называется компьютерной
программой, а этот язык – языком программирования.
Алгоритм обладает рядом свойств:
✓ должен описываться на формальном языке, исключающем неоднозначность толкования;
✓ должен быть понятен исполнителю;
✓ исполнитель должен уметь выполнять все команды, составляющие алгоритм;
✓ множество возможных команд, из которых состоит алгоритм, конечно
и изначально строго задано;
✓ свойство конечности (результативности): алгоритм должен приводить к решению задачи (получению результата) за конечное число шагов;
✓ свойство массовости: алгоритм должен быть применим для некоторого
класса задач, различающихся исходными данными;
✓ всегда имеет входные и выходные данные.

10

Устройство компьютера
Компьютер состоит из двух важнейших частей: вычислительный блок и
память.
1. Вычислительный блок – это центральный процессор (Intel Pentium,
Core i7, AMD Athlon, Ryzen и т.д.) (рис. 1, а). Именно он обеспечивает работу
компьютера, то есть исполнение программ. Можно сказать, что компьютер без
процессора – не более чем «груда железа».
2. Память – это хранилище данных. Компьютер занимается обработкой
информации, он не создает эту информацию из ничего. Данные поступают на
вход компьютера, выполняются некоторые преобразования, и что-то получается
на выходе. Все эти данные нужно где-то хранить, и хранятся они в памяти.
Выделяют два вида памяти:
1. Энергозависимая память (оперативная память, оперативное запоминающее устройство, ОЗУ) (рис. 1, б). Хранит данные только при подаче электропитания. Когда говорят, что в компьютере 4 или 8 гигабайт памяти, как правило,
речь ведут именно об ОЗУ.
2. Энергонезависимая память (внешняя память, внешнее запоминающее
устройство, ВЗУ) (рис. 1в). Хранит данные вне зависимости от подачи электропитания. К устройствам памяти данного вида относятся жесткие диски (HDD) и
твердотельные накопители (SSD), но также к ним можно отнести различные
флешки, включая карты памяти, компакт-диски и т.п.

а)

б)
в)
Рис. 1. Комплектующие компьютера: а – процессор Intel Core i7;
б – модуль памяти DDR4; в – SSD-накопитель
Источник: https://www.ixbt.com

ОЗУ – быстрая память, операции с ней (чтение и запись) происходят даже
не в разы, а на порядки быстрее, чем с ВЗУ. Можно сказать, что оперативная
память предназначена для текущей, оперативной работы с данными (тут важна
скорость), а внешняя – для их долгосрочного хранения (тут больше важна емкость, объем дискового пространства).
При выполнении программы сам ее код и данные, с которыми она работает,
находятся в оперативной памяти. Например, необходимо поместить в память
11

число 5, чтобы затем выполнить с ним некоторые математические манипуляции.
На языке Python эта операция выглядит так:
a = 5

В результате ее выполнения в оперативной памяти создастся ячейка под
названием a, в которой будет храниться число 5, и храниться оно там будет до
тех пор, пока память не будет очищена (пока программа выполняется).
Если нужно хранить значение переменной a в течение длительного времени, его необходимо записать во внешнюю энергонезависимую память – в файл
на диске (например, текстовый).
Высокоуровневые языки
Все данные в компьютере хранятся в виде чисел. Компьютер – это вычислительная машина, очень продвинутый калькулятор. Все, что он умеет, – производить математические операции над какими-то числами и считывать (записывать) данные из памяти (в память). Как уже было отмечено, занимается этим центральный процессор.
Строго говоря, только выполнять операции с данными процессор и умеет,
и компьютерные вычисления именно так и реализуются. Например, очень упрощенно и условно операция сложения чисел 𝐴 и 𝐵 выглядит так: в каждом разряде
ячейки 𝐵 устанавливается состояние, соответствующее сумме цифр слагаемых,
набранных первоначально в 𝐴 и 𝐵 в этом разряде, и переходной единицы из
предыдущего разряда, если она есть; в результате в ячейке 𝐵 оказывается сумма
чисел [21].
Любые действия, осуществляемые компьютером, в конечном счете состоят
из подобных элементарных операций. Этих операций очень много. Чтобы получить результат любого математического выражения, нужно перебрать и обработать множество ячеек с данными.
Для программирования первых компьютеров нужно было указывать каждую такую элементарную операцию, то есть отдавать команду компьютеру
напрямую: скопируй данные из этой ячейки памяти в другую ячейку, с той ячейкой сделай что-нибудь еще и т.д. Программы состояли из последовательностей
отверстий на перфокартах (старинных носителях данных) (рис. 2).
Конечно, работа программиста была тяжела и трудоемка. Описанное программирование является низкоуровневым. Под низким уровнем подразумевается, что программист практически напрямую отдает команды процессору, общается с ним на очень низком уровне, в так называемых машинных кодах.

12

Рис. 2. Перфокарта формата IBM
Источник: https://ru.wikipedia.org

Затем появился язык ассемблера – язык тоже низкоуровневый, но все-таки
более высокого уровня, чем машинные коды. У разных моделей процессоров
были собственные отличающиеся системы команд, и соответственно, под каждый процессор надо было писать специфические для него программы. Выглядит
программа на ассемблере так:
org
mov
mov
int

0x100
ah, 0x9
dx, hello
0x21

Принцип программирования на ассемблере все тот же: программа содержит команды процессору, предписывающие ему осуществлять некоторые операции с теми или иными данными в ячейках памяти. На ассемблерах пишут и сегодня (на момент издания данного пособия), это требуется в некоторых специфических задачах.
Шло время, появились унифицированные системы команд для разных процессоров. В частности, все современные процессоры производства компаний
Intel и AMD понимают систему команд x86 и ее расширение x86_64. Уровень
абстракции (то есть уровень, на котором происходит общение программиста с
компьютером) вырастал, а требования к квалификации программистов падали.
Появились языки программирования высокого уровня.
Программист, пишущий на таком языке, оперирует не ячейками памяти, с
которыми надо что-то сделать, а более абстрактными структурами и конструкциями данных. Язык высокого уровня похож на естественный язык – в особенности для англоговорящих программистов. Впрочем, вот пример кода на языке
программирования 1С 8:
Переменная = Новый Массив;
Переменная.Добавить(22); // в ячейку 1 записать значение 22
Переменная.Добавить(33); // в ячейку 2 записать значение 33
Сообщить(Переменная[0]); // вывести ячейки 1

13

Но процессор все равно понимает только свои машинные коды. «Высокоуровневость» языка заключается в том, что между непосредственно оборудованием (процессором) и программистом, пишущим код, есть специальные промежуточные слои, программные прослойки, которые берут программный код на
языке высокого уровня, понятный человеку, и преобразуют его в команды, понятные процессору. Таким «переводчиком с программистского языка на процессорный» является транслятор языка программирования.
Транслятор бывает двух видов (рис. 3).
Транслятор

Компилятор

Интерпретатор
Рис. 3. Виды трансляторов

Компилятор переводит целиком весь код программы в машинные коды, на
выходе получается исполняемый файл, который можно запускать на выполнение. Интерпретатор последовательно транслирует в машинный код каждую команду программы и сразу выполняет ее. Недостаток интерпретатора: он более
медленный, потому что приходится транслировать каждую команду отдельно, а
не всю программу разом, как это делает компилятор. Python является интерпретируемым языком.
Тенденции в сфере информационных технологий таковы, что уровень абстракции языков растет и программировать становится все проще: от программиста уже не требуется разбираться в тонкостях работы компьютера, порог
вхождения в профессию падает. Существуют даже визуальные языки программирования, не требующие непосредственного кодирования. Программа на таком
языке представляет собой набор графических объектов, составляемый при помощи мыши (рис. 4).

Рис. 4. Пример фрагмента программы на языке Google Blockly
Источник: https://developers.google.com

14

Ознакомившись с понятием высокоуровневого языка, перейдем к языку
программирования Python.
1.2. Язык Python
Общие сведения о языке
Python – универсальный язык программирования высокого уровня. Несмотря на то, что на логотипе языка изображены две змейки, назван он не в честь
этих представителей животного царства, а в честь британского телешоу «Летающий цирк Монти Пайтона» (рис. 5).

а)
б)
Рис. 5. Происхождение названия языка Python: а – логотип Python;
б – кадр из скетча Монти Пайтон «Мертвый попугай»
Источник: https://ru.wikipedia.org

Одна из целей создателей языка – сделать его «забавным для использования». И действительно, Python существенно отличается от большинства других
языков своей простотой, изяществом кода и оригинальностью синтаксиса.
По версии IEEE1 Spectrum Python уже несколько лет является самым популярным языком программирования в мире (по данным на 2023 г. (рис. 6).
Python создан в 1991 году. Создателем языка является Гвидо ван Россум,
голландский программист, лауреат премии Free Software Award 2001 г. за вклад
в развитие свободного программного обеспечения.
Python пережил несколько поколений архитектурных изменений и по сей
день продолжает быть актуальным. На практике можно встретить программы,
написанные на языке двух версий: версии 2 и версии 3. На данный момент актуальна и активно развивается именно версия 3. Текущий релиз – 3.12.1 (по состоянию на конец декабря 2023 г.). Последней официально поддерживаемой версией второго поколения Python была 2.7.18.

IEEE (институт инженеров электротехники и электроники) – некоммерческая инженерная ассоциация, разрабатывающая широко применяемые в мире стандарты по радиоэлектронике, электротехнике и аппаратному обеспечению вычислительных систем и сетей.
1

15

Рис. 6. Рейтинг популярности языков программирования в 2023 г.
Источник: [16]

Следует разделять понятия язык Python и интерпретатор Python. Язык
программирования – это набор правил и ключевых слов, с помощью которых записываются программы, интерпретатор же – это компьютерная программа, которая исполняет программный код, записанный на языке. Когда говорят, что
была выпущена новая версия Python, имеют в виду как саму версию языка (он
постоянно обновляется, дорабатывается), так и интерпретатор, предназначенный
для этой версии. Например, интерпретатор Python 3.9 предполагает, что исполняемые им программы написаны на языке версии 3.9, и при интерпретации ведет
себя так, как предписано спецификацией данной версии Python. Программы,
написанные на Python 2, не будут корректно работать, если попытаться их запустить с помощью интерпретатора Python 3 (скорее всего, они не запустятся вовсе
из-за несовпадения синтаксиса). Программы же, написанные на Python 3.5, будут
работать с интерпретатором Python 3.10 (обратное не гарантируется). Новые версии языка (в рамках одной мажорной версии, которой является третья) сохраняют совместимость со старыми версиями, просто новые обладают рядом возможностей, которых не было в старых.
Перечислим некоторые важные особенности Python:
✓ является изначально объектно-ориентированным (каждая переменная
является ссылкой на объект);
✓ является интерпретируемым (эталонная реализация интерпретатора –
CPython, но существуют и другие);

16

✓ характеризуется строгой динамической типизацией (ее еще называют
«утиной» по принципу «утиного теста»: если что-то выглядит как утка, плавает
как утка и крякает как утка, то это, вероятно, и есть утка);
✓ имеет автоматическое управление памятью (сборку мусора);
✓ характеризуется выделением блоков кода пробельными отступами.
К преимуществам Python относятся следующие его качества:
✓ универсальность (на Python можно написать программы для решения
практически любой задачи);
✓ кроссплатформенность (существуют интерпретаторы Python для различных программных и аппаратных платформ: персональных компьютеров,
смартфонов, сетевых устройств и т.д.);
✓ огромное сообщество разработчиков;
✓ широкий выбор готовых библиотек (в том числе для научных расчетов,
анализа данных, машинного обучения и т.д.);
✓ минималистичность и простота программ;
✓ пологая кривая обучения (чтобы суметь решить задачу, имеющую
практическое значение, достаточно освоить азы языка, что можно сделать в короткие сроки; по мере углубления знаний сложность и полезность создаваемых
программ могут возрастать);
✓ язык способствует написанию красивого и понятного кода (это обусловлено как самим синтаксисом Python, так и правилами программирования на
нем, описанными в Дзене и PEP8, – об этом ниже).
Основным недостатком Python, с точки зрения автора, является то, что он
интерпретируемый, а следовательно, медленный (в сравнении с компилируемыми языками). Однако Python использует скомпилированные функции и объекты, написанные на языке C, а также промежуточный байт-код, который создается на основе исходных Python-скриптов. Эти факторы позволяют несколько
нивелировать данный недостаток и повысить производительность исполнения
программ. Не стоит забывать, что разработчиками активно ведутся работы по
оптимизации и ускорению интерпретатора.
Дзен Python
Принципы языка Python, его философия сформулированы в тексте под
названием The Zen of Python. Приведем его перевод на русский язык [19]:
1. Красивое лучше, чем уродливое.
2. Явное лучше, чем неявное.
3. Простое лучше, чем сложное.
17

4. Сложное лучше, чем запутанное.
5. Плоское лучше, чем вложенное.
6. Разреженное лучше, чем плотное.
7. Читаемость имеет значение.
8. Особые случаи не настолько особые, чтобы нарушать правила.
9. При этом практичность важнее безупречности.
10. Ошибки никогда не должны замалчиваться.
11. Если они не замалчиваются явно.
12. Встретив двусмысленность, отбрось искушение угадать.
13. Должен существовать один и желательно только один очевидный способ сделать это.
14. Хотя он поначалу может быть и не очевиден, если вы не голландец.
15. Сейчас лучше, чем никогда.
16. Хотя никогда зачастую лучше, чем прямо сейчас.
17. Если реализацию сложно объяснить – идея плоха.
18. Если реализацию легко объяснить – идея, возможно, хороша.
19. Пространства имен – отличная штука! Будем делать их больше!
Конечно, многие из пунктов Дзена могут быть непонятны начинающему
программисту, однако по мере изучения языка все становится на свои места.
И чтобы стать хорошим «питонистом» (программистом на Python), следует этих
принципов придерживаться.
Стандарт PEP8
Важнейшей рекомендацией по стилевому оформлению программ на языке
Python является стандарт PEP8: он описывает правила именования и структурирования кода, принятые в сообществе Python-разработчиков.
Приведем некоторые правила PEP8:
✓ для выделения блоков кода следует использовать отступы из четырех
пробелов;
✓ рекомендуется использовать строки, длина которых не превышает диапазон 80–120 символов (первые мониторы были ограничены 80 символами в ширину);
✓ функции верхнего уровня и определения классов следует отделять от
основного кода программы двумя пустыми строками;
✓ следует использовать пустые строки для логического разделения программы на блоки;
✓ следует использовать одиночные пробелы с каждой стороны у операторов присваивания, сравнения и логических операторов.
18

Подробнее о стандарте PEP8 и его требованиях к коду можно прочитать в
следующих источниках: документ на английском языке [13], выжимка на русском языке [14].
Приступая к программированию на Python
Чтобы написать и выполнить программу на Python, необходимы следующие программные компоненты, установленные на компьютере:
1. Редактор программного кода. Это текстовый редактор, предоставляющий возможности для удобного написания программ на языке программирования (в нашем случае Python).
2. Транслятор языка. Это программа-переводчик, «транслирующая» (переводящая) программу с высокоуровневого языка программирования в низкоуровневый язык, понятный процессору. Как мы уже выяснили, в случае Python
используется следующая разновидность транслятора: интерпретатор.
Интерпретатор Python можно скачать по ссылке [1].
Удобной средой разработки, имеющей в составе редактор кода, является
PyCharm (ссылка для скачивания: [23]). PyCharm – инструмент, предназначенный для опытных Python-разработчиков, эта среда предоставляет программисту
широкие возможности, включая отладчик и инструменты версионирования программ, однако начинающему установить ее и разобраться, как в ней работать, не
так просто.
Мы будем писать код в онлайн-среде разработки Google Colab. Знакомству
с данной платформой посвящена вторая глава учебного пособия.
Стоит отметить, что интерпретатор Python (программа python.exe) имеет
так называемый интерактивный режим работы, который позволяет писать и
выполнять команды языка в командной строке по одной. В этом режиме длинные, сложные программы не пишут, однако его удобно использовать как инструмент решения некоторых задач (например, в качестве продвинутого калькулятора) (рис. 7).

Рис. 7. Интерпретатор Python в интерактивном режиме

19

Прежде чем приступить к изучению основ Python, познакомимся со средой
разработки Google Colab. Это необходимо, чтобы выполнять код из примеров и
практиковаться в программировании.
1.3. Задания для самостоятельной работы
Ответьте своими словами на следующие вопросы:
1. Приведите по два-три примера алгоритма для: исполнителя-человека;
исполнителя-компьютера.
2. Какими свойствами характеризуется алгоритм?
3. Что такое язык программирования?
4. Что такое компьютерная программа?
5. Каковы функции блока компьютера, который называется «центральный процессор»?
6. В чем различие оперативной и внешней памяти?
7. В чем отличие интерпретатора от компилятора?
8. Каковы преимущества языка Python, обеспечившие его широкую популярность?
9. Что такое «Дзен Python» и стандарт PEP8? Являются ли они наборами
строгих предписаний или только рекомендациями программисту?
10. Какие программные компоненты являются минимально необходимыми для того, чтобы написать и выполнить компьютерную программу?

20

2. Среда разработки Google Colaboratory
Вторая глава целиком посвящена основам работы в облачной среде Google
Colab. Она содержит материал, знание которого необходимо для выполнения
всех приведенных примеров программного кода.
2.1. Общие сведения о платформе
Чтобы программировать на Python, используют набор программных инструментов, который носит название интегрированной среды разработки
(Integrated Development Environment, IDE). Таких сред разработки для языка
Python существует достаточно большое количество. Рассмотрим одну из них:
Google Colaboratory. Эта IDE отличается простотой настройки и удобством использования, чем обусловлена ее популярность в среде Python-программистов,
аналитиков данных и специалистов по машинному обучению.
Google Colaboratory (широко используется сокращение Colab) – облачная
платформа для разработки на языке Python от компании – технологического гиганта Google. К ее преимуществам можно отнести:
✓ бесплатность использования;
✓ отсутствие необходимости сложной и длительной настройки программного обеспечения на компьютере: для работы нужен лишь веб-браузер одной из последних версий (например, Google Chrome, Mozilla Firefox, Яндекс.Браузер) и доступ к интернету;
✓ большое количество предустановленных программных библиотек и
простота установки новых;
✓ возможность предоставлять доступ к написанным программам другим
интернет-пользователям.
2.2. Основы работы в Colab
Для работы в Colaboratory необходимо пройти по ссылке
https://colab.research.google.com/?hl=ru. Эту же ссылку легко получить, сделав запрос google colab в любой поисковой системе (Google, Яндекс и т.д.). Откроется
приветственная страница (рис. 8).
Для работы в Colab требуется наличие аккаунта Google (почтового ящика
в домене @gmail.com). Нажмем кнопку «Войти» и увидим стандартную страницу входа (рис. 9).

21

Рис. 8. Приветственная страница Google Colab

Рис. 9. Страница аутентификации Google

Следует ввести свои учетные данные либо зарегистрировать новый аккаунт, нажав на кнопку «Создать аккаунт». После аутентификации создадим новый
файл, в котором будем писать наши программы на Python, – он называется блокнот (рис. 10).

22

Рис. 10. Создание нового блокнота Colab

После этого откроется основное окно среды разработки Colab (рис. 11).

Рис. 11. Интерфейс блокнота

Изучим элементы интерфейса блокнота.
1. Название блокнота. Блокнот – это файл с расширением .ipynb, который
содержит код нашей программы и результаты его выполнения. Для удобства его
можно переименовать.
2. Основное меню. Пункт «Файл» позволяет создавать блокноты, открывать ранее созданные, скачивать их на локальный компьютер и т.п. Пункт «Среда
выполнения» позволяет управлять выполнением ячеек с программным кодом.
3. Кнопки добавления ячеек. Можно добавлять ячейки как с кодом, так и
с текстом (подробнее о типах ячеек ниже).
4. Основное рабочее поле с ячейками. Именно тут производится наполнение блокнота содержимым – программным кодом или форматированным текстом.
5. Кнопка «Поделиться». Она позволяет предоставлять доступ к блокноту
другим пользователям.
Следует отметить особенность IDE Colab, которая идет вразрез с концепцией модулей программного кода, традиционной для программирования. Дело в
23

том, что блокноты Colab состоят не только из программного кода. Обычный файл
с исходным кодом (модуль) выполняется при запуске целиком от первой до последней строки. Блокнот же состоит из ячеек двух видов: с кодом и с форматированным текстом. Ячейки с кодом являются аналогами модулей и выполняются
целиком, от начала до конца, при этом их в блокноте может быть несколько.
Ячейки с текстом позволяют вставлять в блокнот собственно текст, тем или
иным образом отформатированный, но не только: они могут включать также математические формулы (используется язык TeX) и изображения. Эта особенность позволяет использовать Colab не только как удобное средство разработки
программ на Python, но и как инструмент создания презентаций и прочих учебнометодических материалов. Интеграция с программным кодом и возможность его
выполнения здесь и сейчас раздвигает возможности преподавания и вкладывает
новые смыслы в понятие «интерактивный учебник».
Напишем первую простейшуюпрограмму на Python. При создании нового
блокнота одна ячейка с кодом в нем уже содержится. Также можно добавить новую ячейку, нажав на кнопку «+ Код». По принятой у программистов традиции
первая написанная программа выводит на экран фразу «Привет, мир!». Напишем
такую программу:
print("Привет, мир!")

Текст программы (ее исходный код) написан. Теперь следует его выполнить, для чего нажмем на кнопку с треугольником в кружке, которая появляется
в левой части ячейки при наведении на нее указателя мыши. В результате ячейка
будет запущена на выполнение – это означает, что написанный в ней код выполнится целиком, с первой до последней строки (так же, как выполняется код в
традиционных модулях). Результат выполнения ячейки приведен на рис. 12.

Рис. 12. Ячейка с кодом и результат ее выполнения

Зеленая галочка слева означает, что операция успешно выполнена. В области под ячейкой можно увидеть вывод программы на экран – в нашем случае это
строка приветствия миру.
Опишем еще одну особенность выполнения программ в среде Colab, обусловленную структурой блокнотов, состоящей из множества ячеек с кодом. В отличие от традиционных IDE, где данные, с которыми взаимодействует про-

24

грамма, размещаются в оперативной памяти и хранятся в ней только до окончания выполнения программы (после чего память очищается), блокнот имеет состояние, которое хранится и изменяется в течение всего срока работы с ним (пока
он не будет закрыт). Выполнение ячеек с кодом обновляет это состояние, при
этом оно хранится даже в моменты, когда никакой код фактически не выполняется.
Продемонстрируем описанную особенность на примере. Для этого добавим еще четыре ячейки, в каждую из которых поместим одну из строк следующего кода (на содержимое кода внимание пока можно не обращать).
newlist = [1, 2,
newlist[0] = 10
newlist[1] = 20
newlist[2] = 30

3] # создание списка из трех целых чисел
# перезапись первого элемента другим числом
# перезапись второго элемента другим числом
# перезапись третьего элемента другим числом

Также для демонстрации в конце каждой ячейки поместим вывод значения
объекта newlist на экран. (Со списками и другими сложными типами данных
мы познакомимся в дальнейшей части пособия, а пока что разбираемся с особенностями Colab.)
newlist = [1, 2, 3]
print(newlist)

# создание списка из трех целых чисел

1

newlist[0] = 10
print(newlist)

# перезапись первого элемента другим числом

2

newlist[1] = 20
print(newlist)

# перезапись второго элемента другим числом

3

newlist[2] = 30
print(newlist)

# перезапись третьего элемента другим числом

4

Выполним указанные ячейки в следующем порядке: 1, 3, 4, 2 (рис. 13).
Как можно заметить, список, созданный в ячейке 1, был помещен в память
(стал частью состояния блокнота), и последующие ячейки последовательно изменяли его содержимое, причем в том порядке, в каком они были выполнены.
Свой итоговый вид [10, 20, 30] список принял после выполнения ячейки 2, потому что оно было осуществлено последним. Порядок выполнения ячеек с кодом
может быть совершенно произвольным. Для большей наглядности изобразим эту
схему с помощью следующей иллюстрации (рис. 14).

25

Рис. 13. Результат выполнения ячеек в произвольном порядке

Рис. 14. Изменение состояния блокнота ячейками

Состояние блокнота (то есть значения переменных, используемых в программе) в каждый момент времени определяется результатами выполнения последней вызванной ячейки с кодом. Можно заметить, что после успешного выполнения ячейки справа от зеленой галочки появляется число в квадратных скобках. Это порядковый номер вызова ячейки. Первая выполненная в блокноте
ячейка получает номер 1, вторая – 2, двести восемьдесят шестая – 286, и т.д. Эта
нумерация позволяет определять порядок вызова ячеек и то, какая из них была
выполнена последней (ячейка с максимальным номером) и тем самым определила текущее состояние блокнота. Очень важно понимать этот механизм, чтобы
не столкнуться с неожиданными (но в действительности логичными и закономерными) результатами выполнения программы в Colab.
Также следует знать о том, что после закрытия блокнота вывод программ
в ячейках сохраняется. Но это не относится к состоянию блокнота: в случае бездействия пользователя оно хранится некоторое время, после чего сбрасывается,

26

все объекты в памяти исчезают. Выглядит блокнот в исходном состоянии следующим образом (рис. 15).

Рис. 15. Блокнот в исходном состоянии

Как можно заметить, зеленые галки и нумерация слева от ячеек пропали.
Сбросить состояние можно и вручную с помощью пункта меню «Перезапустить
сеанс» (рис. 16).

Рис. 16. Сброс состояния блокнота вручную

В правой части активной ячейки (той, в которой находится курсор и с которой происходит взаимодействие) отображается панель, позволяющая изменять
позицию ячейки (двигать вверх-вниз) и удалять ячейку (рис. 17).

27

Рис. 17. Панель управления ячейкой

Установка сторонних библиотек
Библиотеки функций – это наборы уже кем-то написанного программного
кода, позволяющего решать те или иные задачи. Программирование на 90 % состоит из использования готового кода, потому что абсолютное большинство решаемых программистом узких задач (таких как сортировка массива, вычисление
коэффициента корреляции или построение модели линейной регрессии методом
наименьших квадратов) уже было кем-то решено, причем, скорее всего, более
качественно, чем это смог бы сделать программист, решая такую задачу своими
силами впервые. Как уже было отмечено, Google Colab имеет большое количество предустановленных библиотек. Однако невозможно предустановить абсолютно все библиотеки (их очень много), поэтому в Colab предусмотрен механизм
установки сторонних библиотек. Осуществляется установка путем выполнения
в ячейке с кодом следующей команды:
!pip install

Попробуем установить библиотеку PyMorphy2, предназначенную для морфологического анализа текстов:
!pip install pymorphy2

Если после выполнения в ячейке появится зеленая галочка, значит, установка выполнилась успешно, теперь эту библиотеку можно подключить и использовать в своей программе.
Если затребованная библиотека уже установлена в Colab, система об этом
напишет, и ничего не произойдет.
Стоит отметить, что команда !pip не является инструкцией языка Python.
Pip – это специальная программа, которая позволяет управлять установкой библиотек (так называемый пакетный менеджер; пакет – это другое название библиотеки функций). Эта программа исполняется в облаке, то есть где-то на серверах Google. Чтобы вызывать такого рода системные программы, в Colab предусмотрен специальный механизм – написание команд с лидирующим символом
знака восклицания (!). Соответственно, работает этот механизм только в среде

28

Google Colab. В других IDE попытка выполнить подобную инструкцию внутри
программы на Python приведет к ошибке.
Также следует иметь в виду, что при очищении состояния блокнота установленные пользователем библиотеки удаляются. При следующем выполнении
программы их необходимо будет установить повторно.
Предоставление доступа к блокноту
Colab позволяет делиться собственными блокнотами с другими пользователями. Настроить совместный доступ к блокноту позволяет кнопка «Поделиться», открывающая соответствующее меню (рис. 18).

Рис. 18. Меню настройки совместного доступа

В меню настройки доступа можно либо предоставить доступ к блокноту
конкретным пользователям (добавив их почтовые адреса в список), либо открыть
доступ всем по ссылке. При этом можно выбрать одну из трех ролей: читатель,
комментатор и редактор. Читатель может только просматривать оригинальный
блокнот и создавать его копию, комментатор может оставлять комментарии, а
редактор может вносить в блокнот изменения.
Чтобы открыть общий доступ к блокноту на чтение по ссылке, следует выбрать пункт «Все, у кого есть ссылка» и указать роль «Читатель». Сформированную ссылку можно скопировать и распространить. Любой пользователь, имеющий данную ссылку, сможет просмотреть блокнот, причем даже без входа в аккаунт Google. А войдя в аккаунт, он сможет создать свою собственную копию
блокнота, выполнять и редактировать ее по своему усмотрению.
29

2.3. Задания для самостоятельной работы
Выполните следующие задания:
1. Войдите в Google Colab (при необходимости зарегистрируйте учетную
запись Google). Создайте новый блокнот.
2. Создайте ячейку с кодом, напишите в ней указанную команду и выполните ее.
print("Привет, мир! Я изучаю Python!")

3. Создайте ячейку с текстом. Поэкспериментируйте со следующими элементами, вставляя их в ячейку: обычный текст с различным форматированием
(полужирный, курсив), заголовки разного размера, маркированный и нумерованный списки, гиперссылка, изображение. Используйте палитру компонентов в
верхней части ячейки.
4. Настройте общий доступ к блокноту по ссылке с правами на чтение.
Убедитесь, что доступ открыт, пройдя по ссылке на блокнот с другого компьютера или телефона.

30

3. Синтаксис Python и основные конструкции программы
Данная глава посвящена первому практическому знакомству с языком Python, его базовым понятиям и написанию простейших программ.
3.1. Переменные
Данные, с которыми работает программа, хранятся в оперативной памяти.
Память состоит из ячеек, которые имеют свои адреса. Если дать ячейке памяти
какое-то имя и что-то в нее записать, появится переменная – поименованная область памяти, хранящая некоторое значение.
Создадим несколько переменных:
a = 15
perem = "Привет"
variable = [1, 2, 9]

После выполнения кода выше в оперативной памяти появятся поименованные ячейки с данными (рис. 19).

Рис. 19. Переменные в памяти

Можно провести аналогию с математическими переменными, содержащими некоторые числа. Переменная в программировании – это воплощение на
практике данного абстрактного понятия из математики.
Имя переменной программист выбирает сам. Приведем несколько правил
именования переменных в Python.
1. Имя переменной состоит из одного или нескольких слов на английском
языке, причем эти слова должны информировать программиста о содержимом
переменной. Примеры информативных имен: count, address_of_office,
date_of_birth.
2. Имя должно начинаться с маленькой буквы.
3. Имя не может начинаться с цифры.
4. Не может быть именем ключевое слово Python: интерпретатор не сможет правильно обработать такой код, потому что будет считать, что в программе
выполняется определенная стандартная команда, а не объявляется переменная.
31

Примеры ключевых слов: continue, raise, pass, def, return, while, True,
False. Ключевые слова, как правило, выделяются средой разработки цветом.
5. Регистр символов в имени имеет значение (data и dATa – разные переменные).
В различных языках программирования существуют договоренности о
стиле именования переменных в случае, когда имя состоит из нескольких слов.
В C-подобных языках (C++, C#, Java и некоторых других) принята так называемая верблюжья нотация (camel case): первое слово пишется с маленькой буквы,
а все последующие – с большой. Пример: newVariableInJava. В Python правилом хорошего тона является использование «змеиной нотации»: каждое слово в
имени переменной пишется с маленькой буквы, слова разделяются подчеркиванием. Пример: new_cool_variable.
3.2. Оператор присваивания
Оператор языка программирования – это специальный символ или ключевое слово, сообщающие транслятору о необходимости выполнения той или
иной операции с данными.
Фундаментальной и важнейшей операцией в программировании является
операция присваивания. Она позволяет помещать те или иные значения (данные) в переменные. На языке Python присваивание записывается так:
=

Выражением в программировании называется совокупность переменных,
литералов, знаков операций, имен функций, скобок, которая может быть вычислена в соответствии с синтаксисом языка программирования. Результатом вычисления выражения является значение – данные определенного типа. Другое
название значения (данных) – объект.
Литералом называется запись в исходном коде программы, представляющая собой фиксированное значение, которое можно ввести с клавиатуры.
Приведем несколько примеров использования оператора присваивания:
a = 5 # в переменную a помещается число 5
b = (a + 10) / a # в переменную b помещается значение выражения (a+10)/a

Если с первой командой все понятно, то вторая выполняется в два этапа:
сначала вычисляется значение выражения в правой части (a+10)/a, а затем оно
помещается в левую часть (переменную b).

32

Примеры выражений (записей, которые могут находиться в правой части
оператора присваивания):
3 # выражение состоит из одного числового значения 3, заданного литералом
(a + 10) / (b - a) # арифметическое выражение
round(a) # выражение, состоящее из вызова функции
(a + b) ** 2 + 1 / abs(b) # выражение, включающее переменные, литералы,
# знаки арифметических операций и вызов функции

При выполнении программы выражение выполняется в соответствии с
приоритетами операций, из которых оно состоит, и «превращается» в некоторое
результирующее значение того или иного типа (объект).
Множественное присваивание
В Python существует механизм присваивания одного значения нескольким
переменным сразу. Выглядит соответствующая конструкция так:
= = ... =

Например, нужно создать несколько переменных со значением 0. Код:
x = y = z = 0

В результате в памяти появятся три переменные: x, y, z, каждая равна 0.
3.3. Комментарии
Комментарии – это текстовые записи в программе, которые частью программы не являются и игнорируются транслятором при ее выполнении. Они поясняют те или иные фрагменты программного кода и нужны для того, чтобы
пользователь, читающий программу, разобрался, что она делает.
Однострочный комментарий обозначается символом #. Весь текст, расположенный после #, считается комментарием.
a = 1

# отступ - не менее 2 пробелов

Многострочные комментарии заключены в тройные кавычки (двойные
или одинарные): """...""". Следует отметить, что многострочных комментариев как отдельного элемента синтаксиса в Python не предусмотрено. С точки
зрения интерпретатора строка в тройных кавычках является строковым объектом (значением, данными). Ее можно поместить в переменную или как-то иначе
обработать. А можно использовать и в качестве комментария.

33

""" Эту строку можно
использовать как
многострочный комментарий """

Помимо поясняющей функции комментарии имеют функцию отладочную:
с их помощью можно «выключать» определенные фрагменты кода. Это может
быть полезно, когда написанный код не хочется удалять совсем, однако в данный
момент он в программе не требуется.
3.4. Типы данных
Каждое значение в памяти компьютера имеет строго определенный тип. От
типа данных зависит, как именно организовано хранение данных памяти и какие
операции с ними можно совершать.
Условно можно выделить следующие типы данных в программировании:
✓ простые (элементарные, скалярные);
✓ сложные (структурированные).
К простым типам данных будем относить следующие:
✓ число;
✓ строка;
✓ логическое (булево) значение.
Числа могут быть целыми (int), вещественными (float) и комплексными
(complex). Последние рассматривать в данном пособии не будем.
10 # целое положительное число, заданное литералом
-7 # целое отрицательное число, заданное литералом
10.75 # вещественное число, заданное литералом
3+05j # комплексное число, заданное литералом

Строка (str) – это последовательность символов2. Строковый литерал задается с помощью кавычек (двойных или одинарных).
"Это значение строкового типа"

# строка, заданная литералом

В действительности строковый тип относится к структурированным типам, потому что он не является элементарным (это последовательность отдельных элементов – символов). Однако, по мнению автора, на начальном
этапе изучения Python не следует слишком погружаться в нюансы, а строковый тип данных – один из первых,
с которым приходится столкнуться при написании программ. Ввиду этого пока будем считать его «простым».
2

34

Комбинирование кавычек разного типа позволяет включать символ кавычки в само содержимое строки. В этом случае включаемые кавычки должны
быть вида, отличного от вида внешних кавычек, задающих строковый литерал.
"Привет, 'мир'!"
'Привет, "мир"!'

# использование внутри строки одинарных кавычек
# использование внутри строки двойных кавычек

Булево (логическое) значение (bool) – это специальный тип данных, позволяющий использовать в программировании аппарат математической логики.
Булево значение определяет истинность или ложность высказывания и бывает
двух видов: истина (True) и ложь (False). Напомним, что регистр символов в
Python имеет значение: True является ключевым словом, а true – нет.
a = True # задание булева значения "Истина" литералом
b = False # задание булева значения "Ложь" литералом

Существует еще один элементарный тип данных – NoneType (пустой тип).
Значение этого типа может быть только одним: None. None означает, что какойто объект в памяти есть, но он не содержит никаких данных. Например, можно
создать переменную, выделить под нее ячейку памяти, но при этом никаких
осмысленных данных туда не записывать. В результате мы укажем, что переменная существует, но является пустой. Вновь не забудем о важности регистра (none
не литерал).
a = None

# создание пустой переменной

Существует способ узнать тип того или иного значения. Для этого служит
функция type()(рис. 20). О функциях – чуть ниже.

Рис. 20. Вывод типов данных нескольких значений

35

Преобразование типов
В процессе программирования часто приходится выполнять операции над
значениями разных типов (например, складывать строку и число). Как упоминалось выше, от типа данных зависит, какие операции можно выполнять с этими
данными. Строки можно складывать со строками, числа – с числами, но строки
с числами – нельзя. Однако иногда это необходимо, и вскоре мы столкнемся с
такими ситуациями. Ввиду этого требуется механизм преобразования данных
одного типа в данные другого типа. В Python преобразование типов осуществляется с помощью функций следующего вида:
()

Рассмотрим несколько примеров преобразования типов:
int("15") # преобразование строки в целое число, результат 15
float("-15.997") # строка в вещественное число, результат - 15.997

Строка, содержащая запись числа, преобразуется в значение числового
типа лишь в том случае, если эта запись соответствует литералу числа, иначе
произойдет ошибка выполнения. Так, 15 является корректным литералом типа
int, а -15.997 – корректным литералом типа float. При этом целочисленный
литерал может быть интерпретирован как float, потому что все его символы
(цифры и знак минус) допустимы для литерала этого типа и в математике множество вещественных чисел включает в себя множество целых.
float("15")
15.0

Однако не наоборот: литерал float не может быть интерпретирован как
целочисленный, он содержит недопустимые для типа int символы (точку).
int("-15.997")
...
ValueError: invalid literal for int() with base 10: '-15.997'

Значение float может быть преобразовано в значение int, при этом дробная часть отбрасывается (математически вещественные числа отличаются от целых наличием дробной части, а у int она отсутствует, ее негде хранить).
int(-15.997)

# вещественное число в целое, результат -15

36

Подчеркнем: дробная часть просто отбрасывается, округления не происходит (например, число 3,7 будет преобразовано в 3).
int(True)

# логическое значение в целое число, результат 1

В int могут быть преобразованы значения логического типа по следующему правилу: True → 1, False → 0. Функция float() тоже работает с bool, она
возвращает вещественные значения 1.0 и 0.0.
str(10)

# целое число в строку, результат "10"

Значение любого типа может быть преобразовано в строку. Результатом
такого преобразования является строковое представление этого значения. Для
простых типов оно совпадает с их литералами, значения же сложных типов
имеют свои собственные строковые представления. Преобразование в строку может быть осуществлено явно при вызове функции str(), а также неявно при попытке интерпретации значения как строкового. Последнее происходит при выводе значения на экран при помощи функции print(), а также при конструировании F-строк (об этом в параграфе 3.6).
Отдельным пунктом стоит упомянуть булификацию – преобразование значений любого типа в логическое значение. Эта процедура может выполняться
явно при вызове функции bool(), а также неявно при попытке интерпретации
значения как логического, когда в определенном месте программы (например, в
условии операторов if и while, см. главу 4) ожидается значение булева типа, но
оказывается значение иного типа.
Приведем общее правило булификации. Значение интерпретируется как истина (True) всегда, кроме следующих случаев:
✓ значение имеет числовой тип и равно 0;
✓ значение является пустой коллекцией, не содержащей элементов (см.
параграф 5.7);
✓ значение пустое (None).
bool(123) # ненулевое число: True
bool(0.0) # нулевое число любого типа: False
bool([1, 2, 3]) # непустая коллекция (список): True
bool(()) # пустая коллекция (кортеж): False
bool(None) # False

37

3.5. Функции
Функции – крайне важный элемент любого языка программирования. Все
программирование построено на работе с функциями.
Функция – это программа, вложенная в основную (родительскую) программу, то есть подпрограмма.
Любая программа является реализацией некоторого алгоритма. Алгоритм, в
свою очередь, имеет входные (исходные) и выходные (результирующие) данные.
Соответственно, функция также имеет входные и выходные данные (рис. 21).
𝑥1
𝑥2

𝑦 = 𝑓(𝑥1, 𝑥2 )

𝑦

Рис. 21. Схематичное изображение функции двух аргументов 𝑦 = 𝑓(𝑥1 , 𝑥2 )

Можно сказать, что функция – это фрагмент программного кода, который
при вызове выполняется весь целиком, от начала до конца. Этот код имеет имя,
принимает некоторые данные на вход, как-то их обрабатывает и возвращает некоторый результат.
Основное предназначение функций – избежать дублирования кода в программе при многократном выполнении одного и того же алгоритма с различными входными данными. Например, при вычислении коэффициента корреляции между двумя наборами чисел нужно выполнить достаточно много математических вычислений, и программа, которая это делает, займет не одну строку
кода. При этом в процессе корреляционного анализа часто необходимо вычислить не одно значение коэффициента, а несколько (для разных выборок). Входные данные будут отличаться, но алгоритм (методика вычислений) останется
неизменным. Нужно ли будет дублировать один и тот же код, чтобы несколько
раз вычислить коэффициент корреляции? Нет, если использовать функцию, которая это делает.
Функции бывают стандартные (уже готовые) и пользовательские. Пользовательские функции программист пишет сам, чтобы впоследствии использовать. Стандартные функции уже кем-то написаны (профессиональными разработчиками), и программист может их использовать в своей программе. Множество стандартных функций поставляется вместе с интерпретатором Python и доступно для использования программисту изначально.
Примеры стандартных функций – int() и round():
int("3") # функция преобразования строки в целое число
round(3.14159) # функция округления вещественного числа

38

Вызов функции:
(, , ...)

Входные данные функции представлены аргументами (входными параметрами) – значениями того или иного типа. В качестве аргументов используются выражения. Теоретически аргументов может быть неограниченное количество (а может не быть ни одного).
Выходные данные функции – это значение, которое является результатом
ее выполнения (то есть результатом выполнения алгоритма, который реализован
данной функцией). Говорят, что функция возвращает то или иное значение, поэтому выходные данные называют возвращаемым значением функции. Возвращаемое значение – это значение (объект) того или иного типа (простого или
сложного). Возвращаемое значение может быть максимум одно. Причем это не
является ограничением: не стоит забывать, что типы данных бывают сложные
(их значения состоят из нескольких элементов). Также бывают функции, которые вообще ничего не возвращают.
Зная, что выражения могут включать в себя вызов функций, не будем удивляться, встретив в программе каскадные (вложенные) вызовы функций (рис. 22).
𝑥1
𝑥2

𝑦

𝑦 = 𝑓1 (𝑥1 , 𝑥2 )
𝑥3

𝑧 = 𝑓2 (𝑦, 𝑥3 )

𝑧

Рис. 22. Схематичное изображение каскадного вызова функций

В коде такой каскадный вызов может выглядеть следующим образом. Будем считать, что переменные x1, x2, x3 и функции f1(), f2() в программе объявлены заранее и доступны для обращения.
z = f2(f1(x1, x2), x3)

Вызов таких вложенных друг в друга функций происходит «изнутри
наружу», начинается с самой глубоко вложенной функции. Очевидно, что
прежде, чем выполнится функция f2(), должно быть вычислено значение ее первого аргумента, а для этого должна быть выполнена функция f1(). Можно отметить, что значение, на рисунке обозначенное y, являющееся результатом выполнения функции f1(), не записывается ни в какую переменную, а сразу же посту-

39

пает на вход функции f2(). Стиль программирования, в котором активно используется такой «конвейерный» подход (результаты одних функций незамедлительно подаются на вход другим), называется функциональным.
3.6. Ввод-вывод данных
Любой алгоритм (а значит, и программа) имеет входные и выходные данные. Входные данные необходимо откуда-то получить.
Источники входных данных (способы ввода):
✓ явное задание в тексте программы через литералы;
✓ ручной ввод с клавиатуры (с консоли) во время выполнения программы;
✓ загрузка из файла на диске;
✓ загрузка по сети (например, из Интернета);
✓ другие (например, использование данных о текущей дате-времени).
Виды выходных данных (способы вывода):
✓ вывод на экран монитора (в консоль);
✓ сохранение в файл на диске;
✓ отправка по сети (например, отправка сообщения в мессенджере);
✓ вывод на печать (на принтер);
✓ другие.
Для ввода данных с клавиатуры в Python применяется функция input().
input()

Приглашение к вводу – это строковое значение, которое выводится в качестве запроса при вводе. Приглашение к вводу можно не задавать, в этом случае
в качестве него будет использована пустая строка, и пользователь, увидев мигающий курсор, должен будет сам догадаться, что программа ожидает от него
ввода с клавиатуры. Таким образом, функция input() является примером функции, которая может не иметь аргументов.
text = input("Введите ваше имя: ") # ввод строки с клавиатуры
# и сохранение ее в переменную text
Введите ваше имя: Святослав

Результат выполнения следующего кода будет полностью аналогичен
предыдущему:

40

invitation = "Введите ваше имя: "
text = input(invitation)
Введите ваше имя: Святослав

Здесь мы всего лишь поместили строку приглашения к вводу в переменную, которую затем использовали при вызове функции input(). Однако данный
случай – пример ситуации, когда нецелесообразно создавать отдельную переменную для хранения объекта. Тем не менее сделать так никем не запрещено.
Отметим важный нюанс: ввести с клавиатуры с помощью input() можно
только значение строкового типа. Даже набираемые на клавиатуре цифры будут сохранены в памяти как строка. Это значит, что для выполнения арифметических операций над числами, вводимыми с клавиатуры, необходимо преобразовать тип введенных значений из строкового в числовой.
# производится попытка преобразовать тип введенного с клавиатуры
# значения в целочисленный (int). Если введенная строка не содержит числа
# (состоит не только из цифр, точки и знака -), произойдет ошибка
number = int(input("Введите целое число: "))

Вывод на экран в Python реализуется при помощи функции print():
print(, , ..., ,
sep=, end=)

Входными данными этой функции помимо объектов, которые требуется
вывести на экран, являются строковые значения разделителя и строки, завершающей вывод.
Разделитель (значение аргумента функции sep) – это строка, которая подставится между выводимыми объектами (если их больше одного). По умолчанию
разделителем является пробел, то есть значения выводятся в строку через пробел.
Строка, завершающая вывод (значение аргумента функции end), – это
строка, которая добавится в конец последнего выводимого объекта. По умолчанию разделителем является символ переноса строки \n, то есть каждый вызов
функции print() выводит данные начиная с новой строки.
print("abc", 10, -99.9, sep=";", end="|")
print("Эта надпись выводится в той же строке, что и предыдущие 3 значения")
abc;10;-99.9|Эта надпись выводится в той же строке, что и предыдущие 3 значения

Внутри строки могут использоваться специальные символы:
\n – символ переноса строки.
\t – символ табуляции.
41

print("1-я строка\n2-я строка\n3-я строка\n\t4-я строка с отступом")
1-я строка
2-я строка
3-я строка
4-ая строка с отступом

В Colab возможен вывод значения на экран без функции print(). Это работает, когда значение находится в последней строке ячейки и никак не обрабатывается: не записывается в переменную с помощью оператора присваивания и
не подается на вход функции. То же самое происходит при работе с интерпретатором в интерактивном режиме: результат вычисления выражения (объект)
сразу же выводится на экран (см. рис. 7).
number = 1
text = "Текстовая строка"
text
'Текстовая строка'

Как можно заметить, объект в последней строке выводится на экран без
вызова специальной функции. Это работает только для последней строки. Если
ячейка содержит несколько строк с объектами, которые необходимо вывести,
применение функции print() обязательно (рис. 23).

Рис. 23. Вывод нескольких значений на экран в разных строках

Режимы обработки и конструирование строк
Строковые литералы могут обрабатываться интерпретатором по-разному в
зависимости от выбранного режима обработки, который задается с помощью
префиксов (специальных символов в начале литерала – перед открывающими кавычками): f, r, u, b (также F, R, U, B).
Интерполяция строк (F-строки) – это механизм, позволяющий внедрять
в строку (строковый литерал) значения выражений, не заботясь о преобразовании типов (оно происходит автоматически). F-строка имеет следующий вид:
f"текст... {} текст..."

42

Префикс f включает возможность использования фигурных скобок как
элементов синтаксиса языка. В эти скобки, расположенные внутри строкового
литерала, помещаются выражения, результаты вычисления которых внедряются
в строку.
Moscow_age = 874 # значение типа int
Perm_age = 298 # значение типа int
# конструирование строки с помощью соединения нескольких подстрок
text1 = "Москве " + str(Moscow_age) +" лет, а Перми " + str(Perm_age) + " лет"
# конструирование строки с помощью интерполяции
text2 = f"Москве {Moscow_age} лет, а Перми {Perm_age} лет"
print(text1) #
print(text2) #
Москве 874 лет,
Москве 874 лет,

вывод строки, сконструированной соединением подстрок
вывод строки, сконструированной интерполяцией
а Перми 298 лет
а Перми 298 лет

Внутри выражений в фигурных скобках могут быть и строковые литералы,
в этом случае кавычки внешней и внедряемых строк должны быть разного вида:
print(f"Москва {'старше'} Перми на {abs(Moscow_age - Perm_age)} лет")
print(f'Москва {"старше"} Перми на {abs(Moscow_age - Perm_age)} лет')
Москва старше Перми на 576 лет
Москва старше Перми на 576 лет

R-строка (raw-строка) – строковый литерал, который обрабатывается
«как есть», без поиска в нем специальных символов.
# F-строка
print(f"Москве {Moscow_age} лет, а\nПерми\t{Perm_age} лет")
Москве 874 лет, а
Перми
298 лет
# R-строка
print(r"Москве {Moscow_age} лет, а\nПерми\t{Perm_age} лет")
Москве {Moscow_age} лет, а\nПерми\t{Perm_age} лет

Префиксы можно комбинировать:
# интерполяция сработает (благодаря f), а табуляция нет (из-за r)
print(fr"{2}x{2}\t=\t{2 * 2}")
2x2\t=\t4

Косая черта \ является экранирующим символом в строках. С помощью нее
задаются специальные символы табуляции и переноса строки, также она может
использоваться, например, для включения внутрь строкового литерала кавычек
того же типа, что и внешние кавычки.

43

print("Привет, \"мир\"!")
Привет, "мир"!

# еще один способ включить кавычки в строку

Напишем простую программу, которая запрашивает анкетные сведения о
пользователе и красиво выводит их на экран:
name = input("Как вас зовут? ") # ввод имени
age = input("Сколько вам лет? ") # ввод возраста
city = input("В каком городе вы живете? ") # ввод города
print() # вывод пустой строки (чтобы отделить ввод от вывода)
print("=== ДАННЫЕ ОБ ОБЪЕКТЕ ===") # вывод заголовка анкеты
print("Имя:", name) # вывод имени
print(f"Возраст: {age}") # вывод возраста
print(f"Место постоянной дислокации: {city}") # вывод города
print("Статус: вооружен и опасен") # вывод строковой константы
print("=========================") # вывод линии для красоты
Как вас зовут? Ипполит
Сколько вам лет? 25
В каком городе вы живете? Петушки
=== ДАННЫЕ ОБ ОБЪЕКТЕ ===
Имя: Ипполит
Возраст: 25
Место постоянной дислокации: Петушки
Статус: вооружен и опасен
=========================

3.7. Математические вычисления
Как уже было сказано, в зависимости от типа со значением можно производить различные операции. Рассмотрим операции над числами (арифметические). Основные арифметические операции в Python приведены в табл. 2.
Таблица 2
Математические операции в Python
Тип операции
Сложение
Вычитание
Умножение
Деление без
остатка
Остаток от
деления

Оператор
Тип результата
+
Если оба операнда int, то результат
int, иначе float
Если оба операнда int, то результат
int, иначе float
*
Если оба операнда int, то результат
int, иначе float
//
Если оба операнда int, то результат
int, иначе float
%
Если оба операнда int, то результат
int, иначе float

Вещественное
деление

/

Возведение в
степень

**

float (результат – всегда вещественное

число, даже если математически частное является целым)
Если оба операнда int, то результат
int, иначе float
44

Пример
2 + 3.5
2 - 3

# 5.5

# -1

2 * 3.5

# 7.0

7 // 3 # 2
7 // 3.6 # 1.0
7
7
7
6

%
%
%
/

3 #
3.6
3.5
2 #

3 ** 2

1
# 3.4
# 0.0
3.0

# 9

Не будет лишним пояснить принцип действия операций // и %. Вещественное деление / работает как обычное деление в математике, и его результат совпадает с тем, который мы интуитивно ожидаем получить (за исключением того
нюанса, что результат всегда вещественный). Результатом же деления без
остатка является число, равное тому, сколько раз делитель помещается в делимом целиком. Например, 3,6 целиком помещается в 7 только один раз, поэтому
результатом выражения 7 // 3.6 является единица (причем типа float, потому
что второй операнд вещественный). Фактически результат деления без остатка
равен результату вещественного деления с обнуленной (или отброшенной совсем в случае целочисленных операндов) дробной частью. Результатом операции
получения остатка от деления является собственно остаток – число, которое получится, если из делимого вычесть результат деления без остатка. Например, 3,6
целиком помещается в 7 один раз, остается 3,4, а 3,5 помещается в 7 дважды,
остаток 0. Удобнее всего использовать операции // и % с целыми числами, ведь
из школьного курса математики мы точно знаем, что 7 на 3 делится с остатком,
результатом будет 2, а остаток равен 1.
Как нам уже известно, выражение вычисляется не разом, а поэтапно в соответствии с приоритетами операций, из которых оно состоит. Перечислим приоритеты математических операций в составе выражения:
1. Операции в скобках.
2. Вызов функций.
3. Возведение в степень.
4. Взятие числа с противоположным знаком (-).
5. Умножение, деление, остаток от деления.
6. Сложение, вычитание.
Если операции, имеющие равный приоритет, расположены в выражении
подряд, они выполняются по порядку слева направо. Такие операции называются
левоассоциативными.
# сложение и вычитание - левоассоциативные операции
5 - 8 + 14 # сначала вычислится 5 - 8 (будет -3), потом -3 + 14
11

Однако есть исключение: операция возведения в степень является правоассоциативной и выполняется справа налево. Данная логика продиктована ма𝑧
тематикой: в выражении 𝑥 𝑦 сначала вычисляется именно 𝑦 𝑧 , а уже затем 𝑥 возводится в степень – результат первого шага.

45

# возведение в степень - правоассоциативная операция
2 ** 4 ** 1 # сначала вычислится 4 ** 1 (будет 4), потом 2 ** 4
16

Рассмотрим пример вычисления сложного арифметического выражения
𝑥+

𝑦=

𝑎+𝑏𝑥+𝑥 2 −3
3

ln(√𝑥+1− √𝑥)

import math
#
#
a
b
x

𝑎
3

.

# подключим библиотеку с математическими функциями

прежде чем обращаться к переменным, надо задать им какое-то значение
введем значения переменных с клавиатуры, преобразуя в тип float
= float(input("Введите переменную a: "))
= float(input("Введите переменную b: "))
= float(input("Введите переменную x: "))

# длинные команды можно переносить на новую строку с помощью символа \ в конце
y = (a + b * x + x ** 2 - 3 ** (x + a / 3)) / \
math.log(math.sqrt(x + 1) - x ** (1 / 3))
y

# выведем результат вычислений (значение y) на экран

Выполним эту программу, подставив в качестве значений 𝑎 = 2, 𝑏 = −3,
𝑥 = 0,5, и убедимся, что ответ получился 3.3899710923743247.
Запись выражения, вычисляющего y, получилась довольно-таки устрашающей. Разберемся, как происходит вычисление (рис. 24).

Рис. 24. Порядок выполнения операций при вычислении выражения

Итак, в выражении есть дробь, то есть деление. Поскольку синтаксис языка
программирования ограничен символами, которые можно ввести с клавиатуры,
математическую формулу любой сложности приходится записывать в одну
строку теми средствами, какие есть. Сначала должно выполниться вычисление
выражения в числителе, затем в знаменателе, а потом должно произойти деление
числителя на знаменатель. В числителе сложное выражение, поэтому возьмем
𝑎

его в скобки. Показатель степени выражения 3𝑥+3 тоже является сложным, поэтому и его следует взять в скобки. Очевидно, что вычисление начнется отсюда.
Приведем последовательность вычислений с комментариями (табл. 3, 4). Серым
цветом выделены операнды – значения, участвующие в вычислении операции
текущего шага.

46

Таблица 3
Вычисление сложного математического выражения (числитель)
Шаг
Операция
a / 3
1
x + a / 3
2
x ** 2
3
4
5
6
7
8

3
b
a
a
a
3

** (x
* x
+ b *
+ b *
+ b *
** (x

+ a / 3)
x
x + x ** 2
x + x ** 2 + a / 3)

Результат
0.6667…
1.1667…
0.25
3.6028…
-1.5
0.5
0.75
-2.8528…

Комментарий
Приоритет деления выше, чем сложения.
После скобок самая приоритетная операция – возведение в степень.
Затем идет умножение.
И только потом – сложение…
…и вычитание.

После шага 8 вычисление числителя завершено, результатом его является
некоторое значение числового вещественного типа. Переходим к знаменателю
(см. табл. 4).
Таблица 4
Вычисление сложного математического выражения (знаменатель)
Шаг
9
10
11
12
13
14

Операция

Результат
x + 1
1.5
math.sqrt(x + 1)
1.2247…
1 / 3
0.3333…
x ** (1 / 3)
0.7937…
math.sqrt(x + 1) - x ** (1 / 3)
0.4310…
math.log(math.sqrt(x + 1) - x ** (1 / 3)) -0.8415…

Здесь производится расчет натурального логарифма, для чего применяется
функция log() из библиотеки math. О подключаемых функциях поговорим чуть
ниже, а пока просто вспомним, что вызов функций в составе выражения имеет
наивысший приоритет (после скобок, хотя автору не приходит в голову пример
выражения, в котором операция в скобках и вызов функции конкурировали бы
между собой за первое место в очереди выполнения). Чтобы вычислить результат выполнения функции, нужно получить значение ее аргумента, которым (ар3
гументом) является выражение √𝑥 + 1 − √𝑥 . Обратимся к нему. Для извлечения
квадратного корня в библиотеке math заготовлена функция sqrt(). Однако для
извлечения корня произвольной степени готовой функции там нет, поэтому для
3
решения данной проблемы следует вспомнить математику и тот факт, что √𝑥 =
1

𝑥 3 . Можно спросить: для чего дробь 1⁄3 записывать как отдельную операцию в
скобках? Дело в том, что это дробное число иррационально, обладает бесконечной дробной частью, и в тексте программы его невозможно записать точно.
47

Скобки же необходимы для того, чтобы сначала выполнилось деление и только
затем возведение в степень (которое имеет более высокий приоритет).
Последней, пятнадцатой по счету, операцией выполнится деление числителя (значения, полученного по итогам операции 8) на знаменатель (значение,
полученное по итогам операции 14). И, конечно, результат этого деления (объект
– значение вещественного типа 3.3899710923743247) будет записан в переменную y, что можно считать шестнадцатой операцией в рассмотренной нами комплексной команде (инструкции) программы.
Комбинированное (составное) присваивание
Зачастую в программировании результат выполнения математической операции записывается в переменную, являющуюся одним из операндов. Типичные
сценарии, в которых применяется такой подход (организация счетчиков и «копилок»), описаны в разделе про циклы (см. параграф 4.3), а пока разберемся с
механизмом комбинированного присваивания.
Предположим, нужно вычислить сумму значений двух переменных и записать результат в первую переменную:
a = 3
b = 5
a = a + b # значение выражения a + b запишем в переменную a
a # убедимся, что a = 8
8

В случае присваивания сначала вычисляется выражение в правой части,
затем результат записывается в переменную в левой части. Так и здесь: сначала
вычисляется a + b, при этом переменная a хранит ранее записанное значение 3,
оно и используется в вычислениях, и только после этого a перезаписывается новым значением 8. Очевидно, что на момент выполнения команды переменная a
должна существовать и что-то хранить. Существует специальная версия оператора присваивания для случаев, когда результат операции помещается в переменную – левый операнд:
a += b

# результат аналогичен выражению a = a + b, только запись короче

Синтаксис комбинированного присваивания выглядит так:
=

Приведем несколько примеров:

48

a -= 1 # a = a - 1
a /= b ** 2 # a = a / b ** 2
a **= (b + 1) * 5 # a = a ** ((b + 1) * 5)

В последнем примере следует обратить внимание на приоритеты: сначала
вычисляется значение выражения – правого операнда (b + 1) * 5, только потом
осуществляется возведение левого операнда в степень. Если бы данная команда
была записана с помощью обычного оператораприсваивания, а не составного,
вычисление показателя степени было бы необходимо взять в скобки (ведь у операции ** более высокий приоритет, чем у операции *).
3.8. Подключение функций из библиотек
Существует многообразие подключаемых библиотек готовых функций на
все случаи жизни (с понятием «библиотека» мы уже сталкивались ранее и даже
рассматривали их установку в главе 2). Одной из библиотек, доступных программисту изначально, является math – библиотека с функциями для математических
вычислений.
Подключение уже установленной в системе библиотеки осуществляется с
помощью ключевого слова import, после которого через запятую перечисляются
модули (один или больше):
import , , ...

Что такое модуль? Мы уже упоминали, что это файл с исходным кодом,
содержащий описание функций. Можно было бы не разделять понятия библиотеки и модуля, использовать эти термины как синонимы (зачастую это оправданно), если бы не тот факт, что название библиотеки, под которым она опубликована в репозитории, не всегда совпадает с именем ее файла-модуля. Примером
подобной библиотеки является BeautifulSoup: модуль ее актуальной (на дату
написания этого материала) версии называется bs4. Кроме того, нередко объемные сложные библиотеки состоят из нескольких модулей, имеющих разные
названия.
Ключевое слово as позволяет задавать подключаемому модулю псевдоним, по которому к нему можно обращаться в тексте программы. Это удобно,
если название модуля слишком длинное и сложное.
import math # подключение библиотеки math
import math as mt # использование псевдонима

Для обращения к функции из подключаемой библиотеки используется следующий синтаксис:
49

.
math.sqrt(144) # вызовем функцию sqrt() для вычисления корня из 144
mt.sqrt(144) # вызовем ту же функцию, обратившись по псевдониму

Возможно подключение не модуля целиком, а только определенных функций из него. Для этого служит синтаксическая конструкция from … import:
from import , , ...

В этом случае в пространстве имен программы (это область, в которой
перечислены названия всех объектов программы в памяти, доступных для обращения) появятся имена подключенных функций, и для их вызова не понадобится
указывать родительский модуль через точку.
from math import sqrt, floor, ceil # подключим несколько функций
x = sqrt(16) # извлечение квадратного корня
y = floor(123.45) # округление вниз
z = ceil(123.45) # округление вверх

Вместо перечисления функций можно подставить значок звездочки *, это
добавит в пространство имен все функции, содержащиеся в модуле:
from math import *

Однако злоупотреблять данной возможностью не следует, потому что
среди подключенных функций могут быть функции с именами, совпадающими
с именами уже существующих в памяти объектов. Ошибки при этом не возникнет, но может возникнуть путаница: при обращении к объекту по имени будет
осуществляться доступ к тому объекту, какой был добавлен в пространство имен
последним. Продемонстрируем это правило на примере:
sqrt = 3 # объявим переменную sqrt
from math import * # подключим все функции из math, в том числе и sqrt()
sqrt(9) # попробуем вызвать функцию sqrt
3.0

Несмотря на то, что сначала в программе была объявлена переменная sqrt,
позже данное имя было переиспользовано для стандартной функции
math.sqrt(). А вот обратный случай:
from math import * # подключим все функции из math, в том числе и sqrt()
sqrt = 3 # объявим переменную sqrt
sqrt(9) # попробуем вызвать функцию sqrt

50

...
----> 3 sqrt(9)

# попробуем вызвать функцию sqrt

TypeError: 'int' object is not callable

В строке с попыткой вызова функции sqrt() произошла ошибка, потому
что после подключения этой функции в программе была создана переменная,
«присвоившая» себе имя sqrt, а переменная функцией не является, вызвать ее
для выполнения нельзя, о чем и сообщает интерпретатор в описании ошибки.
Таким образом, использовать значок * при подключении всех функций модуля следует лишь тогда, когда нет сомнений, что эти функции имеют длинные
специфические названия, которые уж точно не будут нами использованы в качестве имен переменных, а также не встречаются среди подключаемых в программе функций из других модулей.
Помимо функций в библиотеках могут встречаться и переменные (правильнее называть их константами, ведь их значение заранее прописано в модуле и не меняется в процессе выполнения программы). Например, в модуле math
содержится несколько математических констант:
math.inf # плюс бесконечность
-math.inf # минус бесконечность (полученная путем добавления -)
math.pi # число Пи (3.14...)
math.e # экспонента (2.71...)

Полный перечень функций и констант в том или ином модуле можно получить, изучив документацию по библиотеке (документация math доступна по
ссылке [8]), а также вызвав список доступных для обращения объектов, поставив
точку после названия модуля и чуть подождав (рис. 25). Этот список не входит
на экран целиком, однако его можно проматывать вниз-верх.

Рис. 25. Всплывающий список функций и констант модуля math в Colab

51

3.9. Операции сравнения чисел
Часто в программировании возникает необходимость сравнения нескольких значений между собой. Забегая вперед, отметим, что операции сравнения
определены не только для чисел, но о сравнении объектов других типов поговорим в следующих главах. В Python существуют следующие операторы сравнения
(таблица 5):
Таблица 5
Операторы сравнения в Python
Тип операции
Проверка равенства
Проверка неравенства
Проверка того, что левый операнд строго больше
Проверка того, что левый операнд нестрого больше
Проверка того, что левый операнд строго меньше
Проверка того, что левый операнд нестрого меньше

Оператор
==
!=
>
>=
<
9 # False
>= 9 # False
< 9 # True
на конкретную строку с командой, при выполнении которой произошла ошибка. Также выводится тип и описание ошибки, при этом описание более информативно, чем просто «некорректный синтаксис». Так, в примере выше ошибка произошла при выполнении функции int() и была вызвана
К так называемому синему экрану смерти в операционной системе Windows приводят критические ошибки,
возникающие при работе системных программ. Такие ошибки обычно сигнализируют о проблемах с оборудованием компьютера, препятствующих его дальнейшей нормальной работе, и необходимости перезагрузки. Получить такой эффект в обычной прикладной программе на Python не очень просто; тем не менее подобные ошибки
можно отнести к классу ошибок выполнения.
3

58

передачей в функцию входного строкового значения, которое невозможно интерпретировать как целое число. Конечно, предвидеть заранее, что пользователь
программы введет с клавиатуры некорректное значение, не удастся.
Перечислим некоторые типы ошибок выполнения и ситуации, в которых
они возникают. За полным перечнем стандартных исключений в Python можно
обратиться к документации языка.
TypeError: операция применена к объекту несоответствующего типа. Не забудем: тип данных строго определяет, какие операции можно выполнять со значениями этого типа.
"Мне " + 19 + "лет" # попытка сложить строку и число
...
TypeError: can only concatenate str (not "int") to str

ValueError: функция получает аргумент правильного типа, но некорректного значения. Такая ситуация типична при использовании математических
функций: значение аргумента может выходить за пределы области определения
данной функции.
import math
math.sqrt(-4) # попытка извлечь квадратный корень из отрицательного числа
# причем та же операция командой (-4) ** 0.5 сработает,
# результатом будет комплексное число (complex)
...
ValueError: math domain error

ZeroDivisionError: деление на ноль. Такая ошибка может возникнуть при
использовании всех видов деления: вещественного /, без остатка //, а также получения остатка от деления %.
5 / 0 # попытка поделить на ноль
...
ZeroDivisionError: division by zero

NameError: не обнаружена переменная (или функция) с указанным именем.
Прежде чем обращаться к объекту по имени, объект с таким именем нужно в
программе объявить (например, создать переменную или подключить функцию
из библиотеки).
age = 19 # создали переменную age,
print(Age) # но вывести на экран пытаемся Age (регистр символов важен)
...
NameError: name 'Age' is not defined

59

IndexError: индекс за границами диапазона. Такая ошибка часто происходит при работе с индексированными коллекциями (см. главу 5): например, при
попытке обратиться к пятнадцатому элементу списка, в котором элементов всего
десять.
KeyError: несуществующий ключ. Эта ошибка часто происходит при работе со словарями (см. параграф 10.2) в случае обращения к элементу с ключом,
которого в словаре нет.
Обработка исключений
Алгоритм обладает свойством массовости, он способен решать задачу при
множестве различающихся входных данных. Из этого следует практическая невозможность предусмотреть и заранее определить все данные, которые могут
оказаться на входе (например, множество чисел бесконечно). А значит, простор
для возникновения ошибок выполнения очень широк: на вход программе (особенно сложной и объемной, каковыми в той или иной степени являются все программы, имеющие практическую полезность) может попасть «что угодно».
Чтобы свести количество ошибок выполнения к минимуму, программу тщательно тестируют на различных наборах входных данных. Однако исключить абсолютно все ошибки возможно далеко не всегда. В языках программирования и
в Python в частности эта особенность реального мира предусмотрена. Существуют специальные средства, позволяющие обрабатывать исключительные ситуации так, чтобы они не приводили к нештатному завершению программы.
За обработку ошибок в Python отвечает оператор try, который записывается в виде следующей конструкции:
try:
"рискованный" участок кода
except :
реакция на ошибку типа 1
except :
реакция на ошибку типа 2
...
else:
код, который выполнится, если ошибок не было
finally:
код, который выполнится в конце всей конструкции безусловно

«Рискованный» участок кода в блоке try содержит команды, во время выполнения которых возможно возникновение ошибок. Блоки except, которых может быть несколько, содержат код – реакцию на возникновение ошибки указанного типа. При этом тип ошибки может быть не указан вовсе: в этом случае будут
перехватываться все возможные ошибки. В блок else помещается код, который
выполнится в случае отсутствия ошибок при выполнении кода в блоке try, а

60

блок finally содержит код, который выполнится после обработки ошибок всегда – даже если ошибок выполнения не было. (О блоках кода, выделяемых отступами, поговорим подробнее в параграфе 4.2.)
В своем минимальном виде конструкция try выглядит так:
try:
result = 10 / 0 # на ноль делить нельзя, здесь всегда будет ошибка
except:
print("Произошла ошибка!")
Произошла ошибка!

Как можно заметить, исключительная ситуация возникла (потому что в
блоке try всегда будет происходить деление на ноль: делитель задан константой,
а не переменной), однако программа не «сломалась», просто вывелось сообщение об ошибке, то есть выполнился код в блоке except. Рассмотрим пример использования полной конструкции try:
from math import asin

# функция, вычисляющая арксинус

x = int(input("Введите целое число: "))
try:
result = asin(10 / x)
except ZeroDivisionError:
print("Ошибка: деление на ноль!")
except ValueError:
print("Ошибка: некорректное значение аргумента функции!")
else:
print("Ошибок не было")
finally:
print("Обработка \"рискованного\" кода завершена")
Введите целое число: 0
Ошибка: деление на ноль!
Обработка "рискованного" кода завершена

В данном случае к ошибке вновь привело деление на ноль, обусловленное
вводом 0 в качестве делителя с клавиатуры. При этом выполнился блок except,
перехватывающий ошибку ZeroDivisionError. Код в блоке finally также выполнился в конце.
Взглянем на вывод той же программы при других введенных значениях
переменной x:
Введите целое число: 1
Ошибка: некорректное значение аргумента функции!
Обработка "рискованного" кода завершена

При вводе 1 ошибка произошла уже не при делении, а при выполнении
функции asin(): значение 10.0, являющееся результатом деления 10 / 1, не

61

попадает в область определения арксинуса, и выполнился блок кода, перехватывающий ошибку ValueError.
Если же ввести такое значение x, при котором ошибки в коде блока try не
произойдет вовсе, выполнятся блоки else и, конечно, finally, результат будет
следующим:
Введите целое число: 15
Ошибок не было
Обработка "рискованного" кода завершена

Оператор try позволяет значительно повысить отказоустойчивость программы, снизить количество ошибок выполнения при ее работе, однако злоупотреблять им не следует. Если в программе произошла действительно важная
ошибка, из-за которой дальнейшее корректное выполнение алгоритма невозможно (например, не создалась нужная переменная или того хуже – в переменную не записалось нужное значение), нельзя просто подавить это исключение и
позволить программе работать дальше как ни в чем не бывало: к благоприятным
последствиям это не приведет. Некоторую осмысленную обработку исключения
сделать необходимо: так, в ряде ситуаций допустимым может быть задание подходящего значения переменной, которое не нарушит дальнейшую работу алгоритма, при обработке ошибки в блоке except. Еще одним вопиющим проявлением небрежности является объявление всего кода программы потенциально
рискованным и помещение его целиком в блок try. Такое применение данного
инструмента в большинстве случаев является бесполезным, потому что нельзя
всю программу считать нашпигованной ошибками (в конце концов, надо писать
хорошие программы, тщательно их тестировать), следует точечно обрабатывать
отдельные небольшие участки кода и прописывать адекватную реакцию на возможные при их выполнении специфические ошибки.
3.12. Задания для самостоятельной работы
Решите следующие задачи:
1. Напишите программу, которая запрашивает имя пользователя и выводит
следующую строку:
Приветствую тебя, о ""!

2. Напишите программу, которая запрашивает сведения о пользователе
(имя, возраст, возраст сестры, название родного города) и выводит их на экран в
следующем виде. Учитывать направление разницы в возрасте (старше или

62

младше) не требуется: расчет следует вести исходя из предпосылки старшинства
сестры.
=== АНКЕТА ===
Имя:
Возраст:
Сестра старше на лет
Родной город:
==============

3. Введите с клавиатуры два целых числа. Вычислите и выведите на экран
их сумму, разность, произведение, результат вещественного деления первого
числа на второе, результат деления без остатка первого числа на 10, результат
получения остатка от деления второго числа на 10. Используйте приглашения к
вводу (чтобы пользователь понимал, чего ждет от него программа). Проверяйте
корректность ввода с помощью оператора try.

63

4. Условия и циклы
В этой главе описываются фундаментальные алгоритмические конструкции, без которых не обходится практически ни одна программа.
4.1. Основные алгоритмические структуры
Алгоритм может быть линейным, когда все его шаги (команды) выполняются строго друг за другом. Примером может быть алгоритм, вычисляющий значение математического выражения. На рис. 29 представлен такой алгоритм в
виде блок-схемы (это один из способов графического представления алгоритма).
Начало

Ввод n

n = int(input("Введите n: "))
x = 10 * n + 3
print(x)

x = 10*n + 3

Вывод x

Конец

б

а

Рис. 29. Блок-схема (а) и программная реализация на Python (б) линейного алгоритма,
вычисляющего значение выражения 10𝑛 + 3

Строго линейными от начала до конца бывают только простейшие, самые
примитивные алгоритмы. Как правило, алгоритм решения какой-либо практической задачи имеет более сложную структуру, включающую помимо линейных
участков кода еще ветвления и циклы.
Всего существует три основных алгоритмических структуры:
1. Линейное выполнение. Шаги алгоритма выполняются последовательно
друг за другом.
2. Ветвление. В зависимости от истинности некоторого условия выполняется тот или иной набор команд алгоритма.
3. Цикл. Один и тот же фрагмент алгоритма выполняется несколько раз
подряд.
Две последние рассмотрим подробно.

64

4.2. Условный оператор if
Ветвление – это развилка в алгоритме: можно пойти одним путем (выполнить одну последовательность шагов), а можно другим (выполнить другую последовательность шагов). Одновременно эти два пути не могут быть пройдены
за один проход по алгоритму, они взаимоисключающие: в зависимости от выполнения некоторого условия идем либо сюда, либо туда.
В качестве примера ветвления рассмотрим фрагмент алгоритма получения
второго высшего образования (рис. 30).

В каком пермском вузе есть
направление «Программная
инженерия» с вечерней
формой обучения?

в ПГНИУ

Поступить в
ПГНИУ

в НИУ ВШЭ

Поступить в
НИУ ВШЭ

Хорошо учиться

Окончить с отличием

Устроиться
разработчиком
в Яндекс

Рис. 30. Блок-схема алгоритма с ветвлением

Проверка условия должна представлять собой некоторый вопрос, ответами
на который являются либо «да» / «нет», либо какие-то варианты дальнейших действий. Как правило, в программировании вопрос сформулирован с вариантами ответов «да» / «нет», то есть ветвление двоичное (развилка на два пути) (рис. 31).

да

Сданы ли вступительные
экзамены в МГУ?

Рис. 31. Двоичное ветвление
65

нет

Чтобы организовать множественное ветвление (развилку на несколько путей), можно использовать вложенные друг в друга двоичные ветвления (рис. 32).

да

нет

Сданы ли вступительные
экзамены в МГУ?

да

Сданы ли вступительные
экзамены в ПТУ?

нет

Рис. 32. Множественное ветвление (развилка на три пути)

Реализовать такую развилку с выбором в Python помогает условный оператор if:
if :
команды первого блока кода (выполнятся, если истинно условие 1)
elif :
команды второго блока кода (выполнятся, если истинно условие 2)
elif :
команды третьего блока кода (выполнятся, если истинно условие 3)
...
else:
команды блока кода, которые выполнятся при ложности всех условий

Условие – это выражение, результат вычисления которого имеет логический тип (bool) либо может быть интерпретирован как значение логического
типа (вспомним механизм булификации, см. параграф 3.4). Ключевые слова elif
и else в команде могут отсутствовать. Приведем пример простейшей команды с
условным оператором:
age = 15
if age < 18:
print("Вы несовершеннолетний, спиртного не продадим!")
Вы несовершеннолетний, спиртного не продадим!

Значение выражения age < 18 равно True, потому что в переменной age
содержится число 15. Как следствие этого, условие выполняется, и команда
print() выводит сообщение на экран. При age ≥ 18 команды блока бы не выполнились и ничего не вывелось.
Сделаем небольшое отступление и разберемся с понятием блок кода. Мы
уже сталкивались с ним, изучая оператор try (см. параграф 3.11). Блок кода –
это фрагмент программы, который начинается с двоеточия, а все его команды
66

отделяются отступами. Вспомним один из пунктов стандарта PEP8: «для выделения блоков кода следует использовать отступы из четырех пробелов» (см. параграф 1.2). Здесь речь как раз идет о блоках кода, которые в программировании
на Python встречаются постоянно (рис. 33).

Рис. 33. Блок кода внутри условного оператора

Отметим, что в Google Colab после двоеточия при переходе на новую
строку (клавиша Enter) отступы проставляются автоматически, и при этом используется не четыре пробела, как рекомендовано, а два. Количество пробелов,
составляющих отступ, может быть произвольным: главное, чтобы все отступы
одного блока кода имели одно и то же количество пробелов. В противном случае программа не запустится из-за ошибок синтаксиса (рис. 34).

Рис. 34. Нарушение одинаковой длины отступов в одном блоке кода

Команды основной программы никаких отступов не имеют, это верхний,
первый уровень кода. Блок кода внутри основной программы образует второй
уровень кода, а блок кода внутри второго уровня – третий уровень кода. И таких
вложенных друг в друга блоков может быть множество, при этом выстраивается
наглядная иерархическая структура.
if age < 18:
print("Вы несовершеннолетний, спиртного не продадим!")
if age > 16:
print("Хоть Вам и больше 16, все равно не продадим!")

Вспомним, что в качестве одного из преимуществ языка Python мы приводили следующее: красивый и понятный код программ. Структурирование кода с
помощью отступов, будучи неотъемлемой особенностью синтаксиса языка (в
силу чего не поддается игнорированию программистом при всем его гипотетическом желании), относится, по мнению автора, к аргументам в пользу выдвину-

67

того тезиса о красоте кода. При этом нужно быть внимательным. Сравните приведенные ниже фрагменты кода: в зависимости от количества отступов вторая
команда print() относится к одному из двух блоков кода или к основной программе.
age = 15
# оба сообщения выведутся только в случае выполнения обоих условий
# при age=15 не выведется ничего, потому что условия не выполняются
if age < 18:
if age > 16:
print("Хоть Вам и больше 16, но спиртного не продадим!")
print("Как тебе не стыдно, мальчик!")

age = 15
# первое сообщение выведется при выполнении обоих условий
# второе сообщение выведется при выполнении первого условия (age 16:
print("Хоть Вам и больше 16, но спиртного не продадим!")
print("Как тебе не стыдно, мальчик!")
Как тебе не стыдно, мальчик!
age = 93
# первое сообщение выведется при выполнении обоих условий
# второе выведется безусловно
# (оно вообще не относится к блокам кода внутри условных операторов)
if age < 18:
if age > 16:
print("Хоть Вам и больше 16, но спиртного не продадим!")
print("Как тебе не стыдно, мальчик!")
Как тебе не стыдно, мальчик!

Разобравшись с блоками кода и отступами (незапуск программы из-за
слишком вольного обращения с отступами – частая ошибка начинающих программистов на Python!), вернемся к изучению оператора if. Пример конструкции с ключевым словом else:
age = 25
if age < 18:
print("Вы несовершеннолетний, спиртного не продадим!")
else:
print("Добро пожаловать, дорогой клиент! Вам виски или мартини?")
Добро пожаловать, дорогой клиент! Вам виски или мартини?

В данном случае age > 18, поэтому условие в блоке if не выполнится, но
присутствует блок else, поэтому выведется сообщение про клиента. Наконец,
рассмотрим пример с ключевым словом elif:
68

age = 18
if age < 18:
print("Вы несовершеннолетний, спиртного не продадим!")
elif age == 18:
print("По закону-то Вы совершеннолетний, но может, не стоит?")
else:
print("Добро пожаловать, дорогой клиент! Вам виски или мартини?")
По закону-то Вы совершеннолетний, но может, не стоит?

Поскольку age = 18, выполнится второе условие (первый блок elif), и выведется призыв к благоразумию. Напомним, что блоков elif может быть несколько, проверяться условия будут сверху вниз до тех пор, пока какое-то из них
не выполнится. Если не выполнилось ни одно условие в блоках if и elif, тогда
либо выполнится код в блоке else, либо, при отсутствии оного, не произойдет
ничего, программа продолжит выполняться дальше.
Существует краткая однострочная форма условного оператора. Ключевые слова if и else могут находиться внутри выражения:
if else

При этом else является обязательной частью: результатом выражения
должно быть некоторое значение – либо одно, либо другое. Рассмотрим пример:
в данном случае в переменную drink попадет строка «Буратино» (речь о газированном напитке), потому что условие age ≥ 18 не выполнится.
age = 15
drink = "Коньяк" if age >= 18 else "Буратино"
drink
'Буратино'

Логические операции и сложные условия
Логические операции (операции булевой алгебры) – это операции, которые можно осуществлять со значениями логического типа (bool). С их помощью
можно составлять сложные (составные) высказывания и, как следствие, сложные
условия. Основных логических операций три: конъюнкция, дизъюнкция и отрицание. Для описания принципа действия логических операций обычно используют так называемые таблицы истинности (рис. 35).
Конъюнкция

Дизъюнкция

Отрицание

a

b

a and b

a

b

a or b

a

not a

0
0
1
1

0
1
0
1

0
0
0
1

0
0
1
1

0
1
0
1

0
1
1
1

0
1

1
0

Рис. 35. Таблицы истинности основных логических операций
(обозначения: 1 – истина, 0 – ложь)
69

Конъюнкция (логическое И) реализуется оператором and. Результат операции равен True тогда и только тогда, когда оба операнда тоже True, в остальных случаях False.
# гулять пойдем только при выполнении обоих условий
# (и температура > 20, и солнце), тогда и только тогда
temperature = 25
sunny = False
walk = (temperature > 20) and sunny
# второе условие не выполняется
walk
False

# walk будет False, потому что

Отметим, что логические операции имеют более низкий приоритет, чем
операции сравнения, поэтому сравнение можно не выделять скобками, оно все
равно выполнится в первую очередь. Однако использовать скобки для наглядности и снижения риска запутаться не возбраняется. Рассмотрим пример с конъюнкцией в условном операторе:
temperature = 25
sunny = False
if (temperature > 20) and sunny:
print("Отличная погода - и тепло, и солнечно! Пойдем гулять!")
else:
print("Что-то погода не очень, лучше посидим дома.") # этот блок
Что-то погода не очень, лучше посидим дома.

Дизъюнкция (логическое ИЛИ) реализуется оператором or. Результат
операции равен False тогда и только тогда, когда оба операнда тоже False, в
остальных случаях True.
# гулять пойдем при выполнении любого из условий - подойдет
# и температура > 20, и солнце
temperature = 25
sunny = False
walk = (temperature > 20) or sunny # walk будет True, потому что
# первое условие выполняется (требуется выполнение хотя бы одного из двух)
walk
True

Пример с дизъюнкцией в условном операторе:
temperature = 25
sunny = False
if (temperature > 20) or sunny:
print("Погода сойдет! Жди в 7, пойдем гулять!") # этот блок
else:
print("Что-то погода не очень, лучше посидим дома.")
Погода сойдет! Жди в 7, пойдем гулять!

70

Отрицание (логическое НЕ) реализуется оператором not. Это очень простая операция, которая инвертирует значение операнда ( True превращает в
False и наоборот).
# гулять пойдем, если температура не меньше или равна 20
# (то есть больше 20)
temperature = 25
walk = not (temperature {b}:", a > b)
print(f"{a} >= {b}:", a >= b)
print(f"{a} < {b}:", a < b)
print(f"{a}