Programmirovanie dlya normalnykh s nulya na yazyke Python

До загрузки: 30 сек.



Благодарим, что скачиваете у нас :)

Если, что - то:

  • Поделится ссылкой:
  • Документ найден в свободном доступе.
  • Загрузка документа - бесплатна.
  • Если нарушены ваши права, свяжитесь с нами.
Формат: pdf
Найдено: 20.07.2020
Добавлено: 30.09.2020
Размер: 3.88 Мб

В серии:Библиотека ALT
М. В. Сысоева, И. В. Сысоев
Программирование для
нормальных с нуля на языке Python
В двух частях
Часть 1
Учебник
Москва
Базальт СПО МАКС Пресс 2018

УДК 004.43
ББК 22.1С95
С95 Сысоева М. В., Сысоев И. В.
Программирование для нормальных с нуля на языке
Python: Учебник. В двух частях. Часть 1 / Ответственный
редактор: В. Л. Черный :  М.: Базальт СПО; МАКС Пресс,
2018.  176 с. [+4 с. вкл]: ил.  (Библиотека ALT).
ISBN 978-5-9908979-5-3
ISBN 978-5-317-05783-1
ISBN 978-5-317-05784-8 (часть 1)
Книга  учебник, задачник и самоучитель по алгоритмизации и
программированию на Python. Она не требует предварительны х знаний
в области программирования и может использоваться для обуч ения с
нуля.
Издание адресовано студентам, аспирантам и преподавателя м ин-
женерных и естественно-научных специальностей вузов, шко льникам
старших классов и учителям информатики. Обучение языку в зн ачи-
тельной степени строится на примерах решения задач обработ ки ре-
зультатов радиофизического и биологического эксперимент а.
Сайт книги: http://www.altlinux.org/Books:Python- sysoeva
Ключевые слова: программирование; численные методы; алго рит-
мы; графики; Python; numpy
УДК 004.43
ББК 22.1
Материалы, составляющие данную книгу, распространяются н а условиях лицензии GNU
FDL. Книга содержит следующий текст, помещаемый на первую с траницу обложки: В серии
“Библиотека ALT”. Название: Программирование для норм альных с нуля на языке Python.
В двух частях. Часть 1. Книга не содержит неизменяемых разд елов. Linux  торговая мар-
ка Линуса Торвальдса. Прочие встречающиеся названия могут являться торговыми марками
соответствующих владельцев.
ISBN 978-5-9908979-5-3
ISBN 978-5-317-05783-1
ISBN 978-5-317-05784-8 (часть 1) c
Сысоева М. В., Сысоев И. В., 2018
c
Basealt, 2018

ОглавлениеПредисловие 5
Глава 1. Введение 7
1.1 Языки программирования . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Парадигмы программирования . . . . . . . . . . . . . . . . . . .12
1.3 Типизация в языках программирования . . . . . . . . . . . . . .14
1.4 Области программирования . . . . . . . . . . . . . . . . . . . . . 20
1.5 Области применения Python . . . . . . . . . . . . . . . . . . . . . 23
1.6 Первая программа. Среда разработки . . . . . . . . . . . . . . . .27
Глава 2. Основные типы данных 32
2.1 Числа. Арифметические операции с числами. Модуль math. . . 32
2.2 Строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.3 Условия и логические операции . . . . . . . . . . . . . . . . . . .42
2.4 Списки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
2.5 Кортежи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.6 Словари . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
2.7 Примеры решения задач . . . . . . . . . . . . . . . . . . . . . . . 56
2.8 Задания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Глава 3. Циклы 67
3.1 Цикл с условием ( while). . . . . . . . . . . . . . . . . . . . . . . 67
3.2 Цикл обхода последовательности ( for). . . . . . . . . . . . . . . 70
3.3 Некоторые основные алгоритмические приёмы . . . . . . . . . .73
3.4 Отладка программы . . . . . . . . . . . . . . . . . . . . . . . . . . 78
3.5 Задания на циклы . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Глава 4. Функции 93
4.1 Функции в программировании . . . . . . . . . . . . . . . . . . . . 93
4.2 Параметры и аргументы функций . . . . . . . . . . . . . . . . . .97
4.3 Локальные и глобальные переменные . . . . . . . . . . . . . . . .100
4.4 Программирование сверху вниз . . . . . . . . . . . . . . . . . . .102
4.5 Рекурсивный вызов функции . . . . . . . . . . . . . . . . . . . . . 103
4.6 Примеры решения заданий . . . . . . . . . . . . . . . . . . . . . . 106
4.7 Задания на функции . . . . . . . . . . . . . . . . . . . . . . . . . 108

4Оглавление
Глава 5. Массивы. Модульnumpy 112
5.1 Создание и индексация массивов . . . . . . . . . . . . . . . . . .113
5.2 Арифметические операции и функции с массивами . . . . . . . .120
5.3 Двумерные массивы, форма массивов . . . . . . . . . . . . . . .125
5.4 Примеры решения задач . . . . . . . . . . . . . . . . . . . . . . . 130
5.5 Задания на массивы, модуль numpy. . . . . . . . . . . . . . . . . 132
Глава 6. Графики. Модуль matplotlib 134
6.1 Простые графики . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
6.2 Заголовок, подписи, сетка, легенда . . . . . . . . . . . . . . . . .138
6.3 Несколько графиков на одном полотне . . . . . . . . . . . . . . .141
6.4 Гистограммы, диаграммы-столбцы . . . . . . . . . . . . . . . . .146
6.5 Круговые и контурные диаграммы . . . . . . . . . . . . . . . . .149
6.6 Трёхмерные графики . . . . . . . . . . . . . . . . . . . . . . . . . 150
6.7 Учёт ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
6.8 Примеры построения графиков . . . . . . . . . . . . . . . . . . .153
6.9 Задания на построение графиков . . . . . . . . . . . . . . . . . .156
Глава 7. Библиотеки, встроенные в numpy160
7.1 Элементы линейной алгебры . . . . . . . . . . . . . . . . . . . . . 160
7.2 Быстрое преобразование Фурье . . . . . . . . . . . . . . . . . . .163
7.3 Генерация случайных чисел . . . . . . . . . . . . . . . . . . . . . 166
7.4 Примеры решения заданий . . . . . . . . . . . . . . . . . . . . . . 167
7.5 Задания на использование встроенных библиотек numpy. . . . . 171

ПредисловиеЭта книга написана для инженеров, физиков, биологов и прост о всех-всех, кто
не изучал программирование прежде, но для кого оно может быт ь полезно как
средство решения своих насущных задач, а не является самоце лью. Для них вы-
бор правильного языка для обучения и работы очень важен: так ой язык должен
быть одновременно прост в освоении и использовании и логичн о организован,
иметь много внешних модулей и расширений для решения реальн ых задач (то
есть быть популярным), и быть хорошо доступен  свободно рас пространяться
вместе со внешними модулями для всех основных операционных систем. Язык
Python лучше всех других удовлетворяет всем этим требовани ям и поэтому ныне
используется во многих вузах и школах для обучения и одновре менно бьёт ре-
корды по популярности среди учёных и инженеров.
Книга позволит вам, начав с нуля, быстро и качественно научи ться делать
нужные вещи: производить вычисления, читать, записывать и анализировать
данные, строить графики, и при этом освоить основные принци пы программи-
рования: структуры данных, циклы, условия, подпрограммы, поиск ошибок и
отладку. Подбирая материал, мы сознательно придерживалис ь самых простых
путей решения той иной задачи, даже если это несколько проти воречило ака-
демически принятому порядку изложения или сложившимся тра дициям. В ря-
де случаев, например, при работе с текстовыми файлами и масс ивами, мы да-
же предпочли использование широко популярных внешних моду лей встроенным
средствам. Всё изложение построено так, чтобы быть полезны м и применимым
сразу, ведь усваивается то, что используется.
Книга может выступать как в качестве самоучителя, так и в кач естве учеб-
ника для преподавания в школе или вузе, задачника или просто справочника.
Сведения об авторах •Сысоева Марина Вячеславовна  кандидат физико-математиче ских наук,
ассистент кафедры Радиоэлектроника и телекоммуникации Саратовско-
го государственного технического университета имени Гага рина Ю.А.
• Сысоев Илья Вячеславович  кандидат физико-математически х наук, до-
цент кафедры динамического моделирования и биомедицинско й инженерии

6Предисловие
Саратовского национального исследовательского государственного универ-
ситета имени Н.Г. Чернышевского.
Сведения о рецензентах •Пономаренко Владимир Иванович  доктор физико-математиче ских наук,
ведущий научный сотрудник Саратовского филиала Института радиотех-
ники и электроники имени В.А. Котельникова РАН.
• Огнева Марина Валентиновна  кандидат физико-математичес ких наук,
заведующая кафедрою информатики и программирования Сарато вского
национального исследовательского государственного унив ерситета имени
Н. Г. Чернышевского.
• Курячий Георгий Владимирович  преподаватель факультета В МК Мос-
ковского Государственного Университета им. М. В. Ломоносов а, автор кур-
сов по Python для ВУЗов и Вечерней математической Школы, разра ботчик
компании Базальт СПО.

Глава 1
Введение
1.1 Языки программированияПервый проект вычислительной машины был разработан Чарльз ом Бэбби-
джем в 1833 году в Великобритании. Описание проекта сделала Августа Ада
Кинг (единственная дочь знаменитого поэта лорда Байрона), она же ввела такие
фундаментальные понятия, как цикл, рабочая ячейка, и п отому считается
первым в мире программистом; язык программирования Ада назв ан в её честь.
Машина Бэббиджа никогда не была реализована полностью, хотя на её реа-
лизацию ушло 17 тысяч фунтов стерлингов и 9 лет времени. Осно вная проблема,
с которою столкнулся Бэббидж,  низкий уровень элементной б азы: промыш-
ленность того времени не была готова производить детали нуж ного качества и
в требуемые сроки. Тем не менее, его последователь Георг Шутц в 1850-ых по-
строил несколько работающих разностных машин.
Первая реальная электрическая вычислительная машина была построена
немецким инженером-исследователем К. Цузе в 1938 году, ана логичные рабо-
ты велись независимо от него в США Д. Штибитцем и Г. Айкеном. Базо вые
принципы архитектуры современных ЭВМ были сформулированы Джоном фон
Нейманом в 1946 году в США, а в 1948 году в Англии была построена пе рвая
ЭВМ, основанная на этих принципах.
В СССР первая машина БЭСМ была спроектирована в 1951 году и уж е в
следующем году началась её практическая эксплуатация. Элем ентная база для
первых ЭВМ 40-50-ых годов представляла собою вакуумные лам пы. Переход на
полупроводниковую элементную базу в 1960-ых позволил суще ственно повысить
быстродействие, уменьшить размер и энергопотребление ЭВМ . Следующим эта-
пом стал переход от отдельных транзисторов к интегральным л огическим схе-
мам.
Первые программы заключались в установке ключевых переключат елей на
передней панели вычислительного устройства. Очевидно, та ким способом мож-
но было составить только небольшие программы. Одну из первы х попыток со-

8Глава 1. Введение
здать полноценный язык программирования предпринял немец кий учёный Ко-
нрад Цузе, который в период с 1943 по 1945 год разработал язык Plankalk¨ul
(Планкалкюль). В переводе на русский язык это название соотв етствует выра-
жению планирующее исчисление. Это был очень перспективны й язык, факти-
чески являвшийся языком высокого уровня, однако из-за воен ных действий он
не был доведён до практической реализации.
Неизвестно, насколько бы ускорилось развитие программиро вания, если бы
наработки Цузе стали доступны другим учёным в конце 40-х год ов, но на прак-
тике с развитием компьютерной техники сначала получил распр остранениема-
шинный язык . Запись программы на нём состояла из единиц и нулей. Машинны й
язык принято считать языком программирования первого поко ления (при этом
разные машины разных производителей использовали различн ые коды, что тре-
бовало переписывать программу при переходе на другую ЭВМ).
Программа Hello, world! для процессора архитектуры x86 (О С MS DOS,
вывод при помощи BIOS прерывания int10h) выглядит следующим образом (в
шестнадцатеричном представлении):
B B 1 1 0 1 B 9 0 D 0 0 B 4 0 E 8 A 0 7 4 3 C D 1 0 E 2 F 9
C D 2 0 4 8 6 5 6 C 6 C 6 F 2 C 2 0 5 7 6 F 7 2 6 C 6 4 2 1
Вскоре на смену такому методу программирования пришло прим енение язы-
ков второго поколения, также ограниченных спецификациями конкретных ма-
шин, но более простых для использования человеком за счет ис пользования мне-
моник (символьных обозначений машинных команд) и возможно сти сопоставле-
ния имен адресам в машинной памяти. Они традиционно известн ы под наиме-
нованием языков ассемблера ( транслируемые языки). Эти языки относятся к
языкам низкого уровня, то есть близким к программированию н епосредственно
в машинных кодах.
Однако при использовании ассемблера становился необходим ым процесс пере-
вода программы на язык машинных двоичных кодов перед её выпо лнением, для
чего были разработаны специальные программы, также получи вшие название
ассемблеров (трансляторов). Сохранялись и проблемы с пере носимостью про-
граммы с ЭВМ одной архитектуры на другую, и необходимость для программи-
ста при решении задачи мыслить терминами низкого уровня: ячейка, адрес,
команда.
Классическая программа на одном из диалектов Ассемблера:
. 3 8 6 / / тип процессора
. M O D E L S M A L L / / модель памяти
. D A T A / / инициализированные данные : m s g D B ’ H e l l o , Ђ W o r l d ’ , 1 3 , 1 0 , ’ $ ’
. C O D E / / исполняемый код : S T A R T : m o v a x , @ D A T A / / Загрузка адреса сегмента в регистр d s
m o v d s , a x

1.1. Языки программирования9
m o v a x , 0 9 0 0 h
l e a d x , m s g
i n t 2 1 h
m o v a x , 4 C 0 0 h
i nt 2 1 h
E N D S T A R T
Поскольку команды ассемблера всего лишь более удобно обозн аченные ин-
струкции в двоичных кодах, как правило, можно добиться взаи мнооднозначного
соответствия между программами в машинных кодах и программ ами на ассем-
блере, следовательно, они оказываются полностью взаимно за меняемыми. В этом
кроется как ключевое преимущество, так и ключевой недостаток ассемблера. С
одной стороны, программирование в двоичных кодах становит ся ненужным ров-
но с того момента, как написана программа-транслятор, при э том сохраняется
полный доступ ко всем возможностям ЭВМ. С другой стороны, ес ли изменят-
ся инструкции или регистры, программа на ассемблере окажет ся бесполезна.
Поскольку архитектура ЭВМ меняется часто, а одновременно с осуществуют вы-
числительные машины различных архитектур, получается, чт о программы на
ассемблере приходится всё время переписывать.
Чтобы не переписывать каждый раз программу, необходимо был о создать
некоторый уровень абстракции: спрятать детали организаци и конкретного ком-
пьютера от программиста и позволить ему мыслить категориями более универ-
сальными, чем категории конкретных инструкций конкретной машины. Такой
шаг был впервые сделан в 1958 году, когда появился первый язы к высокого
уровня  FORTRAN (сокращение от FORmula TRANSlation). Хотя прог рам-
мы на Фортране работали существенно (в 2–4 раза) медленнее, чем программы
на ассемблере, переход на языки высокого уровня стал огромн ым шагом вперёд,
поскольку число способных к программированию людей резко у величилось: ста-
ло не нужно помнить все регистры и инструкции процессора. Пр ограммировать
начали не только профессиональные программисты, но и учёны е и инженеры.
Программа Привет мир на Фортране (эта программа будет ком пилиро-
ваться только сравнительно современными компиляторами, п оддерживающими
стандарт Frotran 90 или более новые):
P rogram h e l l o
write ( * , * ) ’ H e l l o , Ђ W o r l d ! ’
end
Конечно, программа на Фортране требовала перевода в двоичный код, ко-
торый, в отличие от ассемблера, нельзя было сделать простым взаимно одно-
значным транслированием. Для этого была написана на ассемб лере специальная
программа  компилятор. Поэтому такие языки получили назва ниекомпили-
руемых . Когда изменяется архитектура ЭВМ, компилятор для каждого языка
приходится переписывать, ведь он всё равно написан на ассем блере. Компили-
руемые языки: Fortran (1958 г.), Algol (1960 г.), С (1970 г.) и его потомки (C++,

10Глава 1. Введение
D, Vala), Pascal (1970 г.) и его потомки (Delphi, FreePascal/Lazarus)  основа
современного программирования. Программа Привет мир на Pascal:
p rogram h e l l o ;
begin
w
rite
( ’ H e l l o , Ђ W o r l d ’ ) ;
end .
Программа Привет мир на С:
# in
lude < s t d i o . h >
int m a i n ( ) {
p r i n t f ( ’ H e l l o , Ђ W o r l d ’ ) ;
r eturn 0 ;
}
Со временем производительность компьютеров выросла настол ько, что ока-
залось возможным не компилировать код программ в двоичный, а сразу испол-
нять его строчка за строчкою. Такой способ называется интерп ретированием,
программа, интерпретирующая код  интерпретатором, а такие языки ин-
терпретируемые . MATLAB (1978 г.), Perl (1987 г.), Python (1992 г.), PHP (1995
г.), Ruby (1995 г.), Javascript (1995 г.)  примеры популярн ых интерпретируе-
мых языков. Интерпретатор может работать в двух режимах: ин терактивном и
выполнения скрипта.
Программа Привет мир на Perl:
# ! / u s r / b i n / p e r l
p rint " H e l l o , Ђ W o r l d \ n "
Программа Привет мир на Python:
p rint ( ’ H e l l o , Ђ W o r l d ’ )
На PHP:
< ? = ’ H e l l o , Ђ W o r l d ’ ? >
На Ruby:
{ p u t s " H e l l o , Ђ W o r l d " }
На JavaScript:
< s c r i p t t y p e = " a p p l i c a t i o n / j a v a s c r i p t " > A l e r t ( ’ H e l l o , W o r l d ’ ) ;
< / s c r i p t >
Интерпретируемые языки проще в освоении и использовании, н о их область
применения ограничена, поскольку программы на них не могут взаимодейство-
вать с процессором напрямую, а производительность существе нно ниже, чем у

1.1. Языки программирования11
компилируемых. Они используются там, где либо время исполнения программы
некритично, либо в случае, когда программа пишется на один р аз, поскольку то-
гда относительно большое время исполнения компенсируется существенно мень-
шим временем написания. Так, Perl появился как язык для обра ботки текстов,
PHP  пример удачного языка для создания сайтов. Промежуточное положение между компилируемыми и интерпрет ируемыми
языками занимают языки виртуальных машин , самые распространённые из ко-
торых Java (компилируется в машинный код виртуальной машин ы Java Virtual
Machine) и C# (компилируется в машинный код виртуальной маш ины Common
Language Runtime  основы для всех языков семейства .NET). Для них компиляция происходит не в двоичный код данного конк ретного
процессора, а в двоичный код специальной виртуальной машин ы (иногда его
называют байткод). Таким образом, достигаются два существен ных плюса: во-
первых, можно не перекомпилировать программу под каждый но вый процессор,
во-вторых, компилятор, имея возможность анализировать вс ю программу цели-
ком, всё-таки может произвести ряд оптимизаций, увеличива я таким образом
скорость исполнения по сравнению с простым пошаговым интер претированием.
Хотя языки виртуальных машин ближе к компилируемым, чем инте рпрети-
руемые языки, они появились позже и их условно можно назвать пятым поколе-
нием языков программирования. 1
Некоторые языки могут и компилироваться,
и интерпретироваться, и компилироваться в байткод, наприм ер, OCaml.
Программа Привет мир на Java:
lass H e l l o W o r l d {
p ubli
stati
void m a i n ( S t r i n g a r g s [ ] ) {
S y s t e m . o u t . p r i n t l n ( " H e l l o Ђ W o r l d " ) ;
}
}
Таблица 1.1. Поколения языков программирования
I поколение Машинные языки
II поколtение Транслируемые языки (ассемблеры)
III поколение Компилируемые языки
IV поколение Интерпертируемые языки
V поколение Языки виртуальных машин
1Многие авторы до сих пор выделяют только 3 поколения языков п рограммирования, сов-
мещая компилируемые, интерпретируемые и компилируемые в б айткод языки в рамках одного
последнего. Хотя такая классификация является классичес кою, в наше время с нею труд-
но согласиться, так как большинство программистов никогда не имели дело с первыми двумя
поколениями и, следовательно, для них от такой классификац ии вовсе нет толка.

12Глава 1. Введение
С начала 90-х на смену обычным языкам программирования в обл асти вы-
числений стали приходить различные специализированные математические па-
кеты . В настоящее время наибольшею популярностью пользуется Ma tLab. Кро-
ме него часто используются также другие коммерческие пакеты : Mathematica,
MathCad, STATISTICA, а также свободные аналоги: SciLab и, ос обенно, ста-
тистический пакет R. Пакеты существенно упростили разрабо тку приложений,
внеся два ключевых усовершенствования:
•большая доступная встроенная библиотека алгоритмов, кото рая может
быть расширена средствами, как самого пакета, так и с подключ ением мо-
дулей на Fortran и C;
• встроенные средства для построения графиков, позволяющие в изуализиро-
вать данные на экране компьютера в интерактивном режиме и сох ранять
результаты построения в файлы основных форматов.
1.2 Парадигмы программирования Парадигма программирования  это совокупность идей и понят ий, определя-
ющих стиль написания компьютерных программ (подход к програм мированию).
Важно отметить, что парадигма программирования не определ яется одно-
значно языком программирования; практически все современ ные языки про-
граммирования в той или иной мере допускают использование ра зличных пара-
дигм ( мультипарадигмальное программирование ). Также важно отметить, что
существующие парадигмы зачастую пересекаются друг с другом в деталях, по-
этому можно встретить ситуации, когда разные авторы употре бляют названия из
разных парадигм, говоря при этом, по сути, об одном и том же яв лении. Счита-
ется, что все парадигмы делятся на две большие части: импера тивное и деклара-
тивное программирование. Императивное программирование  это парадигма
программирования, которая описывает процесс вычисления в виде инструкций,
изменяющих состояние данных. Подразделы императивного про граммирования
 структурное иобъектно-ориентированное .Декларативное программирова-
ние  это парадигма программирования, в которой вместо пошагов ого алгорит-
ма решения задачи (что делает императивное программирован ие, описывающее
как решить задачу) задаётся спецификация решения задачи, т . е. описывается,
что собой представляет проблема и что требуется получить в к ачестве результа-
та. Декларативные программы не используют понятия состояни я и, в частности,
не содержат переменных и операторов присваивания. К деклар ативной парадиг-
ме относится функциональное программирование.
Структурное программирование  методология разработки программно-
го обеспечения, в основе которой лежит представление прогр аммы в виде иерар-
хической структуры блоков. Языками-первопроходцами в это й парадигме были
Fortran, Algol и B, позже их приемниками стали Pascal и C. В соо тветствии с
данной методологией любая программа состоит из трёх базовых управляющих

1.2. Парадигмы программирования13
структур: последовательность, ветвление, цикл; кроме того, используются под-
программы. При этом разработка программы ведётся пошагово , методом сверху
вниз.
Следование принципам структурного программирования сдел ало тексты про-
грамм, даже довольно крупных, нормально читаемыми. Серьёз но облегчилось
понимание программ, появилась возможность разработки про грамм в нормаль-
ном промышленном режиме, когда программу может без особых з атруднений
понять не только её автор, но и другие программисты. Python и спользует эту
парадигму как вспомогательную. Объектно-ориентированное программирование (ООП)  это методоло-
гия программирования, основанная на представлении програ ммы в виде совокуп-
ности объектов, каждый из которых является экземпляром опр еделенного клас-
са, а классы образуют иерархию наследования. В основе концеп ции объектно-
ориентированного программирования лежит понятие объекта  некой сущно-
сти, которая объединяет в себе поля (данные) и методы (выпол няемые объектом
действия). Например, объект ЧЕЛОВЕКможет иметь поля ИМЯ,ФАМИЛИЯ и мето-
ды КУШАТЬ ,СПАТЬ . Соответственно, в программе можем использовать оператор ы
ЧЕЛОВЕК.ИМЯ:=’Иван’ иЧЕЛОВЕК.КУШАТЬ(пища) .
С самого начала Python проектировался как объектно-ориент ированный язык
программирования: все данные представляются объектами Pyt hon, программа
является набором взаимодействующих объектов, посылающих др уг другу сооб-
щения, каждый объект имеет собственную часть памяти и может иметь в составе
другие объекты, каждый объект имеет тип, объекты одного тип а могут прини-
мать одни и те же сообщения (и выполнять одни и те же действия) .
Функциональное программирование  парадигма программирования, в ко-
торой процесс вычисления трактуется как вычисление значен ий функций в ма-
тематическом понимании последних (в отличие от функций как подпрограмм в
структурном программировании). Наиболее известные LISP, Haskell, семейство
языков ML. Противопоставляется парадигме императивного программир ования, которая
описывает процесс вычислений как последовательное измене ние состояний (в
значении, подобном таковому в теории автоматов). При необх одимости, в функ-
циональном программировании вся совокупность последоват ельных состояний
вычислительного процесса представляется явным образом, н апример, как спи-
сок. Функциональное программирование предполагает обходитьс я вычислением
результатов функций от исходных данных и результатов други х функций, и не
предполагает явного хранения состояния программы. Соотве тственно, не пред-
полагает оно и изменяемость этого состояния (в отличие от им перативного, где
одной из базовых концепций является переменная, хранящая с воё значение и
позволяющая менять его по мере выполнения алгоритма). Функциональное программирование является одной из паради гм, поддержи-
ваемых языком программирования Python. Основными предпос ылками для пол-
ноценного функционального программирования в Python явля ются: функции

14Глава 1. Введение
Рис. 1.1. Парадигмы программирования
высших порядков, развитые средства обработки списков, рек урсия, возможность
организации ленивых вычислений. Элементы функциональног о программирова-
ния в Python могут быть полезны любому программисту, так как п озволяют
гармонично сочетать выразительную мощность этого подхода с другими подхо-
дами.
Визуальное программирование  способ создания программы для ЭВМ
путём манипулирования графическими объектами вместо напи сания её текста.
Визуальное программирование часто представляют как следующ ий этап разви-
тия текстовых языков программирования. Наглядным примеро м может служить
среда разработки Delphi, сделанная для языка Ob ject Pascal , где редактируют-
ся графические объекты: форма, кнопки, метки. В последнее в ремя визуальному
программированию стали уделять больше внимания в связи с ра звитием мобиль-
ных сенсорных устройств (КПК, планшеты).
С Python поставляется библиотека tkinter на основе Tcl/Tk д ля создания
кроссплатформенных программ с графическим интерфейсом. С уществуют рас-
ширения, позволяющие использовать все основные библиотеки графических ин-
терфейсов: wxPython, основанное на библиотеке wxWidgets, PyGTK для Gtk,
PyQt и PySide для Qt и другие. Некоторые из них также предоста вляют широ-
кие возможности по работе с базами данных, графикой и сетями , используя все
возможности библиотеки, на которой основаны.
1.3 Типизация в языках программирования
Все данные в компьютере хранятся в виде последовательностей нулей и еди-
ниц подряд. Для удобства эти последовательности группируют по 8 цифр подряд
и такую группу называют байтом (два байта называются машинным словом). Од-
нако оперировать последовательностями битов напрямую при написании боль-
ших программ неудобно, поэтому вводят дополнительные дого ворёности о спо-

1.3. Типизация в языках программирования15
собе интерпретации отдельных байтов в памяти. Эти договорённости и можно
назвать типами данных. Все языки программирования можно ра зделить на:
• нетипизированные (бестиповые),
• типизированные.
Нетипизированными являются языки ассемблера, а также язык програм-
мирования встраиваемых устройств Forth. По сути, бестипов ые  это наиболее
низкоуровневые языки, предоставляющие прямой доступ к мани пулированию
отдельными битами прямо в регистрах процессора. Все компил ируемые и интер-
претируемые широко используемые языки, такие как Pascal, C , Python, PHP и
другие, являются типизированными. У отсутствия типизации есть некоторые преимущества:
•Полный контроль над действиями компьютера. Компилятор или и нтерпре-
татор не будет мешать какими-либо проверками типов, запрещ ая те или
иные действия.
• Получаемый код обычно имеет высокую эффективность, котора я, правда,
зависит в первую очередь от квалификации программиста.
• Прозрачность инструкций. При знании языка обычно нет сомне ний, что из
себя представляет тот или иной код.
Недостатки отсутствия типизации:
• Сложность написания программы быстро растёт с ростом необх одимой аб-
стракции и общности. Даже операции с такими, казалось бы, не сложными
объектами, как списки, строки или записи, уже требуют сущест венных уси-
лий.
• Отсутствие проверок и как следствие огромное число трудноу ловимых оши-
бок на этапе компиляции. Любые бессмысленные действия, напр имер вы-
читание указателя на массив из символа будут считаться сове ршенно нор-
мальными.
• Высокие требования к квалификации программиста и фактичес ким знани-
ям об архитектуре целевой ЭВМ.
Типизированные языки делятся ещё на несколько пересекающихся катего-
рий.
1. Сильная/слабая типизация (также иногда говорят строгая / нестрогая).
Сильная типизация означает, что язык не позволяет смешиват ь в выраже-
ниях различные типы и не выполняет автоматические неявные п реобразо-
вания, например, нельзя вычесть из строки множество. Языки со слабой ти-
пизацией выполняют множество неявных преобразований автом атически,

16Глава 1. Введение
даже если может произойти потеря точности или преобразован ие неодно-
значно. В действительности почти все популярные языки: C, J ava, Python,
Pascal и другие имеют условно сильную типизацию, позволяя нек оторые
автоматические преобразования типов. Самые распространё нные примеры:
автоматическое приведение целых чисел к действительным и д ействитель-
ных к комплексным, а также символов к строкам. Крайний случа й слабой
типизации  отсутствие типов вообще.
Преимущества сильной типизации:
• Надежность  вместо неправильного поведения вы получите ис клю-
чение или ошибку компиляции.
• Скорость  преобразования типов могут быть довольно затрат ными,
с сильной типизацией необходимо писать их явно, что заставл яет про-
граммиста как минимум знать, что этот участок кода может быт ь мед-
ленным, или избегать их.
• Понимание работы программы  опять же, вместо неявного прив еде-
ния типов программист пишет все сам, а, значит, примерно пон имает,
что сравнение строки и числа происходит не само собой и не по в ол-
шебству, а использовать действительнозначную переменную в качестве
счётчика цикла опасно из-за ошибок округления.
• Определенность  когда вы пишете преобразования вручную, вы точ-
но знаете, что вы преобразуете и во что. Также вы всегда будет е по-
нимать, что такие преобразования могут привести к потере то чности,
затратам машинного времени или стать причиною логической о шибки.
Преимущества слабой типизации:
• Удобство использования смешанных выражений (например, ко мбини-
рование целых и вещественных чисел).
• Скорость разработки: не нужно тратить время на написание бо льшого
числа явных преобразований типов.
• Краткость записи.
2. Явная/неявная типизация. Явно-типизированные языки отличаются
тем, что тип новых переменных/функций/их аргументов нужно писать яв-
но. Соответственно, языки с неявной типизацией перекладыв ают эту задачу
на компилятор/интерпретатор, такой способ называется авт оматическим
выведением типов. Все компилируемые языки  наследники ALGO L 60 –
имеют явную типизацию. Это C, C++, D, Java, C#, Pascal, Modula 2 , Ada
и другие. Напротив, языки семейства ML (Standard ML и Ocaml) , Haskell,
почти все интепретируемые языки: Pyhton, Ruby, Perl, PHP, Ja vaScript, Lua
имеют неявную.
Преимущества явнойтипизации:

1.3. Типизация в языках программирования17
•Многие логические ошибки, ведущие к неверному приведению т ипов,
можно отловить на этапе компиляции. Либо эти ошибки вовсе не воз-
никают, поскольку попытка выписать тип выражения приводит к мыс-
ли, что само выражение неверно.
• Знание того, какого типа значения могут храниться в конкрет ной пере-
менной, снимает необходимость помнить это при отладке и дал ьнейшей
модификации программы.
• Существенно упрощается написание компиляторов, поскольк у компи-
лятор не должен уметь определять тип переменной. Как следст вие, ча-
сто можно произвести ряд дополнительных оптимизаций уже на этапе
компиляции автоматически.
Преимущества неявнойтипизации:
• Сокращение записи (сравните Python и Pascal):
def add(x, y) :
fun
tion add(x: real ; y: integer ): real ;
• Полиморфизм (универсальность). Одна и та же функция может б ыть
написана для переменных разных типов, если используемые в н ей опе-
рации определены для них. В языках с явною типизацией в такой си-
туации приходится писать много одинаковых функций, отлича ющихся
только типом аргументов и результата (это называется перег рузкою
функции), либо эмулировать неявную типизацию за счёт шабло нов и
генериков.
3. Статическая/динамическая типизация. Статическая типизация опре-
деляется тем, что конечные типы переменных и функций устана вливаются
на этапе компиляции. Т.е. уже компилятор на 100% уверен, как ой тип, где
находится. В динамической типизации все типы выясняются уже во время
выполнения программы. Примеры языков со статическою типиз ацией: C,
Java, C#, Ada, С++, D, Pascal. Примеры языков с динамическою типиза-
цией: Python, JavaScript, Ruby, PHP, Perl, JavaScript, Lisp .
При статической типизации параметр подпрограммы и возвращаемое зна-
чение функции связывается с типом в момент объявления и тип н е мо-
жет быть изменён позже (переменная или параметр будут прини мать, а
функция  возвращать значения только этого типа). Некоторы е статически
типизированные языки позже получили возможность также исп ользовать
динамическую типизацию при помощи специальных подсистем. Например,
тип Variant в Delphi, Data.Dynamic в Haskell, C# поддерживает псевдо-тип
dynamic .
Преимущества статическойтипизации:
• Статическая типизация даёт самый простой машинный код.

18Глава 1. Введение
•Многие ошибки исключаются уже на стадии компиляции.
• Статическая типизация хороша для написания сложного, но бы строго
кода.
• В интегрированной среде разработки осуществимо автодопол нение
(среда разработки сама догадывается и дописывает часть код а за про-
граммиста), особенно если типизация  строгая статическая : множе-
ство вариантов можно отбросить как не подходящие по типу.
• Чем больше и сложнее проект, тем большее преимущество дает с тати-
ческая типизация, и наоборот.
Недостатки статической типизации:
• Языки с недостаточно проработанной математической базой о казы-
ваются довольно многословными: каждый раз надо указывать, к акой
тип будет иметь переменная. В некоторых языках есть автомат иче-
ское выведение типа, однако оно может привести к трудноулов имым
ошибкам.
• Тяжело работать с данными из внешних источников (например, в ре-
ляционных СУБД/ десериализация данных).
При динамической типизации переменная связывается с типом в момент
присваивания значения, а не в момент её объявления (как прав ило, она
вообще не объявляется нигде до момента первого использован ия). Таким
образом, в различных участках программы одна и та же перемен ная может
принимать значения разных типов.
Преимущества динамическойтипизации:
• Упрощается написание несложных программ.
• Облегчается работа прикладного программиста с СУБД, которы е
принципиально возвращают информацию в динамически типизи ро-
ванном виде. Поэтому динамические языки ценны, например, для
программирования веб-служб.
• Иногда требуется работать с данными переменного типа. Напр имер,
может понадобиться выдать массив или одно число, или вернут ь спе-
циальное значение типа ничто. В языке со статическою типи зацией
такое поведение приходится эмулировать: одно число заменя ть масси-
вом размером в 1 элемент; при возможности появления особого зна-
чения  вводить так называемые вариантные типы, как сдела но в
OCaml.
Недостатки динамической типизации:
• Статическая типизация позволяет уже при компиляции замети ть про-
стые ошибки по недосмотру. Для динамической типизации тр ебует-
ся как минимум выполнить данный участок кода.

1.3. Типизация в языках программирования19
•Особенно коварны в динамическом языке программирования оп ечат-
ки: разработчик может несколько раз просмотреть неработающ ий код
и ничего не увидеть, пока наконец не найдёт набранный с ошибк ой
идентификатор.
• Не действует либо действует с ограничениями автодополнени е в среде
разработки: трудно или невозможно понять, к какому типу отн осится
переменная, и вывести набор её полей и методов.
• Низкая скорость, связанная с динамической проверкой типа, и боль-
шие расходы памяти на переменные, которые могут хранить чт о угод-
но. К тому же большинство языков с динамической типизацией ин-
терпретируемые, а не компилируемые.
• Невозможна перегрузка процедур и функций по типу данных  то лько
по количеству операндов (правда, она, как правило, и не треб уется).
В действительности, практически все языки, имеющие сильную типизацию,
допускают некоторые послабления. Например, Pascal и D допус кают сме-
шивание в одном выражении целых и действительных чисел (но р езультат
обязан быть действительным), строк и символов (результат о бязан быть
строкою), то есть допускают сведение типа к более общему. Анало гично C
хотя и относят к языкам со слабою в целом типизацией (можно см ешивать
в одном выражении логические переменные, числа, указатели и строки),
всё же не лишён ряда проверок типов.
Таблица 1.2. Типизация в языках программирования
JavaScript Динамическая Слабая Неявная
Ruby Динамическая Сильная Неявная
Python Динамическая Сильная Неявная
Java, C# Статическая Сильная Явная
PHP Динамическая Слабая Неявная
C, C++, Ob jective-C Статическая Слабая Явная
Perl Динамическая Слабая Явная
Haskell, Ocaml, Standard ML Статическая Сильная Неявная
Lisp Динамическая Сильная Неявная
D Статическая Сильная Явная
Fortran 90/95/2003/2008 Статическая Сильная Явная
Pascal, Ob jectPascal/Delphi, Ada Статическая Сильная Явная

20Глава 1. Введение
1.4 Области программирования
Следует понимать, что в сложившейся в наши дни программной и ндустрии
различные языки программирования заняли разные ниши. Неко торые из них
достигли успеха именно благодаря специализации, яркие при меры: JavaScript и
PHP. Другие, как Python и Java  существенно более универсаль ны и получили
признание и распространение за счёт возможности сходными с редствами решать
разные задачи. Но ни один современный язык, в том числе широк о рекламиру-
емые C# и C++, не может эффективно использоваться для решени я любых
задач.
В настоящее время программирование применяется в самых раз личных об-
ластях человеческой деятельности, таких как:
1. Системное программирование
Написание операционных систем, компиляторов, интерпрета торов, вирту-
альных машин. В этой области требования к быстродействию и п отребле-
нию памяти очень велики, а создание переносимых программ за труднено
необходимостью тесно и напрямую взаимодействовать с конкр етным обо-
рудованием (железом). Основные языки программирования в этой об-
ласти: ассемблер, а также компилируемые языки, компилятор ы которых
написаны на них самих методом постепенной самораскрутки (в сегда име-
ют платформозависимое ассемблерное ядро): C, C++, Ob jectiv e C, Pascal,
Ada.
2. Программирование встраиваемых устройств
Создание операционных систем и прикладных программ для раз ных ма-
лых вычислительных машин: станков с программным управлен ием, се-
тевых маршрутизаторов, модемов, автомобильной и авиацион ной электро-
ники. По сути, эта область примыкает к системному программи рованию
и потому здесь используются примерно те же средства: ассембл ер, Forth,
некоторые компилируемые языки.
3. Программирование видеокарт
Видеоускорители имеют весьма специфические аппаратные осо бенности:
они не могут работать напрямую с устройствами ввода/вывода , не могут
сами динамически выделять память, часто способны работать эффективно
только с действительными числами одинарной точности (4 бай та), эффек-
тивно могут выполнять одинаковые инструкции над разными да нными, но
очень теряют в производительности при необходимости глобал ьной про-
верки условий и частой синхронизации потоков. Поэтому для н их созданы
специализированные языки: OpenCL и CUDA.
4. Программирование высоко нагруженных серверов
Задача состоит в управлении большим числом (часто 10 тысяч и более в се-
кунду) запросов, поступающих как локально с этого же компьюте ра, так и,

1.4. Области программирования21
главным образом, по сети. По запросам необходимо производить некоторые
вычисления и/или поиск в базах данных. На первом месте в таки х задачах
стоит надёжность: сбой работы над одним из запросов не долже н приво-
дить к краху исполнения всех остальных или полной остановке сервера. На
втором месте  производительность, в том числе способность , не снижая
существенно производительности на 1 поток, обрабатывать о дновременно
много потоков с использованием нескольких вычислительных ядер или да-
же нескольких физически разнесённых ЭВМ (это свойство назы вается мас-
штабируемостью). Основные языки здесь: Java, C#, Erlang, то есть язы-
ки, использующие виртуальные машины и имеющие достаточно выс окие
возможности абстрагирования (ООП), что позволяет локализ овать многие
ошибки времени исполнения. Реже используется C++, посколь ку, несмот-
ря на высокую производительность и широкие возможности, пр ограммы на
C++ часто приводят к некорректной работе с памятью. В последн ее время
популярны Scala и Go в качестве замены Java, поскольку Scala позволяет
писать более лаконичный и сложный код частично в функционал ьном сти-
ле, а Go прост, поддерживает очень эффективную модель много поточных
вычислений и эффективно компилируется в машинный код.
5. Программы для работы с базами данных
Эта область частично пересекается с предыдущей, но затраги вает также
клиентские программы, где требования к скорости и надёжнос ти работы
не такие жёсткие. Программы в этой области, как правило, соч етают в себе
две части. На одном языке написана высокоуровневая обёртка , с которою
взаимодействует пользователь. Для её написания часто испо льзуются 1С,
C#, Delphi, а также многие интерпретируемые языки, в первую очередь
Python и Ruby. Вторая часть отвечает за непосредственное вз аимодействие
с базою данных и написана на одном из диалектов языка запросо в SQL.
6. Системное администрирование
Задача системного администратора  автоматизация основны х работ по
обслуживанию серверов. Это резервное копирование данных, установка об-
новлений, а также новых программ и библиотек, восстановлен ие после сбоя,
синхронизация разных серверов в кластере, запуск различны х задач раз-
ных пользователей и их распределение по отдельным процессо рным ядрам.
Персональному компьютеру системный администратор почти не нужен, все
основные действия по поддержанию компьютера в работоспособ ном состоя-
нии производит сам пользователь. Долгое время основным язы ком систем-
ных администраторов был shell script, но в настоящее время я зыки общего
применения, в первую очередь Python, также стали активно пр именяться,
поскольку позволяют, владея на высоком уровне одним языком, совмещать
работу системного администратора с работою, например, веб- программиста
или программиста баз данных.

22Глава 1. Введение
7.Написание графических интерфейсов пользователя
В этой области очень большое распространение получила пара дигма ООП
и парадигма визуального программирования. Пишут на многих языках,
как компилируемых: C++, Ob ject Pascal, Vala, так и интерпре тируемых:
Python, Tcl, Ruby. Java и C# также иногда используются в данно й области.
8. Веб-программирование
Написание программ, работающих в браузере, начиная от прост ых сайтов и
заканчивая сложными компьютерными играми, имеет определён ную специ-
фику. В настоящее время здесь используются все основные скри птовые язы-
ки: PHP, Python, Ruby (на платформе Rails). Наибольшую попул ярность
имеет JavaScript, поскольку его виртуальная машина хорошо оптимизиро-
вана по производительности и потреблению памяти во всех поп улярных
браузерах.
9. Компьютерные игры
Уже долгое время индустрия компьютерных игр является локомот ивом
развития как аппаратных средств: центральных процессоров и особенно
видеокарт, так и концепций и языков программирования. Перв оначально
игры писались на системных языках и мало отличались от прочи х про-
грамм, но впоследствии именно в игростроении наибольшее ра спростране-
ние получила концепция объектно-ориентированного програ ммирования.
В настоящее время только самые критичные для производитель ности ча-
сти пишутся на высокопроизводительных языках вроде C++, бо льшая же
часть программной логики и управляющих скриптов, графическ ий интер-
фейс пользователя, и даже многие базовые части пишут на инте рпрети-
руемых языках, самым популярным из которых здесь является P ython.
Основная причина этого  необходимость соблюдать сроки: вр емени на
разработку игр нужно много, но самая лучшая и надёжная игра п отерпит
фиаско на рынке, если опоздает даже на 2–3 года.
10. Научное программирование
Учёные долгое время были одними из основных потребителей ЭВМ . Для
них был создан первый компилируемый язык  Fortran, который и в на-
стоящее время используется в случае, когда производительн ость программ
имеет ключевое значение. Однако возможности современных ко мпьютеров
оказались столь велики, что избыточны для решения большинс тва задач
с точки зрения производительности и объёма памяти. В резуль тате наи-
большее признание в последние 20 лет получили языки интерпр етируемого
типа, глубоко интегрированные со средствами разработки, б иблиотеками
алгоритмов и средствами построения графиков. Такие интегр ированные
системы условно называют пакетами. Наиболее известными п римерами
таких систем являются коммерческие MATLAB, Mathematica, Sta sistica, а
также бесплатные/свободные R, SciLab, GNU Octave. Единстве нный язык
общего назначения, в настоящее время не только сохранивший свою привле-

1.5. Области применения Python23
кательность, но и успешно теснящий математические пакеты,в том числе
и коммерческие,  это Python. Произошло это благодаря прост оте и по-
нятности языка с одной стороны, и наличию очень хороших и выс окопро-
изводительных библиотек алгоритмов и средств для построен ия графиков.
Есть и проекты создания специализированного научного язык а, самым по-
пулярным и развитым из которых является Julia.
1.5 Области применения Python Будучи удачно спроектированным языком программирования, Python пре-
красно подходит для решения ежедневных реальных задач. Он и меет самый ши-
рокий спектр применений: как инструмент управления другим и программными
компонентами и для реализации самостоятельных программ. Ф актически, круг
ролей, которые может играть Python как многоцелевой язык пр ограммирования,
не включает только области встроенных устройств и системног о программирова-
ния, где ограничения на использование памяти и требования к скорости испол-
нения настолько велики, что время и удобство написания прог раммы не играют
существенной роли, причём можно нанять программистов скол ь угодно высокой
квалификации. За счёт чего Python получил столь широкое распространение? Python имеет
огромное количество высококачественных уже готовых модул ей, распространя-
емых бесплатно, которые вы можете использовать в любой части программы.
В модуле уже реализованы многие нужные вам детали программы . Написание
программы с использованием уже готовых модулей можно сравн ить со строи-
тельством сборного каркасного дома: отдельные детали: фун дамент, стены, кры-
ша, коммуникации уже сделаны до вас, вам нужно только выбрат ь подходящие
детали и собрать вместе. Модули подключаются при помощи коман дыimport ,
которая присутствует в начале каждого примера.
Все широко используемые модули делятся на две основные част и: модули
стандартной библиотеки, поставляемые вместе с интерпрета тором Python (эти
модули всегда с вами), и внешние модули, для которых сущес твуют средства
установки. Установка внешних модулей может быть осуществлена разными путями: в
Linux все популярные модули доступны для установки штатным и средствами
(например, через Центр установки и обновления программ в Ubuntu), для
Window и MacOS X доступны скомпилированные установочные фа йлы (напри-
мер, exe или msi для Windows). Можно также использовать возм ожности штат-
ного установщика внешних модулей pip, входящий в состав ста ндартных моду-
лей. С его помощью можно установить почти любой, даже редко ис пользуемый
внешний модуль, для которого нет скомпилированных пакетов под Linux или
установщиков под Windows. Недостатком последнего подхода является то, что
для установки модулей, написанных на других языках, наприм ер, С или Fortran,
pip требует наличия в системе компилятора этих языков, прич ём не абы какого,
а совместимого с тем, что использовал разработчик.

24Глава 1. Введение
1.5.1 Системное администрирование
Встроенные в Python интерфейсы доступа к службам операцион ных систем
(например, половина графического интерфейса Ubuntu написа на на Python) де-
лают его идеальным инструментом для создания переносимых пр ограмм и ути-
лит системного администрирования (иногда они называются ин струментами ко-
мандной оболочки). Программы на языке Python могут:
•Создавать, удалять, отыскивать, сортировать, перебирать файлы и катало-
ги в любой системе. Например, в Linux и MacOS разделительным з наком
при записи пути к файлу является /, а в Windows  \. Програ мма на
Python будет работать и там, так как умеет заменять слэши. Та к же в Linux
и MacOS есть один главный диск, а в Windows их может быть много (C,
D, E). Python автоматически подставляет над этими логическ ими дисками
один общий корень. Для этого используется стандартный моду льos.
Пример:
i mport o s#загружаем модуль
# Создаём список всех файлов и папок в текущей папке:
f i l e s d i r s = o s . l i s t d i r ( " . " )
# Печатаем имена только файлов:
f or f d in f i l e s d i r s :
if o s . p a t h . i s f i l e ( f d ) :
p rint ( f d , ’это файл ’ )
# Проверяем, есть ли в папке f o l d e r 1
i f not o s . p a t h . e x i s t s ( ’ F o l d e r 1 ’ ) :
# Если её нет, создаём её
o s . m k d i r ( ’ F o l d e r 1 ’ )
• Запускать другие программы. Например, автоочистку корзин ы или авто-
установку программ. Для этого используются стандартные мод ули sys, os,
subprocess. Пример, в котором из Python запускается популя рный бесплат-
ный редактор изображений Gimp, причём команда запуска выби рается в
зависимости от типа операционной системы:
i mport s y s
import s u b p r o c e s s
if s y s . p l a t f o r m = = ’ w i n 3 2 ’ :
s u b p r o c e s s . c a l l ( [ ’ C : / P r o g r a m Ђ F i l e s / G I M P Ђ 2 / b i n / g i m p - 2 . 8 . e x e ’ ] )
e lif s y s . p l a t f o r m = = ’ l i n u x ’ :
s u b p r o c e s s . c a l l ( [ ’ g i m p ’ ] )
• Производить параллельные вычисления с использованием нес кольких про-
цессов и потоков, для чего используется стандартный модуль multiproces-
sing .

1.5. Области применения Python25
•Осуществлять проверку имён пользователей и паролей на собл юдение по-
литики безопасности и делать многое другое.
При этом стандартная библиотека Python поддерживает все ти пичные ин-
струменты операционных систем: переменные окружения, фай лы, сокеты, кана-
лы, процессы, многопоточную модель выполнения, поиск по ша блону с исполь-
зованием регулярных выражений, аргументы командной строк и, стандартные
интерфейсы доступа к потокам данных, запуск команд оболочк и, дополнение
имен файлов и многое другое.
1.5.2 Написание графических интерфейсов пользователя
Простота Python и высокая скорость разработки делают его отл ичным сред-
ством разработки графического интерфейса. В состав Python входит стандарт-
ный модуль tkinter, позволяющий программам на языке Python реализовать
переносимый графический интерфейс с внешним видом, присущ им операцион-
ной системе. Графические интерфейсы на базе Python/tkinterбез изменений
могут использоваться в MS Windows, X Window (в oneрационных системах UNIX
и Linux) и Mac OS (как в классической версии, так и в OS X). Напишем простенькую программу для создания графического и нтерфейса с
кнопкой, надписью и полем ввода (рис. 1.2):
f rom t k i n t e r i mport *#подключение модуля t k i n t e r
r o o t = T k ( ) #создание главного окна
b t n = B u t t o n ( r o o t , t e x t = ’Кнопочка ’ , w i d t h = 1 0 , h e i g h t = 2 , b g = ’ w h i t e ’ , f g = ’ b l a c k ’ , f o n t = ’ A r i a l Ђ 1 4 ’ ) #создание кнопки
l a b = L a b e l ( r o o t , t e x t = ’Ваша фамилия : ’ ,
f o n t = ’ A r i a l Ђ 1 4 ’ ) #создание надписи
E d i t = E n t r y ( r o o t , w i d t h = 2 0 ) #создание поля ввода
b t n . p a c k ( ) #размещение кнопки на форме
l a b . p a c k ( ) #размещение надписи на форме
E d i t . p a c k ( ) #размещение поля ввода на форме
r o o t . m a i n l o o p ( ) #отображение главного окна
1.5.3 Веб-программирование Python традиционно используется для написания сложных сай тов. Самым по-
пулярным средством для этого служит веб-фреймворк (большо й набор модулей)
Django. С его помощью написаны некоторые очень известные са йты, включая
Instagram и сайт сообщества Mozilla. Django представляет м ножество различных
функций, включая средства для автоматического создания баз данных.
1.5.4 Программы для работы с базами данных В языке Python имеются интерфейсы доступа ко всем основным ре ляционным
базам данных: Sybase, Oracle, Informix, ODBC, MySQL, Postg reSQL, SQLite и

26Глава 1. Введение
Рис. 1.2. Пример простейшего графического приложения, описанного выше.
многим другим. В мире Python существует также переносимый п рикладной про-
граммный интерфейс баз данных, предназначенный для доступ а к базам данных
SQL из сценариев на языке Python, который унифицирует досту п к различным
базам данных.
Например, для базы данных SQLite необходимо подключить моду льsqllite3
( import sqlite3 ). Вот небольшая программа, которая создаёт соединение с ба -
зой данных, если БД не существует, то она будет создана, инач е файл будет
открыт:
i mport s q l i t e 3
c o n n = s q l i t e 3 . c o n n e c t ( ’ d a t a . d b ’ )
c r = c o n n . c u r s o r ( )
c r . e x e c u t e ( " " "CREATE TABLE IF NOT EXISTS ’romanus’
(’numerus’ INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
’nomen’ TEXT NOT NULL, ’praenomen’ TEXT,
’cognomen’ TEXT) " " ")
c r . e x e c u t e ( " " "INSERT INTO romanus VALUES
(1, ’Claudius’,’Tiberius’,’Nero’) " " ")
c o n n . c o m m i t ( )
c o n n . c l o s e ( )
В базу заносится одна запись.

1.6. Первая программа. Среда разработки27
1.5.5 Игры, искусственный интеллект
Python используется для разработки многих популярных игр. Ещё в первой
половине 2000-ых Python стал основным средством для написа ния внутренней
логики четвёртой игры серии Civilization. Сейчас число игр , содержащих в себе
интерпретатор Python и использующих его для реализации прог раммной логики,
редакторов сценариев и искусственного интеллекта, исчисл яется сотнями. Мно-
гие простые игры, браузерные игры и игры для мобильных устро йств использу-
ют модуль pygame, предоставляющий простой и удобный доступ к библиотекам
трёхмерной графики OpenGL и управления звуком OpenAL.
1.5.6 Программирование математических и научных вычислений
Python представляет собою удачный компромисс между языком общего на-
значения и математическими пакетами. Сам по себе чистый P ython пригоден
только для несложных вычислений. Ключевая особенность Python  его расширяемость. Это, пожал уй, самый
расширяемый язык из получивших широкое распространение. К ак следствие
этого, для Python не только написаны и приспособлены многоч исленные биб-
лиотеки алгоритмов на C и Fortran, но и имеются возможности ис пользования
других программных средств и пакетов, в частности, R и SciLa b, а также гра-
фопостроителей, например, Gnuplot и PLPlot.
Ключевыми модулями для превращения Python в математический пакет яв-
ляются numpy,matplotlib иscipy . Кроме них популярностью пользуются sympy
для символьных вычислений, ffnetдля построения искусственных нейронных
сетей, pyopencl /pycuda для вычисления на видеокартах и некоторые другие.
Возможности numpyиscipy покрывают практически все потребности в матема-
тических алгоритмах.
Одним из важнейших преимуществ Python является то, что все и звестные
его реализации, дополнительные специальные модули, в том ч ислеnumpy ,scipy
и matplotlib , а также большинство сред разработки распространяются своб од-
но. Это означает возможность всегда иметь любимое средство р азработки под
рукою.
1.6 Первая программа. Среда разработки. Интерактивный и
скриптовый режим. Примеры решения заданий
1.6.1 Установка Python Установка Python на компьютер зависит от используемой опера ционной си-
стемы. Существуют несколько основных подходов. Нужно поним ать, что следу-
ет различать базовую установку, включающую интерпретатор, с реду разработки
IDLE, а также стандартную библиотеку, и установку дополнит ельных модулей,
которых для Python написано очень много.

28Глава 1. Введение
Таблица 1.3. Способы установки Python
Базовая установка Дополнительные модули ОC
установщик с официального
сайтаhttps://python.org встроенный механизм pip,
любые Linux,
Windows,
MacOS X
использование специальных
сборок: WinPython, Pyzo,
Anakonda и др. частично встроены, расши-
рение затруднительно зависит от
сборки
установка штатными сред-
ствами ОС зависит от типа и версии ОС Linux,
MacOS X
Все эти способы имеют свои преимущества и недостатки:
•При установке с официального сайта в Linux и MacOS X вам придё тся
столкнуться с тем, что у вас будут 2 частично пересекающихся и нтерпре-
татора Python в системе. Дело в том, что эти две ОС частично ис пользуют
Python в своих целях и какой-то (часто не самый свежий) интер претатор по-
ставляется в комплекте. В результате, замена его свежим инт ерпретатором
с официального сайта может частично нарушить работу ОС (кон ечно, это-
го можно не допустить или поправить, но для новичка такой под ход может
стать фатальным). В Windows нет своего Python по умолчанию, п оэтому
установка базового функционала пройдёт штатно, но есть дру гая проблема:
многие полезные модули содержат код на других языках: в перв ую очередь
это Fortran и C, а также могут зависеть от внешних библиотек, также напи-
санных на других языках, например, библиотеки линейной алг ебры Lapack
или графической библиотеки QT. В Linux есть штатная возможн ость уста-
новить все нужные компиляторы и библиотеки средствами само й ОС, в
меньшей степени эта же возможность есть в Mac OSX, но Windows з десь
не предоставляет почти ничего, всё придётся искать и ставит ь своими ру-
ками.
• При использовании специализированных сборок вы получаете готовую и
настроенную среду программирования со множеством установ ленных мо-
дулей помимо стандартной библиотеки. Но если вы захотите чт о-то сверх
того, что там есть, вам придётся сильно помучаться. Часть сб орок, напри-
мер WinPython, ориентированы на определённую ОС.
• Установка штатными средствами ОС (через менеджер пакетов, например
Synaptic в Debian/Ubuntu/AltLinux)  лучший выбор пользоват еля Linux,
так как все устанавливаемые таким образом модули будут рабо тать штатно
почти наверняка, все необходимые библиотеки и компиляторы будут авто-
матически установлены и правильных версий. Редкие недоста ющие пакеты,
как правило, можно доставить через pip. Но в MacOS X такой спо соб слож-
но рекомендовать, поскольку число шатано доступных пакето в невелико, а

1.6. Первая программа. Среда разработки29
Рис. 1.3. Интерактивный режим среды разработки IDLE.
сами они часто очень древних версий. В Windows такой способ в овсе невоз-
можен.
Суммируя выше сказанное, мы будем рекомендовать пользоват елям Linux
пользоваться своим шатаным менеджером пакетов, а пользова телям Windows 
использовать стандартную сборку WinPython, включающую моду ли для мате-
матических и инженерных расчетов, построения графиков и мн огие другие, с
сайта http://winpython.github.io/ .
Помните, что Python и модули к нему  свободное программное о беспечение.
Вы можете выбирать способ установки и нужные вам модули наиб олее удобным
для вас способом и не думать ни о какой плате и лицензионных от числениях.
1.6.2 Интерактивный режим и первая программа После загрузки и установки Python открываем IDLE (среда раз работки на
языке Python, поставляемая вместе с дистрибутивом). Запус каем IDLE (изна-
чально запускается в интерактивном режиме). Далее последу ет приглашение к
вводу ( >>>).
Теперь можно начинать писать первую программу. Традиционн о, первой про-
граммой у нас будет Hello, world. Чтобы написать Hello, wor ld на Python,
достаточно всего одной строки:
> > >
p rint ( ’ H e l l o , Ђ W o r l d ’ )
Функция printвыводит данные на экран.
Интерпретатор выполняет команды построчно: пишешь строку , нажимаешь
, интерпретатор выполняет ее, наблюдаешь результат. Это оч ень удобно,
когда человек только изучает программирование или тестиру ет какую-нибудь
небольшую часть кода. Ведь если работать на компилируемом я зыке, то при-

30Глава 1. Введение
Рис. 1.4. Вывод надписи Hello, world в интерактивном режим е в среде разра-
ботки IDLE.
шлось бы сначала написать код на исходном языке программиро вания, затем
скомпилировать, и уже потом запустить исполняемый файл на в ыполнение.
Кстати, если интерпретатору Python дать команду import this(импортиро-
вать сам объект в себя), то выведется так называемый Дзен Python, иллю-
стрирующий идеологию и особенности данного языка. Считаетс я, что глубокое
понимание этого дзена приходит тем, кто сможет освоить язык Python в полной
мере и приобретет опыт практического программирования.
Хотя интерактивный режим будет вам ещё не раз полезен при напи сании и
отладке программ и тестировании возможностей языка, всё же он не является
основным. В большинстве случаев программист сохраняет код в файл, и запус-
кать уже файл. Такой режим работы называется скриптовый. Фа йлы с кодом на
Python обычно имеют расширение py.
Для того, чтобы создать новое окно для написании скрипта, в и нтерактивном
режиме IDLE выберите File→New File (или нажмите + N). В открыв-
шемся окне попробуйте ввести следующий код:
n a m e =
i nput ( ’Как вас зовут ? ’ )
print ( ’Привет , ’ , n a m e )
Функция inputсчитывает данные, введённые с клавиатуры, и записывает их в
переменную name.
Первая строка печатает вопрос (Как вас зовут?), ожидает, пока вы напе-
чатаете что-нибудь и нажмёте и сохраняет введённое значение в пере-
менной name.
Во второй строке используется функция print для вывода текс та на экран, в
данном случае для вывода "Привет, "и того, что хранится в переменной name.

1.6. Первая программа. Среда разработки31
Рис. 1.5. Скриптовый и интерактивный режим: в интерактивном режиме можно
видеть результаты выполнения скрипта.
Теперь нажмём F5 (или выберем в меню IDLE Run→Run Module ) и убедимся,
что написанное работает. Перед запуском IDLE предложит нам сохранить файл.
Сохраним туда, куда вам будет удобно, после чего программа з апустится.
Для сложения строк можно также воспользоваться оператор ом+:
p rint ( ’Привет , ’ + str ( n a m e ) + ’ ! ’ ) .
1.6.3 Задания
Задание 1 (Ввод/вывод данных) Здесь собраны задачи по сути учебные,
но полезные. Их выполнение позволит вам набить руку и выра ботать
необходимые навыки. Задания необходимо выполнить в интера ктивном
и скриптовом режимах. Выполнять следует все и по порядку.
Напишите программу:
1. последовательно запрашивающую ваши фамилию, имя, отчеств о и
выводящую их одной строкой в последовательности: фамилия →
имя →отчество;
2. последовательно запрашивающую ваши фамилию, имя, отчеств о и
выводящую их одной строкой в последовательности: имя →отче-
ство →фамилия;
3. преобразующую простую русскую фамилию в мужском роде в жен -
ский род (Петров →Петрова; Путин →Путина);
4. последовательно введите число, месяц, год рождения; выв едите да-
ту своего рождения через точки (01.01.2000), слэши (01/01/ 2000),
пробелы (01 01 2000), тире (01-01-2000).

Глава 2
Основные типы данныхВ Python имеется множество встроенных типов данных. Все тип ы делятся на
простые и составные. Переменные 1
простых типов состоят из единственного зна-
чения, к ним относятся числа (всего 3 типа: целые, действите льные и комплекс-
ные) и логические переменные. Переменные составных типов с остоят из набора
значений и, в свою очередь, делятся на неизменяемые, для кот орых нельзя из-
менять значения элементов, добавлять или изымать элементы , и изменяемые,
для которых всё это можно делать. К неизменяемым типам относ ятся строки и
кортежи, к изменяемым  списки, словари и множества.
Чтобы получить корректно работающую программу, важно поним ать, к ка-
кому типу относится переменная. В Python тип переменной не о бъявляется, а
автоматически определяется при присвоении ей значения.
2.1 Числа. Арифметические операции с числами. Модуль
math
Числа в Python делятся на:
• целые,
• действительные (с плавающей точкой размером в 64 бита),
• комплексные (с плавающей точкой размером в 128 бит).
1
Строго говоря, переменных в классическом смысле в Python нет, а естьимена, связан-
ные с некоторыми объектамив памяти. Но использование термина переменная удобно и
принято в программировании. Под переменными мы будем поним ать именно сами объекты.
Называть переменными имена неудобно, так как на протяжении работы программы одно и то
же имя может быть сопоставлено разным объектам, поэтому пол училось бы, что переменные
имеют переменный тип или не имеют его вовсе, что создаёт пута ницу, так как типы активно
используются в Python. Для краткости, однако, мы будем иног да употреблять выражения типа
переменная a, подразумевая объект, имеющий в данный момент имя a, в тех случаях, когда
это не создаёт путаницы.

2.1. Числа. Арифметические операции с числами. Модульmath33
Python поддерживает динамическую типизацию, то есть тип пер еменной
определяется только во время исполнения. Переменная может быть переопре-
делена, при этом её тип изменится:
> > > a = 2
> > > a
2 > > > a = 2 . 0
> > > a
2 . 0 > > > a = 2 + 3 j
> > > a
( 2 + 3 j )
Инструкция a = 2создаёт числовой объект-переменную с целочисленным
значением 2 и присваивает ему имя a. Далее инструкция a = 2.0создаёт новый
числовой объект с действительным значением 2.0 и присваива ет уже ему имяa.
А объект со значением 2 удаляется из памяти автоматически сб орщиком мусо-
ра (англ. garbage collector, специальный процесс, периоди чески освобождающий
память, удаляя объекты, которые уже не будут востребованы п риложениями),
т. к. была потеряна последняя ссылка на этот объект. Затем ин струкцияa=2+3j
создаёт числовой объект с комплексным значением и всё с тем ж е именем, а
объект с действительным значением удаляется.
В интерактивном режиме есть возможность быстро вызвать пре дыдущую ко-
манду сочетанием + p. Поэтому легко можно поправить a=2наa=2.0 .
При операциях с числами существует общее правило: результа т будет того
же типа, что и операнды, если операнды разных типов, то резул ьтат будет при-
ведён к наиболее общему из всех имеющихся. Порядок общности е стественный:
целые →действительные →комплексные . Следующий пример иллюстрирует это
правило:
> > > a = 2
> > > b = 2 + 3 j
> > > a + b
( 4 + 3 j )
Так же полезно запомнить, что для проверки типа любого значен ия и любой
переменной можно использовать функцию type():
> > > a = 5
> > > b = 1 7 . 1
> > > c = 4 + 2 j
> > >
t ype ( a ) ; type ( b ) ; type ( c )
<
lass ’ i n t ’ >
<
lass ’ f l o a t ’ >
<
lass ’ c o m p l e x ’ >

34Глава 2. Основные типы данных
Приведённая программа имеет особенность: в четвёртой стро ке записано сра-
зу 3 оператора. Так можно делать, но при этом для разделения о ператоров нужно
использовать ; (после последнего она не обязательна). Пр обелы в большинстве
случаев необязательны.
Можно явно преобразовывать значение любого типа с помощью со ответству-
ющих функций int(),float() илиcomplex() :
> > > a = 5
> > >
i nt ( a )
5
> > >
f loat ( a )
5 . 0
> > >
omplex ( a )
( 5 + 0 j )
Важно помнить, что комплексное число нельзя преобразовать с помощью функ-
ций int() иfloat() к целому или действительному. Функция int()отбрасывает
дробную часть числа, а не округляет его:
> > > a = 4 . 3
> > >
i nt ( a )
4 > > > b = - 4 . 3
> > >
i nt ( b )
- 4
А теперь про подводные камни и отличие третьего Python от вто рого при ра-
боте в скриптовом (текстовом) режиме. Напишем в текстовом р ежиме в Python
3.x простую программу, которая должна складывать два введё нных числа и вы-
водить результат на экран:
a =
i nput ( ’Введите первое число : ’ )
b =
i nput ( ’Введите второе число : ’ )
print ( a + b )
Ход работы программы:
Введите первое число : 1 0
Введите второе число : 4 1 0 4
Получили совсем не то, что ожидали. Python версий 2.x поддер живал авто-
матическое определение типа переменной при вводе с клавиат уры. Однако это
часто вызывало различные ошибки или сложности. Поэтому при проектирова-
нии версии 3.0 было решено отказаться от автоматического оп ределения типа
и всегда считывать данные как строку. Поэтому, если мы хотим действительно
сложить два числа, программу придется переписать:

2.1. Числа. Арифметические операции с числами. Модульmath35
a = i nt (i nput ( ’Введите первое число : ’ ) )
b =
i nt (i nput ( ’Введите второе число : ’ ) )
print ( a + b )
Вывод программы:
Введите первое число : 1 0
Введите второе число : 4 1 4
Python поддерживает все основные арифметические оператор ы (см. табл. 2.1).
Таблица 2.1. Арифметические операции с числами и встроен- ные функции c одним и двумя аргументами
x + y Сложение  сумма xиy(2 + 3 = 5 )
x - y Вычитание  разность xиy(5 - 2 = 3 )
x * y Умножение  произведение xиy(2 * 3 = 6 )
x / y Делениеxна y: 4 / 1.6 = 2.5 ,10 / 5 = 2.0 , результат всегда
типа float
x // y Деление xна yнацело: 11 // 4 = 2 ,11.8 // 4 = 2.0 , результат
целый, только если оба аргумента целые
x % y Остаток от деления: 11 % 4 = 3,11.8 % 4 = 3.8000000000000007
(присутствует ошибка, связанная с неточностью представле ния
данных в компьютере)
x ** y Возведение xв степень y: ( 2 ** 3 = 8 )
abs(x) Модуль числа x
round(x) Округление (round(11.3) = 11 )
round(x, n) Округляет число x до n знаков после запятой: round(12.34567,
3) = 12.346
pow(x, y) полный аналог записи x ** y
divmod(x, y) выдаёт два числа: частное и остаток, обращаться следует так :
q, r = divmod(x, y)
Отметим, что операции сложения, вычитания, умножения и воз ведения в сте-
пень выдают ответ типа intтолько если оба аргмента целые, типа float, если
один из аргументов действительный, а другой  целый или дейс твительный, и
типа complex , если хотя бы один аргумент комплексный. Операция возведен ия
в степень также может выдать комплексный результат при возв едении отрица-
тельных чисел в степень кроме случая, когда эта степень цела я и нечётная. То
есть, эти опраторы в Python подчиняются общеупотребительны м правилам пре-
образования типов.

36Глава 2. Основные типы данных
Оператор деления традиционно является проблемным: резу льтат его рабо-
ты в разных языках программирования определяется разными п равилами. Для
Python версии 3.x деление / всегда действительного типа. В Python версии
2.x деление подчинялось другому правилу: если оба операнда целые  результат
будет целый, иначе  действительный. Приведём небольшую пр ограмму–пример
для иллюстрации работы операторов /, // и % на Python 3.4.3:
> > > a = 5 ; b = 9 8
> > > c 1 = b / a ; c 2 = b / / a ; c 3 = b % a
> > > c 1 ; c 2 ; c 3
1 9 . 6
1 9
3
Таблица 2.2. Встроенные функции c последовательностями ил и
произвольным числом аргументов
max(a, b,...) Максимальное число из двух или более: max([2, 6, 3]) = 6
min(a, b,...) Минимальное число из двух или более:min([2, 6, 3]) = 2
max(seq) Максимальный элемент последовательности: max([2,6,3]) =6
min(seq) Минимальный элемент последовательности:min([2, 6, 3])=2
sum(seq) Сумма элементов последовательности, например, кортежа
sum((2, 6, 3)) = 11или спискаsum([2, 6, 3]) = 11
sorted(seq) Отсортированный список: sorted([3, 2, 5, 1, 4]) = [1,
2, 3, 4, 5]
То, что описанные функции являются встроенными, означает, ч то они доступ-
ны без всяких дополнительных действий. Однако встроенных ф ункций немного,
гораздо больше функций находится в стандартной библиотеке наборемоду-
лей , поставляемых всегда вместе с интерпретатором Python. Фун кции для ра-
боты с числами находятся в модулях mathдля целых и действительных чисел
и cmath для комплексных. Сделано это потому, что комплексные числа нужны
гораздо реже целых и действительных, а Python часто использ уется в качестве
языка сценариев и в других приложениях, где память нужно эко номить. Самые
употребительные функции модуля mathописаны в таблице 2.3.
Загрузка модулей в Python осуществляется с помощью операто раimport .
Самый простой способ его использования  загрузить всё соде ржимое модуля
глобально:
f rom m a t h i mport *
t = s i n ( p i / 6 )

2.1. Числа. Арифметические операции с числами. Модульmath37
Таблица 2.3. Наиболее употребительные функции и константы
модуляmath
trunc(X) Усечение значения Х до целого
sqrt(X) Квадратный корень из X
exp(X) Экспонента числа Х
log(X),log2(X) ,log10(X) Натуральный, двоичный и десятичный логариф-
мы X
log(X, n) Логарифм X по основанию n
sin(X) ,cos(X) ,tan(X) Синус, косинус и тангенс X, X указывается в ра-
дианах
asin(X) ,acos(X) ,atan(X) Арксинус, арккосинус и арктангенс X
atan2(X, Y) арктангенс отношения X Y
с учётом квадранта degrees(X) Конвертирует радианы в градусы
radians(X) Конвертирует градусы в радианы
sinh(X)
,cosh(X) ,tanh(X) Гиперболические синус, косинус и тангенс X
asinh(X) ,acosh(X) ,atanh(X) Обратный гиперболический синус, косинус и
тангенс X
hypot(X, Y) Гипотенуза треугольника с катетами X и Y
factorial(X) Факториал числа Х
gamma(X) Гамма-функция Х
pi Выдаётся число
e Выдаётся числоe
v = l o g ( e )
p rint ( t , v )
Первую строчку можно прочитать дословно: из модуля mathимпортируем всё
( * означает всё). Такая запись позволяет в теле программы про сто обращаться
к функциям, лежащим в math, без сложной записи: math.sin.
Но такой способ подойдёт только для первых двух-трёх заняти й, на которых
будет использоваться один модуль math. При подключении двух, трёх и более мо-
дулей может возникнуть такая ситуация, когда в разных модул ях лежат функции
с одинаковыми названиями (например, open), но делают они разные действия,
да и аргументы вызываются в разном порядке. В такой ситуации, да и просто
академически правильнее, писать следующим образом:
i mport m a t h
t = m a t h . s i n ( m a t h . p i / 6 )
v = m a t h . l o g ( m a t h . e )
p rint ( t , v )

38Глава 2. Основные типы данных
Если название модуля слишком длинное, или оно вам не нравитс я по каким-то
другим причинам, то для него можно создать псевдоним с помощ ью ключевого
слова as:
i mport m a t p l o t l i b . p y p l o t a s p l t
p l t . p l o t ( x )
2.2 Строки Строки в Python  упорядоченные последовательности символ ов, используе-
мые для хранения и представления текстовой информации, поэ тому с помощью
строк можно работать со всем, что может быть представлено в т екстовой форме.
При этом отдельного символьного типа в Python нет, символ  э то строка длины
1. Более того, символы как элементы строки тоже являются стро ками.
Работа со строками в Python очень удобна. Существует нескол ько вариантов
написания строк:
> > > S 1 = ’ A l i c e Ђ s a i d : Ђ " H i , Ђ A n n e ! " ’
> > > S 2 = " A n n e Ђ a n s w e r e d : Ђ ’ H i , Ђ A l i c e ’ "
Строки в апострофах и в кавычках (иногда говорят одинарных и двойных
кавычках)  это одно и то же. Причина наличия двух вариантов в том, чтобы
позволить вставлять в литералы строк символы кавычек или ап острофов.
Строки можно писать в тройных кавычках или апострофах. Глав ное досто-
инство строк в тройных кавычках в том, что их можно использов ать для записи
многострочных блоков текста:
> > > S = ’ ’ ’Это
длиннаястрока ’ ’ ’
> > > S
’Это \ n длинная \ n строка ’ > > >
p rint ( S )
Это длинная строка
Внутри такой строки возможно присутствие кавычек и апостро фов, главное, что-
бы не было трёх кавычек подряд. Символ ’\n’означает перевод строки на одну
вниз (кнопка ) и разделяет строки текстовых файлов. Заметим, что в
Windows принято использовать 2 разделительных символа под ряд:’\r\n’ , а в
Mac OS X  только ’\r’, но почти все современные редакторы (за исключе-
нием Блокнота Windows) без труда справляются с файлами, за писанными с
использованием чужих разделителей. Все строки в Python являются юникодом, то есть разрешено испол ьзование
любых символов национальных алфавитов, которые вы сможете н абрать (и даже

2.2. Строки39
многих, для которых нет соответствующих клавиш на клавиатуре). При этом ис-
пользуется внутреннее представление UTF32, то есть все симв олы имеют длину
4 байта, что экономит процессорное время, а запись в файл и чт ение из файла
происходят в кодировке UTF8, что обеспечивает совместимост ь со старою коди-
ровкою ASCII и уменьшает потребление памяти.
Здесь уместно упомянуть о том, как в Python при написании код а программы
делать комментарии. Однострочные комментарии начинаются с о знака решетки
#, многострочные  начинаются и заканчиваются тремя двойными кавычками
""" .
Числа могут быть преобразованы в строки с помощью функции str(). На-
пример, str(123) даст строку ’123’. Если строка является последовательностью
знаков-цифр, то она может быть преобразована в целое число в помощью функ-
ции int() :int(’123’) даст в результате число 123, а в вещественное с помощью
функции float():float(’12.34’) даст в результате число 12.34. Для любого
символа можно узнать его номер (код символа) с помощью функц ииord() , на-
пример, ord(’s’) даст результат 115. И наоборот, получить символ по числовом у
коду можно с помощью функции chr(), например chr(100)даст результат ’d’.
2.2.1 Базовые операции над строками Существуют несколько различных подходов к операциям над стр оками.
• Арифметические операции. Для строк подобно числам опреде лены опе-
раторы сложения +и умножения ∗. В результате сложения содержимое
двух строк записывается подряд в новую строку, например:
> > > S 1 = ’ P y ’
> > > S 2 = ’ t h o n ’
> > > S 3 = S 1 + S 2
> > >
p rint ( S 3 )
P y t h o n
Можно складывать несколько строк подряд.
Умножение определено для строки и целого положительного чис ла, в ре-
зультате получается новая строка, повторяющая исходную сто лько раз, ка-
ково было значение числа (возьмём строку S3из прошлого примера):
> > > S 3 * 4
’ P y t h o n P y t h o n P y t h o n P y t h o n ’ > > > 2 * S 3
’ P y t h o n P y t h o n ’
• Функция len()вычислят длину строки, результат имеет целочисленный
тип. Например, len(’Python’)выдаст 6.

40Глава 2. Основные типы данных
•Доступ по индексу. Можно обратиться к любому элементу (символу) стро-
ки по его номеру, нумерация начинается с 0 (первый элемент ст рокиS
имеет номер 0, последний  len(S)-1. Разрешается использовать отрица-
тельные индексы, в этом случае нумерация происходит с конца, что можно
также интерпретировать как правило: к отрицательным индек сам всегда
добавляется длина строки, например последний элемент стро ки чаще всего
обозначают как -1):
> > > S = ’ P y t h o n ’
> > > S [ 0 ]
’ P ’
> > > S [ - 1 ]
’ n ’
Обращение к символу с несуществующим номером порождает ошиб ку:
IndexError: string index out of range .
При использовании индексов необходимо помнить, что строки в Python от-
носятся к категории неизменяемых последовательностей: не льзя поменять
значение того или иного символа, а можно лишь создать новую с троку.
> > > S = ’Ура ’
> > > S [ 1 ] = ’х ’ T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 6 8 > " , l i n e 1 ,
i n < m o d u l e >
S [ 1 ] = ’х ’
T y p e E r r o r : ’ s t r ’
o bje
t d o e s not s u p p o r t i t e m a s s i g n m e n t
> > > S = S [ 0 ] + ’x ’ + S [ 2 ]
> > > S
’Уxа ’
• Срезы позволяют скопировать или использовать в выражениях часть с тро-
ки. Оператор извлечения среза из строки выглядит так: S[n1:n2].n1 
это индекс начала среза, а n2 его окончания, причем символ с номером
n2 в срез уже не входит! Если указан отрицательный индекс, это з начит,
что любой индекс -nаналогичен записи len(s)-n. Если отсутствует пер-
вый индекс, то срез берётся от начала до второго индекса; при отсутствии
второго индекса срез берётся от первого индекса до конца стр оки:
> > > D a y = ’ m o r n i n g , Ђ a f t e r n o o n , Ђ e v e n i n g ’
> > > D a y [ 0 : 7 ]
’ m o r n i n g ’
> > > D a y [ 9 : - 9 ]
’ a f t e r n o o n ’ > > > D a y [ - 7 : ]
’ e v e n i n g ’

2.2. Строки41
Можно извлекать символы не подряд, а через определённое количество. В
таком случае оператор индексирования выглядит так: [n1:n2:n3];n3  это
шаг, через который осуществляется выбор элементов:
> > > f l a g = ’Красный Голубой Белый ’
> > > f l a g [ : : 8 ]
’КГБ ’
Обратите внимание, что в срезе строки sмогут быть пропущены и первый,
и второй индексы одновременно: вместо них подставляются 0и len(s) со-
ответственно.
• Оператор inпозволяет узнать, принадлежит ли подстрока в строке. Опе-
ратор возвращает логическое значение: True, если элемент в составе строки
встречается и False, если нет:
> > > S = ’ P y t h o n ’
> > > S u b S = ’ t h ’
> > > S u b S
i n S
T r u e
• Функции minиmax применимы также и к строкам: max(s)определяет и
выводит (возвращает) символ с наименьшим кодом  номером в к одовой
таблице. Например:
> > > S = ’ P y t h o n ’
> > >
m in ( S )
’ P ’
Возвращает символ с наибольшим значением (кодом). Наприме р:
> > > S = ’ P y t h o n ’
> > >
m ax ( S )
’ y ’
2.2.2 Методы строк Кроме операторов, функций и срезов значительное количеств о операций над
строками доступно в виде методов. Основное различие методов и функций 
синтаксическое; так, большинство методов ранее являлись ф ункциями стандарт-
ного модуля string, в котором теперь остались почти только различные кон-
станты. Обратите внимание, как записываются методы объекта :объект.метод() ,
например, S.isdigit() . Методы  это по сути функции, у которых в качестве
первого аргумента выступает сам объект, метод которого выз вается. Например,
вызов метода S.isdigit()выдаст логическое значение: True, если все символы
строки Sи False иначе.

42Глава 2. Основные типы данных
Таблица 2.4. Базовые операции над строками
Операция Описание
S1 + S2 Объединение двух или более строк в новую строку.
S * n Умножение строки на целое числоn многократное повторение
строки.
len(S) Функция, вычисляющая длину строки S.
S[n] Доступ по индексу (номеру) к любому символу строки.
S[n1:n2:n3] Срез  новая строка, являющаяся частью исходной и содержа-
щая символы с номерами от n1включительно до n2невключи-
тельно, если n3присутствует (может не быть), то берутся не все
символы, а с шагом n3.
S2 in S1 Логический оператор, проверяющий, является ли строка S2ча-
стью строки S1.
min(S) Функция, вычисляющая символ строки Sс наименьшим кодом.
max(S) Функция, вычисляющая символ строки Sс наибольшим кодом.
Бывают методы, как описанный выше, не требующие вовсе никаких аргумен-
тов, бывают с одни аргументом, например метод S1.endswith(S2)требует 1 ар-
гумент  строку  и проверяет, заканчивается ли строка S1строкою S2. Бывают
методы с двумя аргументами, например S1.replace(S2, S3), который заменяет
в исходной строке S1содержащуюся в ней подстроку S2новою подстрокою S3и
выдаёт новую строку, при этом S1остаётся неизменною. Более полную инфор-
мацию о строковых методах можно получить, введя в интеракти вном режиме
команду help(str) .
2.3 Условия и логические операции
2.3.1 Логический (булевский) тип. Операторы сравнения. Логические операторы
Логический (булевский) тип может принимать одно из двух зна ченийTrue
(истина) или False(ложь). В языке Python булевский тип данных обозначается
как bool , для приведения других типов данных к булевскому существуе т функ-
ция bool() , работающая по следующим соглашениям:
• строки: пустая строка  ложь, непустая строка  истина.
• числа: нулевое число  ложь, ненулевое число (в том числе и ме ньшее
единицы)  истина.

2.3. Условия и логические операции43
•функции  всегда истина.
Для работы с алгеброй логики в Python кроме логического типа данных
предусмотрены операторы сравнения:
•> больше,
• < меньше,
• == равно (одиночное = зарезервировано за оператором присваива-
ния),
• ! = не равно,
• > = больше или равно,
• < = меньше или равно.
Вот простенькая программа, вычисляющая различные логическ ие выражения:
x = 1 2 - 5 h 1 = x = = 4
h 2 = x = = 7
h 3 = x ! = 7
h 4 = x ! = 4
h 5 = x > 5
h 6 = x < 5
p rint ( h 1 , h 2 , h 3 , h 4 , h 5 , h 6 )
Её вывод: F a l s e T r u e F a l s e T r u e T r u e F a l s e
Как видим, сравнивать особенно по равенству/неравенству м ожно всё, что угод-
но, включая типы данных. Обратите внимание, что оператор при сваивания имеет
самый низкий приоритет, поэтому расстановка скобок вокруг логических опера-
торов и операторов сравнения не требуется.
Из логических переменных и выражений можно строить более сл ожные (со-
ставные) логические выражения с помощью логических операт оров:not(отри-
цание, логическое НЕ), or(логическое ИЛИ) и and(логическое И):
• x and y  логическое И (умножение). Принимает значение True(исти-
на), только когда x = Trueиy = True . Принимает значение False(ложь),
если хотя бы одна из переменных равна False, или обе переменные False.
• x or y  логическое ИЛИ (сложение). Принимает значение True(исти-
на), если хотя бы одна из переменных равна True, или обе переменные True.
Принимает значение False(ложь), если x == y == False .

44Глава 2. Основные типы данных
A not A
True False
False True
A B A and B A or B
True True True True
True False False True
False True False True
False False False False
Таблица 2.5. Таблицы истинности логических функций для лог ического типа.
• not x  логическое НЕ (отрицание). Принимает значение True(истина),
если x == False . Принимает значение False(ложь), если x == True.
Правила работы логических операторов можно также задать с п омощью таблиц
истинности, в которых указывается истинность составного в ыражения, в зави-
симости от значений исходных простых выражений.
Следует отметить, что логические операции в Python определ ены для объ-
ектов любых типов , но результаты таких операций для операторов andиor не
всегда легко понятны (оператор notработает достаточно просто, он приводит ар-
гумент к логическому значению по описанным в начале этого ра здела правилам
и выдаёт всегда только логическое значение). Вот пример:
> > > [ 1 , 2 ]
a nd [ 1 ] and 1 3
1 3
> > > [ 1 , 2 ]
a nd [ 1 ] or 1 3
[ 1 ]
Здесь все три объекта: [1, 2],[1] и13 будут интерпретироваться как истина,
поскольку списки не пустые, а число не равно нулю. Но в первом с лучае в резуль-
тате вычисления выражения получится число, а во втором  оди н из списков.
Поэтому мы рекомендуем программистам не использовать логи ческие операторы
в выражениях с нелогическими объектами, либо преобразовыв ать эти объекты
к логическому типу напрямую с помощью функции bool():
> > >
b ool ( [ 1 , 2 ] ) and bool ( [ 1 ] ) or bool ( 1 3 )
T r u e > > >
b ool ( [ 1 , 2 ] ) and bool ( [ 1 ] ) and bool ( 1 3 )
T r u e
Логические операторы andиor в Python используются существенно реже,
чем во многих других популярных языках программирования, н апример Java,
C/C++ или Pascal/Delphi, потому что в Python можно делать люб ые двойное,
тройные и т. д. сравнения, например, a < x < bэквивалентно (x > a) and (x <
b) .
Рассмотрим пример, в котором используются логические опера торы и функ-
ции.

2.3. Условия и логические операции45
Пример задачи 1Трое друзей, болельщиков автогонок Формула–1,
спорили о результатах предстоящего этапа гонок.
 Вот увидишь, Шумахер не придет первым,  сказал Джон.  Пер-
вым будет Хилл.
 Да нет же, победителем будет, как всегда, Шумахер,  воскли кнул
Ник.  А об Алези и говорить нечего, ему не быть первым.
Питер, к которому обратился Ник, возмутился:  Хиллу не вида ть
первого места, а вот Алези пилотирует самую мощную машину.
По завершении этапа гонок оказалось, что предположения дву х друзей
подтвердились, а предположения одного из трёх неверны. Кто выиграл
этап гонки?
Решение задачи 1 Введем обозначения для логических высказываний: S по-
бедит Шумахер; H победит Хилл; A победит Алези.
Реплика Ника Алези пилотирует самую мощную машину не содер жит ни-
какого утверждения о месте, которое займёт этот гонщик, поэ тому в дальнейших
рассуждениях не учитывается.
Зафиксируем высказывания каждого из друзей:
•Джон: v1 = not S and H ;
• Ник: v2 = S and not A ;
• Питер: v3 = not H .
Учитывая то, что предположения двух друзей подтвердились, а предположения
одного из трёх неверны, запишем логическую функцию:
f = v 1
a nd v 2 and not v 3 or v 1 a nd not v 2 and v 3 \
or not v 1 and v 2 and v 3
В алгебре логики существует возможность доказательства ут верждения методом
перебора. Утверждение истинно, если при подстановке любых зн ачений перемен-
ных оно превращается в верное тождество. Этот метод перебор а не слишком тру-
доемок, поскольку переменные могут принимать только значе нияFalse иTrue .
Логическая функция от n аргументов может быть задана таблиц ей, в которой
перечислены все возможные наборы из FalseиTrue длины nи для каждого
из них рассчитано значение функции. Пусть эту таблицу нам ав томатически
составит программа на Python:
f or S in ( F a l s e , T r u e ) :
f or H in ( F a l s e , T r u e ) :
f or A in ( F a l s e , T r u e ) :
v 1 =
n ot S and H
v 2 = S
a nd not A
v 3 =
n ot H

46Глава 2. Основные типы данных
f = v 1 a nd v 2 and not v 3 or \
v 1
a nd not v 2 and v 3 or \
n ot v 1 and v 2 and v 3
p rint ( S , H , A , f )
Здесь использован оператор цикла for, подробнее изложенный в следующей гла-
ве. Оператор \позволяет перенести часть кода на следующую строчку, число
начальных пробелов в которой неважно.
Вывод программы:
F a l s e F a l s e F a l s e F a l s e
F a l s e F a l s e T r u e F a l s e
F a l s e T r u e F a l s e F a l s e
F a l s e T r u e T r u e F a l s e
T r u e F a l s e F a l s e T r u e
T r u e F a l s e T r u e F a l s e
T r u e T r u e F a l s e F a l s e
T r u e T r u e T r u e F a l s e
Из таблицы видно, что заданное утверждение истинно ( Trueв четвёртом
столбце) только при S==True,H==False ,A==False . Значит ответ на задачу: побе-
дил Шумахер.
Обратите внимание на отступы, Python к ним чрезвычайно чувс твителен. Де-
ло в том, что в Python фактически нет операторных скобок типа begin/end(как
в Pascal) или {} (как в Cи-подобных языках), их роль выполняют отступы
(роль открывающейся скобки в некотором смысле выполняет :). Если после-
дующая строчка сдвинута по отношению к предыдущей вправо  зн ачит, то, что
на ней написано, представляет собою блок (часть кода, котор ая сгруппирована
и воспринимается как единое целое). Принято и очень рекомен дуется делать по
4 пробела на каждый уровень вложенности. При работе в IDLE и G eany редак-
тор сам поставит нужный отступ, если вы не забудете : в конц е предыдущей
строки, клавиша позволит вернуться на один уровень назад.
Форматирование  очень важный момент при программировании на Python.
Если вы поставите хотя бы один лишний пробел в начале строки, программа во-
обще не запустится, выдав Indentation Error ошибку расстановки отступов,
указав на первую строку, где с точки зрения интерпретатора в озникла ошибка.
2.3.2 Условный оператор if
Поведение реальных программ должно зависеть от входных дан ных. Напри-
мер, в рассмотренной ранее задаче о преобразовании мужской формы фамилии в
женскую добавление символа а вовсе не единственный вариа нт: если мужская
форма заканчивается на ой, ый или ий, нужно это оконча ние отбросить
и добавить соответственно ая или яя. Чтобы программа мо гла осуществить
такой выбор, она должна уметь проверять условия, для чего во всех языках
программирования есть условный оператор.

2.3. Условия и логические операции47
В Python простейшая форма условного оператора имеет вид2
:
i f <логическое выражение > :
<действия, выполняемые, когда логическое
выражение принимает значение T r u e >
В такой форме действия после двоеточия выполняются, если лог ическое вы-
ражение истинно. Если же оно ложно, программа ничего не дела ет и переходит
к оператору, следующему за if. Когда нужно выполнить различные действия,
если условие истинно и если оно ложно, используется следующа я более полная
форма:
i f <логическое выражение > :
<действия, выполняемые, когда логическое
выражение принимает значение T r u e >
e lse :
<действия, выполняемые, когда логическое
выражение принимает значение F a l s e >
Наконец, если нужно последовательно проверить несколько у словий, исполь-
зуется форма с дополнительным оператором elif(сокращение от else if):
i f <логическое выражение > :
<действия, выполняемые, если логическое
выражение принимает значение T r u e >
e lif <второе логическое выражение > :
<действия, выполняемые, если второе логическое
выражение принимает значение T r u e >
e lif <третье логическое выражение > :
<действия, выполняемые, если третье логическое
выражение принимает значение T r u e >
. . .
e lse :
<действия, выполняемые, если ни одно из
логических выражений не принимает значение T r u e >
Дополнительных условий и связанных с ними блоков elifможет быть сколь-
ко угодно, но важно отметить, что в такой сложной конструкци и будет выполнен
всегда только один блок кода. Другими словами, как только не которое условие
оказалось истинным, соответствующий блок кода выполняется , и дальнейшие
условия не проверяются.
Обратите внимание, что после двоеточия в конструкциях типа if,else ,elif
всегда идёт блок, выделенный отступом вправо. Большинство редакторов кода,
в том числе и IDLE, делают этот отступ автоматически. То, что в ыделено отсту-
пами, и есть телооператора, а то, что до двоеточия, называется заголовком.
2
Вообще говоря, выражение может быть вовсе не логическим, в э том случае оно будет
приведено к логическому типу по ранее приведённым правилам .

48Глава 2. Основные типы данных
Приведём простой пример. Следующая простая программа прове ряет, делит-
ся ли первое введённое число на второе нацело:
a =
i nt (i nput ( ’Введите первое число : ’ ) )
b =
i nt (i nput ( ’Введите второе число : ’ ) )
if a % b = = 0 :
p rint ( " Y e s " )
else :
p rint ( " N o " )
2.4 Списки Любой язык программирования обязан поддерживать составные типы дан-
ных, где одна переменная может содержать как контейнер неск олько  в лучшем
случае произвольно много  единиц информации. Для этой цели в Python суще-
ствуют несколько типов данных, самым базовым из которых явля ется список.
Списки в языке программирования Python, как и строки, являют ся упорядо-
ченными последовательностями значений. Однако, в отличие от строк, списки
состоят не из символов, а из различных объектов (значений, д анных), и заклю-
чаются не в кавычки, а в квадратные скобки [ ]. Объекты отделяются друг от
друга с помощью запятой.
Списки могут состоять из различных объектов: чисел, строк и даже других
списков. В последнем случае, списки называют вложенными. Во т некоторые при-
меры списков:
[ 1 5 9 , 1 5 2 , 1 4 0 , 1 2 8 , 1 1 3 ] #список целых чисел
[ 1 5 . 9 , 1 5 . 2 , 1 4 . 0 , 1 2 8 . , 1 1 . 3 ] #список вещественных чисел
[ ’Даша ’ , ’Катя ’ , ’Ксюша ’ ] #список строк
[ ’Саратов ’ , ’Астраханская ’ , 1 0 4 , 1 8 ] #смешанный список
[ [ 1 , 0 , 0 ] , [ 0 , 1 , 0 ] , [ 0 , 0 , 1 ] ] #список списков
Как и над строками, над списками можно выполнять операции со единения и
повторения:
> > > [ 6 , ’октябрь ’ , 2 0 1 5 ] + [ 1 6 , ’декабрь ’ , 2 0 1 5 ]
[ 6 , ’октябрь ’ , 2 0 1 5 , 1 6 , ’декабрь ’ , 2 0 1 5 ]
> > > [ 2 , 3 , 4 ] * 2
[ 2 , 3 , 4 , 2 , 3 , 4 ]
По аналогии с символами (элементами) строки можно получать доступ к эле-
ментам списка по их индексам, складывать их, извлекать срез ы, измерять длину
списка, узнавать тип данных:
> > > l i s t 1 = [ ’ P ’ , ’ y ’ , ’ t h ’ , ’ o ’ , ’ n ’ , 3 . 4 ]
> > >
l en ( l i s t 1 )
6

2.4. Списки49
> > > l i s t 1 [ 0 ] + l i s t 1 [ 1 ]
’ P y ’ > > > l i s t 1 [ 0 ]
’ P ’ > > > l i s t 1 [ 0 : 5 ]
[ ’ P ’ , ’ y ’ , ’ t h ’ , ’ o ’ , ’ n ’ ]
> > > l i s t 1 [ 5 : ]
[ 3 . 4 ]
> > >
t ype ( l i s t 1 )
<
lass ’ l i s t ’ >
Обратите внимание, что нумерация элементов всегда начинае тся с нуля, поэтому
нулевой элемент это ’P’.
В отличие от строк, списки  это изменяемые последовательно сти. Если пред-
ставить строку как объект в памяти, то когда над ней выполняют ся операции
конкатенации и повторения, то эта строка не меняется, а в рез ультате операции
создаётся другая строка в другом месте памяти. В строку нель зя добавить но-
вый символ или удалить существующий, не создав при этом новой строки. Со
списком дело обстоит иначе. При выполнении операций новые с писки могут не
создаваться, а будет изменяться непосредственно оригинал . Из списков можно
удалять элементы, добавлять новые. При этом следует помнит ь, многое зависит
от того, как вы распоряжаетесь переменными. Символ в строке изменить нельзя, элемент списка  можно:
> > > m y s t r = ’ P y t h o n ’
> > > m y l i s t = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > m y s t r [ 1 ] = ’ i ’ T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 2 > " , l i n e 1 ,
i n < m o d u l e >
m y s t r [ 1 ] = ’ i ’
T y p e E r r o r : ’ s t r ’
o bje
t d o e s not s u p p o r t i t e m a s s i g n m e n t
> > > m y l i s t [ 1 ] = ’ i ’
> > > m y l i s t
[ ’ P ’ , ’ i ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
В списке можно заменить целый срез:
> > > m y l i s t [ : 3 ] = [ ’ Y ’ , ’ e ’ , ’ s ’ ]
> > > m y l i s t
[ ’ Y ’ , ’ e ’ , ’ s ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
Для списка можно создавать его копию: > > > l i s t 1 = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > l i s t 2 = l i s t 1 . c o p y ( ) #Создание копии списка
> > > l i s t 2 [ 1 ] = ’ i ’
> > > l i s t 2 , l i s t 1
( [ ’ P ’ , ’ i ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ] , [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ] )

50Глава 2. Основные типы данных
Списокlist2изменился, а список list1 нет.
Для списка можно создать вторую ссылку на список. Внимание! При созда-
нии второй ссылки данные не копируются, просто эти данные теп ерь имеют два
имени, поэтому изменение list1будет приводить к изменению list2:
> > > l i s t 2 = l i s t 1 #Создание второй ссылки, а не копии
> > > l i s t 2 [ 1 ] = ’ i ’
> > > l i s t 2 , l i s t 1
( [ ’ P ’ , ’ i ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ] , [ ’ P ’ , ’ i ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ] )
Изменились оба списка. Для создания копии предусмотрен бол ее простой син-
таксис, нежели использование стандартного метода copy: достаточно взять срез
списка от начала и до конца: list3 = list1[:]эквивалентно тому, что мы на-
писали бы list3 = list1.copy() .
Таблица 2.6. Методы списка
Метод Описание
L.append(x) Добавление элемента со значением xв конец списка L:
> > > L = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > L . a p p e n d ( ’ 3 ’ )
> > > L
[ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ , ’ 3 ’ ]
L.extend(T) Добавление списка или кортежа Tв конец списка L. Похоже на
объединение списков, но создание нового списка не происход ит:
> > > L = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > T = [ ’ 3 ’ , ’ . ’ , ’ 4 ’ ]
> > > L . e x t e n d ( T )
> > > L
[ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ , ’ 3 ’ , ’ . ’ , ’ 4 ’ ] > > > L = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > L . a p p e n d ( T )
> > > L
[ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ , [ ’ 3 ’ , ’ . ’ , ’ 4 ’ ] ]
L.insert(i,x) Вставка элемента со значением х на позицию i в списке L:
> > > L = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > L . i n s e r t ( 3 , ’ ! ’ )
> > > L
[ ’ P ’ , ’ y ’ , ’ t ’ , ’ ! ’ , ’ h ’ , ’ o ’ , ’ n ’ ]

2.4. Списки51
L.pop(i) Извлечение элемента с номеромiиз списка L, элемент удаля-
ется и выдаётся в качестве результата:
> > > L = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > x = L . p o p ( 0 )
> > > L
[ ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > x
’ P ’
Если использовать L.pop()без аргумента, то будет извлекать-
ся последний элемент.
L.remove(x) Удаление элемента со значением xиз списка L:
> > > L = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ ! ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > L . r e m o v e ( ’ ! ’ )
> > > L
[ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
Если в списке содержится несколько одинаковых элементов,
удаляется тот, который имеет наименьший номер.
L.count(x) Определение количества элементов, равных x, в списке L:
> > > L = [ 8 , 1 , 5 , - 7 , 4 , 9 , - 2 , 6 , 2 , 5 ]
> > > L . c o u n t ( 5 )
2
L.index(x) Определение первой слева позиции элемента со значением xв
списке L:
> > > L = [ 8 , 1 , 5 , - 7 , 4 , 9 , - 2 , 6 , 2 , 5 ]
> > > L . i n d e x ( 5 )
2
L.reverse() Переворачивание списка наоборот:
> > > L = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
> > > L . r e v e r s e ( )
> > > L
[ 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ]

52Глава 2. Основные типы данных
L.sort() Сортировка списка по возрастанию (в алфавитном порядке):
> > > L = [ 1 0 , 5 , 2 , 8 , 1 , 1 2 ]
> > > L . s o r t ( )
> > > L
[ 1 , 2 , 5 , 8 , 1 0 , 1 2 ]
К спискам применимы некоторые стандартные функции, наприм ер, знако-
мая нам len, к которой обращаться нужно следующим образом: len(mylist).
Функция sumподсчитывает сумму элементов списка, если все они числовог о ти-
па. Функция rangeпозволяет сформировать диапазон значений целых чисел.
В самом общем случае rangeпринимает 3 аргумента: начало диапазона, конец
(всегда берётся не включительно) и шаг. Обратите внимание, ч то в Python 3.x
эта функция не выдаёт список, а производит специальный объе кт-диапазон. По-
этому, чтобы получить список чисел, нужно обязательно явно преобразовать ре-
зультат с помощью функции list. Есть ещё функция sorted(), которая возвра-
щает новый список, отсортированный по убыванию. Функции minиmax находят
максимальный и минимальный элементы списка. Вот небольшая программа с
использованием этих функций:
> > > A =
l ist (r ange ( 0 , 1 0 , 1 ) )
> > > A
[ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] > > >
s um ( A )
4 5 > > >
m in ( A )
0
> > >
m ax ( A )
9
В данном примере объект Aформируется с помощью итератора range, а потом
явно преобразуется к типу list.
К спискам, как и к строкам, применим оператор in, позволяющий узнать,
принадлежит ли элемент списку. Напомним, что оператор возв ращает логиче-
ское значение: True, если элемент в списке содержится и False, если нет. Вот
программа, использующая этот оператор:
> > > m y l i s t 1 = [ ’ P ’ , ’ y ’ , ’ t ’ , ’ h ’ , ’ o ’ , ’ n ’ ]
> > > m y l i s t 2 = [ 6 , 1 0 , 2 0 1 5 ]
> > > ’ y ’
i n m y l i s t 1
T r u e > > > 3 0
i n m y l i s t 2
F a l s e
> > > m y l i s t 2 . a p p e n d ( [ ’Программирование ’ , 1 1 . 3 0 ] )

2.5. Кортежи53
> > > m y l i s t 2
[ 6 , 1 0 , 2 0 1 5 , [ ’Программирование ’ , 1 1 . 3 ] ] > > > m y l i s t 2 [ - 1 ]
[ ’Программирование ’ , 1 1 . 3 ]
Во второй список специально был добавлен ещё один список, чт обы показать,
что списки могут быть вложенными. Также в последней приведё нной программе
была использована возможность индексировать списки с конц а: минус первый
элемент списка  это его последний элемент. Таким образом, mylist2[-1] это
обращение к последнему (первому с конца) элементу списка, я вляющемуся тоже
списком.
2.5 Кортежи
Список так же может быть неизменяемым, как и строка, в этом сл учае он
называется кортеж ( tuple). Кортеж использует меньше памяти, чем список. При
задании кортежа вместо квадратных скобок используются круг лые (хотя можно
и совсем без скобок). Кортеж не допускает изменений, в него н ельзя добавить
новый элемент, удалить или заменить существующие элементы, но он может
содержать изменяемые объекты, например, списки:
> > > l l = [ ]
> > > A = ( 1 , 2 , 3 , l l )
> > > A
( 1 , 2 , 3 , [ ] )
> > > A [ 1 ] = 4T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 2 2 > " , l i n e 1 ,
i n < m o d u l e >
A [ 1 ] = 4
T y p e E r r o r : ’ t u p l e ’
o bje
t d o e s not s u p p o r t i t e m a s s i g n m e n t
> > > A [ 3 ] . a p p e n d ( 3 )
> > >
p rint ( A , l l )
( 1 , 2 , 3 , [ 3 ] ) [ 3 ]
Видно, что прямая замена элемента кортежа недопустима  выз ываетTypeError ,
так как тип tupleне поддерживает изменеине элементов, но если использовать
втроенный метод appendу списка, являющегося элементом кортежа, этот список
можно изменить. Функция tuple()берет в качестве аргумента строку или список и превращает
его в кортеж, а функция list()переводит кортеж в список:
> > > B =
l ist ( A )
> > > B
[ 1 , 2 , 3 ] > > > C =
t uple ( B )
> > > C

54Глава 2. Основные типы данных
( 1 , 2 , 3 )
Основное различие между кортежами и списками состоит в том, что кортежи
не могут быть изменены. На практике это означает, что у них не т методов, кото-
рые бы позволили их изменить: append(),extend() ,insert() ,remove() ,pop() .
Но можно взять срез от кортежа, так как при этом создастся нов ый кортеж.
Кортежи в некоторых случаях быстрее, чем списки. Но такие оп тимизации
в каждом конкретном случае требуют дополнительных исследов аний. Кортежи
делают код безопаснее в том случае, если у вас есть защищенны е от записи
данные, которые не должны изменяться. Некоторые кортежи мо гут использо-
ваться в качестве элементов множества и ключей словаря (конк ретно, кортежи,
содержащие неизменяемые значения, например, строки, числ а и другие корте-
жи). Словари будут рассмотрены в следующем разделе. Списки н икогда не мо-
гут использоваться в качестве ключей словаря, потому что спи ски  изменяемые
объекты.
В Python можно использовать кортежи, чтобы присваивать зна чение несколь-
ким переменным сразу:
> > > v = ( ’ f ’ , 5 , T r u e )
> > > ( x , y , z ) = v
> > > x
’ f ’ > > > y
5
> > > z
T r u e > > >
Это не единственный способ использования. Предположим, чт о вы хоти-
те присвоить имена диапазону значений. Вы можете использов ать встроенную
функцию range()для быстрого присвоения сразу нескольких последовательны х
значений.
> > > ( M O N D A Y , T U E S D A Y , W E D N E S D A Y , T H U R S D A Y , F R I D A Y , S A T U R D A Y , S U N D A Y ) =
r ange ( 1 , 8 )
> > > M O N D A Y
1 > > > S U N D A Y
7
> > >
Заметим, что при вводе длинных списков, кортежей и словарей как в интерак-
тивном, так и в скриптовом режиме можно перейти на следующую с трочку после
любой запятой, разделяющей элементы. Это позволяет в большин стве случаев
избежать использования символа переноса строки \.

2.6. Словари55
2.6 Словари
Одним из сложных типов данных наряду со строками и списками в язы-
ке программирования Python являются словари. Словарь  это и зменяемый
(как список) неупорядоченный (в отличие от строк и списков) набор пар
’ключ:значение’ . Словари оказываются очень удобными объектами для хра-
нения данных и, по сути, являются своеобразной заменой базе д анных.
Чтобы представление о словаре стало более понятным, можно п ровести ана-
логию с обычным словарём, например, англо-русским. На кажд ое английское
слово в таком словаре есть русское слово перевод: cat  кошка , dog  собака,
bird  птица и т.д. Если англо-русский словарь описывать с по мощью Python,
то английские слова будут ключами, а русские  их значениями:
> > > a n i m a l = { ’ c a t ’ : ’кошка ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’птица ’ ,
’ m o u s e ’ : ’мышь ’ }
> > > a n i m a l
{ ’ m o u s e ’ : ’мышь ’ , ’ c a t ’ : ’кошка ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’п тица ’ }
> > >
t ype ( a n i m a l )
<
lass ’ d i c t ’ >
Обратите внимание на фигурные скобки, именно с их помощью оп ределяется
словарь. Такой тип данных в Python называется dict. Если создать словарь в
интерпретаторе Python (как и было сделано), то после нажати я можно
наблюдать, что последовательность вывода пар ’ключ:значение’не совпадёт с
тем, как было введено. Дело в том, что в словаре абсолютно не ва жен порядок
пар, и интерпретатор выводит их в случайном порядке. Тогда к ак же получить
доступ к определённому элементу, если индексация невозмож на в принципе? В
словаре доступ к значениям осуществляется по ключам, которы е заключаются
в квадратные скобки (по аналогии с индексами строк и списков ):
> > > a n i m a l = { ’ c a t ’ : ’кошка ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’птица ’ , ’ m o u s e ’ : ’мышь ’ }
> > > a n i m a l [ ’ c a t ’ ]
’кошка ’
Словари, как и списки, являются изменяемым типом данных: мож но изме-
нять, добавлять и удалять элементы  пары ’ключ:значение’. Изначально сло-
варь можно создать пустым, например, dic = {}и лишь потом заполнить его
элементами. Добавление и изменение имеет одинаковый синтаксис: словарь[ключ] =
значение . Ключ может быть, как уже существующим (тогда происходит изме не-
ние значения), так и новым (происходит добавление элемента словаря). Удаление
элемента словаря осуществляется с помощью функции del(dic[key])или мето-
да pop(key) :
> > > d i c = { ’ c a t ’ : ’кошка ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’птица ’ , ’ m o u s e ’ : ’мышь ’ }
> > > d i c [ ’ c a t ’ ] = ’кот ’
> > > d i c
{ ’ m o u s e ’ : ’мышь ’ , ’ c a t ’ : ’кот ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’пти ца ’ }

56Глава 2. Основные типы данных
> > > d i c [ ’ f o x ’ ] = ’лиса ’
> > > d i c
{ ’ f o x ’ : ’лиса ’ , ’ m o u s e ’ : ’мышь ’ , ’ c a t ’ : ’кот ’ , ’ d o g ’ : ’пёс ’ ,
’ b i r d ’ : ’птица ’ } > > >
d el ( d i c [ ’ m o u s e ’ ] )
> > > d i c
{ ’ f o x ’ : ’лиса ’ , ’ c a t ’ : ’кот ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’птица ’ }
> > > d i c . p o p ( ’ f o x ’ )
’лиса ’
> > > d i c
{ ’ b i r d ’ : ’птица ’ , ’ c a t ’ : ’кот ’ , ’ d o g ’ : ’пёс ’ }
Тип данных ключей и значений словарей не обязательно должен б ыть стро-
ковым:
> > > D i c P r o g = { 1 : ’ P a s c a l ’ , 2 : ’ P y t h o n ’ , 3 : ’ C ’ , 4 : ’ J a v a ’ }
Словари  это широко используемый тип данных языка Python. Д ля ра-
боты с ними существует ряд встроенных методов и функций. Мет одkeys() для
словаря возвращает последовательность всех используемых ключей в произволь-
ном порядке. Для определения наличия определенного ключа ра ньше был метод
has_key() , но в версии 3.0 вместо него есть знакомый нам оператор in:
> > > D i c P r o g . k e y s ( ) d i c t _ k e y s ( [ 1 , 2 , 3 , 4 ] )
> > > 1
i n D i c P r o g
T r u e > > > ’ P a s c a l ’
i n D i c P r o g
F a l s e
2.7 Примеры решения задач
Пример задачи 2 (Арифметические операции) Напишите программу
(необходимые данные вводятся с клавиатуры) для вычисления всех трёх
сторон прямоугольного треугольника, если даны один из остр ых углов и
площадь.
Решение задачи 2 Обозначим катеты прямоугольного треугольника aи b, а
гипотенузу  c. Площадь треугольника обозначим S, один из острых углов 
. Воспользуемся формулой площади прямоугольного треуголь никаS= ab
2
и
формулой тангенса tg = a
c
. Отсюда можно получить выражение для одного
из катетов: a= q 2
Stg . Теперь легко вычислить оставшийся катет и гипотенузу:
b = 2
S
a и
c= √ a
2
+ b2
.
f rom m a t h i mport *
S =
i nt (i nput ( ’Площадь трегольника = ’ ) )
a l p h a =
i nt (i nput ( ’Острый угол ( в градусах ) = ’ ) )

2.7. Примеры решения задач57
a = s q r t ( 2 * S / t a n ( r a d i a n s ( a l p h a ) ) )
b = 2 * S / a
c = ( a * * 2 + b * * 2 ) * * ( 1 / 2 )
p rint ( a , b , c )
Вывод программы:
Площадь трегольника = 8
Острый угол (в градусах) = 4 5 4 . 0 4 . 0 5 . 6 5 6 8 5 4 2 4 9 4 9 2 3 8 1
Пример задачи 3 (Строки) Свяжите любую переменную со строкой:
У Лукоморья дуб зелёный. . . . Выведите все символы этой стр оки в
обратном порядке.
Решение задачи 3 Листинг программы:
S = ’У Лукоморья дуб зелёный... ’
p rint ( S [ - 1 : : - 1 ] )
Вывод программы:
. . . йынёлез буд яьромокуЛ У
Пример задачи 4 (Простое условие) Ответить на вопрос, истинно ли
условие: x3
+ y3
9. Значения переменных x и y вводятся с клавиатуры.
Решение задачи 4 Листинг программы:
x =
f loat (input ( ’ x Ђ = Ђ ’ ) )
y =
f loat (input ( ’ y Ђ = Ђ ’ ) )
print ( x * * 3 + y * * 3 < = 9 )
Вывод программы:
x = 1
y = 3F a l s e
Пример задачи 5 (Сложное условие) Записать условие (составить ло-
гическое выражение), которое является истинным, когда чис ло X чётное
и меньше 100.
Решение задачи 5 Листинг программы:
X =
f loat (input ( ’ x Ђ = Ђ ’ ) )
print ( ( X % 2 = = 0 ) and ( X < 1 0 0 ) )

58Глава 2. Основные типы данных
Вывод программы:
> > >
x = 5 0 T r u e
> > > = = = = = = = = = = = = = = = = = R E S T A R T = = = = = = = = = = = = = = = = = = =
> > >
x = 3 F a l s e> > > = = = = = = = = = = = = = = = = = R E S T A R T = = = = = = = = = = = = = = = = = = =
> > >
x = 1 0 2 F a l s e
Пример задачи 6 (Условный оператор) Приведём пример множествен-
ного ветвления с использованием elif, где разберём перебор вариантов.
Задача такая: пользователь вводит количество денег в рубля х, в мага-
зине можно купить хлеб за 20 руб. и сыр за 100 руб. Если хватает на
то и другое, покупаем всё, если только на сыр или только на хле б, берём
что-то одно, если не хватает ни на что  уходим.
Решение задачи 6 Листинг программы:
a =
i nt (i nput ( " I n p u t Ђ a m o u n t Ђ o f Ђ m o n e y : Ђ " ) )
if a > = 1 2 0 :
p rint ( " B r e a d Ђ a n d Ђ c h e e s e " )
elif a > = 1 0 0 :
p rint ( " C h e e s e Ђ o n l y " )
elif a > = 2 0 :
p rint ( " B r e a d Ђ o n l y " )
else :
p rint ( " N o t h i n g Ђ : ( " )
Как видим, проверять все условия в каждом случае, например, для хлеба усло-
вие, что денег меньше 100, нет смысла: если первое условие вы полняется, то
проверка прочих никогда не происходит, иначе управление пе редаётся на следу-
ющий elifи так далее, если не выполнилось ни одно из условий, выполняют ся
операторы в блоке else, если таковой присутствует.
Пример задачи 7 (Списки) Создайте список в диапазоне (0, 100) с ша-
гом 1. Свяжите его с переменной. Извлеките из него срез с 20 по 30
элемент включительно.
Решение задачи 7 Листинг программы:

2.8. Задания59
A = l ist ( ( 0 , 1 0 0 , 1 ) )
p rint ( A [ 2 0 : 3 1 ] )
Вывод программы:
[ 2 0 , 2 1 , 2 2 , 2 3 , 2 4 , 2 5 , 2 6 , 2 7 , 2 8 , 2 9 , 3 0 ]
Пример задачи 8 (Кортежи) Создайте кортеж в диапазоне (0, 20) с
шагом 1. Свяжите его с переменной. Выведите эту переменную н а экран.
Решение задачи 8 Листинг программы:
A =
t uple (range ( 0 , 2 0 , 1 ) )
print ( A )
Вывод программы:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
Пример задачи 9 (Словари) Создайте словарь, который будет содер-
жать значения параметров функции y= Acos( t+f). А затем по ключу
запросите значения каждого из них.
Решение задачи 9 Листинг программы
p rint ( ’ y Ђ = Ђ A Ђ c o s ( w t + f ) ’ )
P a r a m e t e r s = { ’ A ’ : 1 0 , ’ w ’ : 1 , ’ f ’ : 0 }
K e y =
s tr (i nput ( ’Какой параметр ? ’ ) )
print ( P a r a m e t e r s [ K e y ] )
Вывод программы: y = A c o s ( w t + f )
Какой параметр ? A 1 0
2.8 Задания
Задание 2 Выполнять три задания в зависимости от номера в списке.
Чтобы узнать номера ваших заданий, необходимо решить задач ку: тре-
буется сделать задания № m, № m+ 5 , № m+ 10 , где m= ( n− 1)%5 + 1 ,n
 порядковый номер студента в списке группы по алфавиту.
Используя арифметические операторы ( +,− ,∗, /, // ,% ), напишите програм-
му (необходимая информация запрашивается у пользователя с клавиатуры).
1. Составьте арифметическое выражение и вычислите n-е чётное число (пер-
вым считается 2, вторым 4 и т.д.).

60Глава 2. Основные типы данных
2. Составьте арифметическое выражение и вычислите n-е нечётное число
(первое  1, второе  3 и т.д.).
3. Сколько человек находится между i-м и k-м в очереди?
4. Сколько нечётных чисел на отрезке [a ;b], если aи b чётные? aи b
нечётные? a чётное, a нечётное?
5. Сколько полных часов, минут и секунд содержится в xсекундах? Разло-
жите имеющееся количество секунд на сумму из xчасов + yминут + z
секунд.
6. В доме 9 этажей, на каждом этаже одного подъезда по 4 кварти ры. В каком
подъезде, и на каком этаже находится n-я квартира?
7. Старинными русскими денежными единицами являются: 1 рубл ь = 100
копеек, 1 гривна = 10 копеек, 1 алтын = 3 копейки, 1 полушка = 0, 25
копейки. Имеется Aкопеек. Разложите имеющуюся сумму в копейках на
сумму из xрублей + yгривен + zалтынов + vполушек.
8. Стрелка прибора вращается с постоянной скоростью, соверш ая w оборо-
тов в секунду (не обязательно стрелка прибора, может быть эт о волчок в
игре Что? Где? Когда? и т.п.) Угол поворота стрелки в нулево й момент
времени примем за 0. Каков будет угол поворота через tсекунд?
9. Вы стоите на краю дороги и от вас до ближайшего фонарного ст олба x
метров. Расстояние между столбами y метров. На каком рассто янии от вас
находится n-й столб?
10. Та же ситуация, что и в предыдущей задаче. Длина вашего ша гаzметров.
Мимо скольких столбов вы пройдете, сделав nшагов?
11. x вещественное число. Запишите выражение, позволяющее выде лить его
дробную часть.
12. x вещественное число. Запишите выражение, которое округли т его до
сотых долей (останется только два знака после запятой).
13. От бревна длиной Lотпиливают куски длиной x. Сколько целых полнораз-
мерных кусков максимально удастся отпилить?
14. Бревно длиной Lраспилили в nместах. Какова средняя длина получив-
шихся кусков?
15. Резиновое кольцо диаметром dразрезали в nместах. Какова средняя длина
получившихся кусков?

2.8. Задания61
Задание 3 (Строки)Задания выполняйте все по порядку. Свяжите лю-
бую переменную со строкой: Мы обязательно научимся програм миро-
вать!. Извлеките из неё следующие срезы:
1. выведите третий символ этой строки;
2. выведите предпоследний символ этой строки;
3. выведите первые пять символов этой строки;
4. выведите всю строку, кроме последних двух символов;
5. выведите все символы с чётными индексами (считая, что инд ексация начи-
нается с 0);
6. выведите все символы с нечётными индексами, то есть, начи ная с первого
символа строки;
7. выведите четыре символа из центра строки;
8. выведите символы с индексами, кратными трём;
9. выведите все символы в обратном порядке;
10. выведите все символы строки через один в обратном порядк е, начиная с
последнего;
11. удалите второе слово из строки;
12. замените второе слово на строку никогда не;
13. добавьте в конец строки на Python;
14. поставьте последнее слово первым в строке;
15. выведите длину данной строки.
Задание 4 (Логический тип данных. Логические операторы) В каж-
дой группе выполнять по одному заданию в зависимости от номе ра в
списке группы: (n − 1)%10 + 1 , гдеn номер в списке.
Вычислить значение логического выражения. Значения перем енныхxиy
вбиваются с клавиатуры.
1. x2
+ x2
4;
2. x2
− x2
4;
3. x 0или y2
6
= 4 ;
4. x 0и y2
6
= 4 ;

62Глава 2. Основные типы данных
5.x·y 6
= 0 или y > x ;
6. x·y 6
= 0 иy > x ;
7. не x·y < 0или y > x ;
8. не x·y < 0и y > x ;
9. x 4или y2
6
= 4 ;
10. x 4и y2
6
= 4 .
Вычислить значение логического выражения при всех возможн ых значениях
логических величин X,Y иZ (для образца можно взять задачку про Шумахера):
1. не ( Xили не YиZ);
2. Yили ( Xи не Yили Z);
3. не (не X и Y или Z);
4. не ( Xили не YиZ) или Z;
5. не ( Xи не Yили Z) и Y;
6. не (не Xили YиZ) или X;
7. не ( Yили не XиZ) или Z;
8. Xи не (не Yили Z) или Y;
9. не ( Xили YиZ) или не X;
10. не ( XиY) и (не Xили не Z).
Записать условие (составить логическое выражение), котор ое является истин-
ным, когда:
1. число Xделится нацело на 13 и меньше 100;
2. число Xбольше 10 и меньше 20;
3. каждое из чисел XиY больше 25;
4. каждое из чисел XиY нечетное;
5. только одно из чисел XиY четное;
6. хотя бы одно из чисел XиY положительно;
7. каждое из чисел X,Y ,Z кратно пяти;
8. только одно из чисел X,Y ,Z кратно трем;

2.8. Задания63
9. только одно из чиселX,Y ,Z меньше 10;
10. хотя бы одно из чисел X,Y ,Z отрицательно.
Задание 5 (Условный оператор) Выполнять три задания в зависимо-
сти от номера в списке. Необходимо сделать задания № m, № m+ 5 ,
№ m+ 10 , где m= ( n− 1)%5 + 1 ,n  номер студента в списке группы в
алфавитном порядке.
1. Напишите программу, которая запрашивает значение x, а затем выводит
значение следующей функции от x(она называется по латыни signum,
что значит знак):
y(x ) = 


1
, x > 0,
0 , x = 0,
− 1, x < 0
2. Напишите программу, которая запрашивает значение x, а затем выводит
значение следующей функции от x:
y (x ) = 


sin
2
(x ), x > 0,
0 , x = 0,
1 + 2 sin( x2
), x < 0
3. Напишите программу, которая запрашивает значение x, а затем выводит
значение следующей функции от x:
y (x ) = 


cos
2
(x ), x > 0,
0 , x = 0,
1 − 2 sin( x2
), x < 0
4. Запросите у пользователя два числа. Далее: •если первое больше второго, то вычислить их разницу и вывест и дан-
ные на печать;
• если второе число больше первого, то вычислить их сумму и выв ести
на печать;
• если оба числа равны, то вывести это значение на печать.
5. Запросите у пользователя два целых числа mиn. Если целое число m
делится нацело на целое число n, то вывести на экран частное от деления,
в противном случае вывести сообщение mна nнацело не делится.
6. Напишите программу для решения квадратного уравнения ax2
+ bx +c=
0 . Значения коэффициентов a, b, c вводятся с клавиатуры. Вычисление
квадратного корня можно организовать либо путём возведени я в степень

64Глава 2. Основные типы данных
0.5, либо с помощью функцииsqrtиз математического модуля. Проверяйте
значение дискриминанта: если оно меньше нуля, корней нет, е сли равно
нулю, значит, корень 1, если больше нуля  корней два. Для этог о можно
использовать конструкцию вида if elif else.
7. Напишите программу, решающую кубическое уравнение вида y3
+ px +q= 0
с помощью формулы Кардано. Значения коэффициентов pи qвводятся с
клавиатуры. Найдите корни уравнения. Помните, что Python м ожет рабо-
тать с комплексными числами, но модуль math использовать дл я их возве-
дения в степень нельзя. Будьте внимательны с кубическим кор нем: кубиче-
ский корень от отрицательного числа превращается в комплек сное число.
8. Напишите программу, которая запрашивает у пользователя его возраст (це-
лое число лет) и в зависимости от значения введённого числа в ыводит:
• от 0 до 7  Вам в детский сад;
• от 7 до 18  Вам в школу;
• от 18 до 25  Вам в профессиональное учебное заведение;
• от 25 до 60  Вам на работу;
• от 60 до 120  Вам предоставляется выбор;
• меньше 0 и больше 120  пять раз подряд: Ошибка! Это программ а
для людей!.
9. Напишите программу, которая поможет вам оптимизировать путешествие
на автомобиле. Пусть программа запрашивает у пользователя следующие
данные:
•Сколько километров хотите проехать на автомобиле?
• Сколько литров топлива расходует автомобиль на 100 километ ров?
• Сколько литров топлива в вашем баке?
Далее в зависимости от введённых значений программа должна выдать
вердикт: проедете вы желаемое расстояние или нет;
10. Пользователь вводит три действительных числа: длины ст орон треуголь-
ника. Программа должна сообщить пользователю:
•является ли треугольник равносторонним;
• является ли треугольник равнобедренным;
• является ли треугольник разносторонним;
• является ли треугольник прямоугольным;
• существует ли вообще такой треугольник (такого треугольни ка не мо-
жет быть, если длина хотя бы одной стороны больше или равна су мме
длин двух других).

2.8. Задания65
11. Известен вес боксёра-любителя. Он таков, что боксёр может быть отнесен
к одной из трех весовых категорий:
•легкий вес  до 60 кг;
• первый полусредний вес  до 64 кг;
• полусредний вес  до 69 кг;
Определить, в какой категории будет выступать данный боксе р.
12. В чемпионате по футболу команде за выигрыш дается 3 очка, за проиг-
рыш  0, за ничью  1. Известно количество очков, полученных к омандой
за игру. Определить словесный результат игры (выигрыш, про игрыш или
ничья).
13. Составить программу, которая в зависимости от порядков ого номера дня
недели (от 1 до 7) выводит на экран его название (понедельник , вторник,
..., воскресенье).
14. Составить программу, которая в зависимости от порядков ого номера ме-
сяца (1, 2, ..., 12) выводит на экран его название (январь, фе враль, ...,
декабрь).
15. Составить программу, которая в зависимости от порядков ого номера меся-
ца (1, 2, ..., 12) выводит на экран время года, к которому отно сится этот
месяц.
Задание 6 (Списки. Кортежи. Словари) Задания выполнять все по по-
рядку.
1. Списки
a) Создайте два списка в диапазоне (0, 100) с шагом 10. Присво йте неко-
торым переменным значения этих списков.
b) Извлеките из первого списка второй элемент. c) Измените во втором списке последний объект на число 200 . Выве-
дите список на экран.
d) Соедините оба списка в один, присвоив результат новой пер еменной.
Выведите получившийся список на экран.
e) Возьмите срез из соединённого списка так, чтобы туда попа ли неко-
торые части обоих первых списков. Срез свяжите с очередной н овой
переменной. Выведите значение этой переменной.
f ) Добавьте в список-срез два новых элемента и снова выведит е его.
g) С помощью функций min()иmax() найдите и выведите элементы объ-
единённого списка с максимальным и минимальным значением.

66Глава 2. Основные типы данных
2.Кортежи
a) Создайте два кортежа: один из чисел в диапазоне (1, количе ство уче-
ников в группе) с шагом 1, второй  из фамилий учеников вашей
группы. Пусть они соответствуют друг другу;
b) Посмотрите, какая фамилия у студента с номером 5.
c) А теперь посмотрите, что записано во второй кортеж под ном ером 5.
d) Объедините два кортежа в один, присвоив результат новой п еремен-
ной. Выведите получившийся список на экран.
e) Возьмите срез из соединенного кортежа так, чтобы туда поп али неко-
торые части обоих первых кортежей. Срез свяжите с очередной новой
переменной. Выведите значение этой переменной.
3. Словари
a) Создайте словарь, связав его с переменной School, и наполните его
данными, которые бы отражали количество учащихся в пяти раз ных
классах (например, 1а, 1б, 2в и т. д.); выведите содержимое с ловаря на
экран.
b) Узнайте сколько человек в каком-нибудь классе. Класс запр ашивается
у пользователя с клавиатуры, если такого запрашиваемого кл асса в
школе нет, то выдаётся сообщение: Такого класса на существ ует.
c) В школе произошли изменения, внесите их в словарь: в трёх к лассах
изменилось количество учащихся; результат выведите на экр ан.
d) В школе появилось два новых класса, новый словарь выведит е на
экран.
e) В школе расформировали один из классов, выведите содержи мое но-
вого словаря на экран.

Глава 3
ЦиклыЦиклы  это инструкции, выполняющие одну и ту же последовател ьность
действий многократно.
В реальной жизни мы довольно часто сталкиваемся с циклами. Н апример,
ходьба человека  вполне циклическое явление: шаг левой, ша г правой, сно-
ва левой-правой и т. д., пока не будет достигнута определенн ая цель (например,
университет или кафе). В компьютерных программах наряду с ин струкциями
ветвления (т.е. выбором пути действия, конструкция if-else ) также существуют
инструкции циклов (повторения действия). Если бы инструкц ий цикла не суще-
ствовало, пришлось вставлять в программу один и тот же код по дряд столько
раз, сколько нужно выполнить одинаковую последовательнос ть действий.
3.1 Цикл с условием ( while)
Универсальным организатором цикла в языке программировани я Python (как
и во многих других языках) является цикл с условием (констру кцияwhile ). Сло-
во while с английского языка переводится как пока (пока логическое вы-
ражение возвращает истину, выполнять определенные операц ии). Конструкция
while на языке Python может выглядеть следующим образом 1
:
a = начальное значение
w hile a оператор сравнения b :
действия
изменение a действия
Эта схема сильно неполная, так как логическое выражение в за головке цикла
может быть более сложным, а изменяться может переменная (ил и выражение)b.
1
В действительности, такое представление является частным и вместоa оператор
сравнения b может стоять любое логическое выражение и даже нелогическо е выражение, ко-
торое может быть интерпретировано как логическое путём нея вных преобразований типов.

68Глава 3. Циклы
Может возникнуть вопрос: Зачем изменятьaили b?. Когда выполнение
программного кода доходит до цикла while, выполняется логическое выраже-
ние в заголовке, и, если было получено True, выполняются вложенные выраже-
ния. После поток выполнения программы снова возвращается в заголовок цикла
while , и снова проверяется условие. Внимание! Если условие никог да не будет
ложным, то не будет причин для остановки цикла, и программа з ациклится.
Простейший способ создать такую ситуацию:
w hile T r u e :
print ( ’У попа была собака, он её любил. ’ )
print ( ’Она съела кусок мяса - он её убил. ’ )
print ( ’Вырыл ямку, закопал и на камне написал: ’ )
Чтобы такого не произошло в обычной программе, необходимо п редусмот-
реть возможность выхода из цикла  ложность выражения в заго ловке. Таким
образом, изменяя значение переменной в теле цикла, можно до вести логическое
выражение до ложности. Эту изменяемую переменную, которая и спользуется в
заголовке цикла while, обычно называют счётчиком. Как и всякой переменной,
ей можно давать произвольные имена, однако очень часто испо льзуются буквы
i и j.
Пример использования цикла while: вывод первых nчисел Фибоначчи. Ряд
Фибоначчи  ряд чисел, в котором каждое последующее число рав но сумме двух
предыдущих: 0, 1, 1, 2, 3, 5, 8, 13 и т. д. Выведем первые 10 чисе л:
f i b 1 = 0
f i b 2 = 1
p rint ( f i b 1 )
print ( f i b 2 )
n = 1 0
i = 2
s u m m a = 0
w hile i < = n :
s u m m a = f i b 1 + f i b 2
p rint ( s u m m a )
f i b 1 = f i b 2
f i b 2 = s u m m a
i = i + 1
Как работает эта программа? Вводятся две переменные ( fib1иfib2 ), ко-
торым присваиваются начальные значения. Присваиваются нача льные значения
переменным nи summa , а также счетчику i. Внутри цикла переменной summaпри-
сваивается сумма двух предыдущих членов ряда, и ее же значен ие выводится на
экран. Далее изменяются значения fib1иfib2 (первому присваивается второе,
второму  сумма), а также увеличивается значение счетчика. Задачка из жизни. В багажник автомобиля грузят овощи и фрукт ы с да-
чи: картофель, капусту, морковь, яблоки, груши и др. Объем б агажника равен

3.1. Цикл с условием (while) 69
350 л. Продукты кладут последовательно, объём каждого груз а известен в лит-
рах. Нужно сказать в какой момент (назвать номер груза) бага жник перепол-
нится. Программа выглядит следующим образом:
s = 0
n = 0
w hile s < 3 5 0 :
x =
i nt (i nput ( ) )
s = s + x
n = n + 1
p rint ( n )
Здесь переменная sхранит суммарный объём уже накопленных грузов, в пере-
менную xсчитывается объём очередного груза, а nсчитает номер груза.
В обоих примерах был применен важный приём накопления суммы. Данный
алгоритмический приём используется, когда надо просуммир овать большое ко-
личество чисел. Для этого переменной, в которую будет запис ываться сумма,
в начале присваивается нулевое значение, затем делается ци кл, где на каждом
шаге к этой переменной добавляется очередное число.
Очень важная, фундаментальная идея, использованная в данн ом приёме, со-
стоит в том, что результат выполнения каждого шага цикла зав исит от значения
переменной, вычисленного на предыдущем. Таким образом, вм есто тривиального
повторения одного и того же мы на каждом шаге получаем новый р езультат.
В приведенном примере очередное число добавляется к значен ию перемен-
ной s, полученному на предыдущем шаге. А к чему добавляется очере дное чис-
ло на самом первом? Чтобы было к чему добавлять, перед циклом обязательно
должна присутствовать инициализация (присваивание начал ьного значения) пе-
ременной, в которой накапливается сумма. Чаще всего требуе тся присвоить ей
начальное значение 0.
Программистский анекдот в тему. Буратино подарили три ябло ка. Два он
съел. Сколько яблок осталось у Буратино? Ответ одно  непр авильный. В
действительности, неизвестно, сколько осталось, так как н е сказано, сколько яб-
лок было у него до того, как ему подарили три новых. Мораль: не забывайте
обнулять (и вообще инициализировать) переменные!
Аналогично накоплению суммы можно в отдельной переменной на капливать
произведение. Переменной, в которой производится накопле ние, присваивается
начальное значение 1. Для примера вычислим факториал некот орого числа. Фак-
ториалом целого числа nназывается произведение всех целых чисел от 1 до n.
Обозначается n!, то есть n! = 1 ·2 ·3 ·. . . ·n .
Вычисляющая факториал программа выглядит так:
n =
i nt (i nput ( ’Сколько факториалов будем суммировать ? ’ ) )
i = 2
p = 1
w hile i < = n :

70Глава 3. Циклы
p = p * i
i = i + 1
p rint ( p )
3.2 Цикл обхода последовательности ( for)
Цикл while не единственный способ организации повторения группы выра -
жений. Также широко применяется цикл for, который представляет собой цикл
обхода заданного множества элементов (символов строки, об ъектов списка или
словаря) и выполнения в своем теле различных операций над ни ми2
.
Как правило, циклы forиспользуются либо для повторения какой-либо по-
следовательности действий заданное число раз, либо для изм енения значения
переменной в цикле от некоторого начального значения до нек оторого конечно-
го.
Для повторения цикла некоторое заданное число раз nможно использовать
цикл forвместе с функцией range:
f or i in range ( n ) :
Тело цикла
В качестве nможет использоваться числовая константа, переменная или п роиз-
вольное арифметическое выражение (например, 2**10). Если значение nравно
нулю или отрицательное, то тело цикла не выполнится ни разу. Если задать цикл таким образом:
f or i in range ( a , b ) :
Тело цикла
то индексная переменная iбудет принимать значения от aдо b - 1 включитель-
но, то есть первый параметр функции range, вызываемой с двумя параметрами,
задает начальное значение индексной переменной, а второй п араметр  значение,
которое индексная переменная принимать не будет. Например , для того, чтобы
просуммировать значения чисел от 1 до n, можно воспользоваться следующей
программой:
s u m m a = 0
f or i in range ( 1 , n + 1 ) :
s u m m a = s u m m a + i
В этом примере переменная iпринимает значения 1, 2, . . .,n, и значение
переменной summaпоследовательно увеличивается на указанные значения. Зде сь
опять видим прием накопления суммы.
2 В большинстве языков программирования под циклом forпринято понимать цикл со счёт-
чиков. Такого цикла в Python нет, хотя существующий forможет исполнять его функции. Цикл
for языка Python фактически представляет собою цикл foreach для каждого. Такой цикл
существует во многих языках программирования, созданных в последние два десятилетия, на-
пример, в D.

3.2. Цикл обхода последовательности (for) 71
Наконец, чтобы организовать цикл, в котором индексная пере менная будет
уменьшаться (в Pascal цикл с downto, цикл с отрицательным приращением), необ-
ходимо использовать функцию rangeс тремя параметрами. Первый параметр
задает начальное значение индексной переменной, второй па раметр  значение,
до которого будет изменяться индексная переменная (не включ ая его!), а третий
параметр  величину изменения индексной переменной. Напри мер, сделать цикл
по всем нечетным числам от 1 до 99 можно при помощи функции range(1, 100,
2) , а сделать цикл по всем числам от 100 до 1 можно при помощи range(100,
0, -1) .
Более формально, цикл for i in range(a, b, d) приd > 0 задаёт значения
индексной переменной i = a,i = a + d ,i = a + 2 * d и так для всех значений,
для которых i < b. Если же d < 0, то переменная цикла принимает все значения
i > b .
Но в языке программирования Python цикл forимеет зачастую несколь-
ко иное применение. Например, список в Python относится к ит ерируемым
объектам. Это значит, что его элементы можно обойти циклом for, причём
переменная-счётчик будет на каждом шаге принимать значени е очередного эле-
мента цикла:
m y l i s t = [ 1 2 , 1 7 . 9 , T r u e , - 8 , F a l s e ]
f or j in m y l i s t :
p rint ( j )
Программа выведет все элементы списка mylistв столбик:
1 2 1 7 . 9
T r u e
- 8
F a l s e
Приведённый способ можно назвать обходом по значению, поско льку автома-
тически создаваемая переменная jна каждом шаге принимает значение очеред-
ного элемента списка. Есть ещё один способ обойти список  по индексам, когда
такая же переменная будет принимать номер очередного элеме нта:
m y l i s t = [ 1 2 , 1 7 . 9 , T r u e , - 8 , F a l s e ]
f or j in range ( 0 , len ( m y l i s t ) , 1 ) :
p rint ( j )
Вывод будет совсем другой:
0 1 23 4

72Глава 3. Циклы
Если написать:
m y l i s t = [ 1 2 , 1 7 . 9 , T r u e , - 8 , F a l s e ]
f or j in range ( 0 , len ( m y l i s t ) , 1 ) :
p rint ( m y l i s t [ j ] )
то вывод будет такой же, как в первом примере. На самом деле, механизм обоих подходов один и тот же, потому ч то во вто-
ром варианте фактически неявно создаётся новая последоват ельностьrange(0,
len(mylist), 1) , содержащая номера всех элементов списка mylist диапазон
от нуля до длины mylistс шагом 1, и этот новая последовательность обходится
по значению.
Напишем с помощью цикла forвывод ряда Фибоначчи:
f i b 1 = 0
f i b 2 = 1
n = 1 0 s u m m a = 0
f or i in range ( n ) :
s u m m a = f i b 1 + f i b 2
p rint ( s u m m a )
f i b 1 = f i b 2
f i b 2 = s u m m a
В результате будет выведено следующее:
1 2 35 8 1 3
2 1
3 4
5 5
8 9
С помощью цикла forможно перебирать строки, если не пытаться их при
этом изменять:
s t r 1 = ’Привет ’
f or i in s t r 1 :
p rint ( i , e n d = ’ Ђ ’ )
Будет выведено:
П р и в е т

3.3. Некоторые основные алгоритмические приёмы73
Здесь можно видеть, что у функцииprintесть параметр end. По умолчанию
end = ’\n’  неотображаемому символу новой строки. В предыдущем приме ре
параметру endбыл присвоен символ пробел.
Цикл forиспользуется и для работы со словарями:
d i c = { ’ c a t ’ : ’кошка ’ , ’ d o g ’ : ’пёс ’ , ’ b i r d ’ : ’птица ’ , ’ m o u s e ’ : ’мышь ’ }
f or i in d i c :
d i c [ i ] = d i c [ i ] + ’ _ r u ’
p rint ( d i c )
Вывод программы:
{’bird’: ’птица_ru’, ’cat’: ’кошка_ru’, ’mouse’: ’мышь_r u’, ’dog’: ’пёс_ru’}
На практике часто не важно, каким образом вы решите задачу. И скать сразу
оптимальное решение не следует, достаточно найти просто пр авильное (а их мо-
жет быть множество). Как писал Дональд Кнут в своём фундамен тальном труде
Искусство программирования, преждевременная оптимиз ация  корень мно-
гих зол.
3.3 Некоторые основные алгоритмические приёмы
3.3.1 Приёмы накопления суммы и произведения. Их комбинация
В разделе про цикл whileрассматривались примеры с накоплением суммы и
произведения. Эти же приёмы можно и нужно применять при рабо те с циклом
for . Так же их можно комбинировать. Рассмотрим следующий пример : необхо-
димо вычислить значение выражения 1! + 2! +· · ·+n!
Решение в лоб состоит в том, чтобы в теле цикла, осуществляюще го сумми-
рование, производить вычисление факториала:
n =
i nt (i nput ( ’Сколько факториалов будем суммировать ? ’ ) )
s = 0
f or i in range ( 1 , n + 1 ) :
# Вычисление факториала от i :
p = 1
f or k in range ( 1 , i + 1 ) :
p = p * k ;
# Добавление вычисленного факториала к сумме :
s = s + p
p rint ( s )
Циклы позволяют повторять выполнение любого набора оператор ов. В част-
ности, можно повторять много раз выполнение другого цикла. Такие циклы на-
зываются вложенными . В приведённом выше примере один цикл forвложен в
другой цикл for.

74Глава 3. Циклы
Типичная ошибка, когда в качестве счётчиков вложенных цикл ов (iи kв
приведённом примере) используется одна и та же переменная. То есть, нельзя в
каждом из циклов использовать одну переменную i. Ваша программа запустит-
ся, но делать будет вовсе не то, что вы от неё ждёте. В приведён ном примере,
если допустить ошибку, заменив переменную kна i, внешний цикл выполнится
всего 1 раз вместо 4-х. Возможна также ситуация, когда такая ошибка приведет к
зацикливанию: внешний цикл будет выполняться бесконечно до лго  программа
зависнет.
Заметим, что при вычислении факториала на каждом шаге получ ается фак-
ториал все большего целого числа. Эти промежуточные резу льтаты однократ-
ного вычисления факториала и можно суммировать:
n =
i nt (i nput ( ’Сколько факториалов суммировать ? ’ ) )
s = 0
p = 1
f or i in range ( 1 , n + 1 ) :
p = p * i
s = s + p
p rint ( s )
Стоит отметить, что в основе рассмотренных ранее алгоритми ческих приё-
мов накопления суммы и произведения лежит фундаментальная идея о том, что
результат вычислений на каждом шаге цикла должен зависеть о т результата вы-
числений на предыдущем шаге. Обобщенным математическим вы ражением этой
идеи являются рекуррентные соотношения .
В наших примерах в качестве рекуррентных соотношений высту пали, напри-
мер, формулы p = p * iиs = s + p . Причём, последнее выражение ( s = s +
p ) является сложною рекурсией, когда значение sзависит не только от своего
прошлого значения, но и от значения pна прошлом шаге.
Для лучшего понимания решим задачу: пусть дано рекуррентно е соотноше-
ние x
n+1 = 1
−x 2
n
. В нелинейной динамике это соотношение называют логисти-
ческим отображением. Оно, например, может использоваться для приближённо-
го описания изменения численности популяций некоторых жив отных во времени.
Пусть начальное значение x
0 = 1
. Параметр = 0 .75 . Необходимо найти x
5.
x = 1
f or i in range ( 1 , 6 ) :
x = 1 - 0 . 7 5 * x * * 2
p rint ( x )
Вывод программы:
0 . 3 5 9 8 9 0 1 8 6 9 3 6 2 9 4 0 4 Однократное вычисление следующих значений по предыдущим по средством
рекуррентных соотношений называется итерацией. А процесс вычислений с по-
мощью рекуррентных соотношений  итерированием.

3.3. Некоторые основные алгоритмические приёмы75
Задание 7Придумайте рекуррентное соотношение, задающее следую-
щие числовые последовательности:
a) 1,2 ,3 ,4 , . . .
b) 0,5 ,10 ,15 , . . .
c) 1,1 ,1 ,1 , . . .
d) 1,− 1,1 ,− 1, . . .
e) 1,− 2,3 ,− 4,5 ,− 6. . .
f ) 2,4 ,8 ,16 , . . .
g) 2,4 ,16 ,256 , . . .
h) 0,1 ,2 ,3 ,0 ,1 ,2 ,3 ,0 , . . .
i) 1!,3! ,5! ,7! , . . .
Важно!!! Если в написанной вами формуле вам встречается значок суммы
P N−1
i =0 x
i, то вы сразу должны представлять себе цикл
forс накоплением суммы
внутри:
x = 0
f or i in range ( 0 , N ) :
x = x + i
Аналогично, если в задании вам встречается значок произведе нияQ
N−1
i =0 x
i,
то вы сразу должны представлять себе цикл forс накоплением произведения
внутри:
x = 1
f or i in range ( 0 , N ) :
x = x * i
3.3.2 Счётчик событий Часто требуется подсчитать, сколько раз во время вычислени й наступает то
или иное событие (выполняется то или иное условие). Для этог о вводится вспо-
могательная переменная, которой в начале присваивается ну левое значение, а
после каждого наступления события она увеличивается на еди ницу.
Пример задачи 10 (Счётчик событий) Пользователь вводит 10 чисел.
Определите, сколько из них являются одновременно чётными и п оло-
жительными.

76Глава 3. Циклы
Решение задачи 10Решение можно записать следующим образом:
C o u n t e r = 0 #Обнуляем переменную-счётчик
f or i in range ( 0 , 1 0 ) :
x =
i nt (i nput ( ’Введите число : ’ ) )
if ( x % 2 = = 0 ) a nd ( x > 0 ) :
C o u n t e r = C o u n t e r + 1
p rint ( C o u n t e r )
Вывод программы:
Введите число: 2
Введите число: 3
Введите число: 4
Введите число: -2
Введите число: -4
Введите число: 3
Введите число: 5
Введите число: 7
Введите число: 6
Введите число: 3
3
3.3.3 Досрочное завершение цикла Отметим два простых оператора breakиcontinue , с помощью которых мож-
но управлять ходом выполнения цикла. Оператор breakпрерывает выполне-
ние цикла, управление передается операторам, следующим за о ператором цикла.
Оператор continueпрерывает выполнение очередного шага цикла и возвращает
управление в начало цикла, начиная следующий шаг.
f or n in range ( 1 0 ) :
if n % 2 = = 0 :
ontinue
i
f
n = = 7 :
b reak
p
rint
( n )
Данная программа будет печатать только нечётные числа из-з а срабатывания
continue . Цикл прекратит выполняться, когда nстанет равно 7. В итоге вывод
программы таков:
1
3
5

3.3. Некоторые основные алгоритмические приёмы77
3.3.4 Поиск первого вхождения
Ранее мы подсчитывали количество положительных чётных чис ел в последо-
вательности ввода. Зачастую нужен не подсчёт, а только пров ерка, произошло
ли за время вычислений некоторое событие. Например, необхо димо проверить,
содержится ли в некоторой последовательности хотя бы одно отрицательное
число. Для того, чтобы утверждать, что отрицательных чисел в последователь-
ности нет, необходимо просмотреть её всю. Если же такое число в ней есть, до-
статочно добраться до него, после чего цикл можно закончить . Получается цикл
for с проверкой и оператором breakвнутри.
s e q = ( 1 2 , 5 4 , 0 , - 7 , 2 2 , - 1 1 , 5 4 , 0 , - 7 )
f or x in s e q :
if x < 0 :
p rint ( x )
break
В этом коде пока нет места для действий на случай, если отрицательное число
не найдено. В самом деле, и после break, и после естественного завершения
цикла программа продолжит работу с одной и той же строки. В Py thon на этот
счёт предусмотрена конструкция else, относящаяся к циклу. Работает она так,
как и ожидается: только если цикл завершился естественным путём  пото-
му что проверка условия в whileоказалась ложной или последовательность в
for закончилась. Если же выход из цикла произошёл по break, блок операторов
внутри elseне выполняется. Так что для того, чтобы вывести какое-нибуд ь со-
общение, если отрицательных чисел в последовательности не т, соответствующий
print() надо добавить в такую конструкцию.
s e q = ( 1 2 , 5 4 , 0 , 7 , 2 2 , 1 1 , 5 4 , 0 , 7 )
f or x in s e q :
if x < 0 :
p rint ( x )
break
e
lse
:
p rint ( " Отрицательных чисел нет " )
3.3.5 Обработка исключений Исключения (exceptions)  ещё один тип данных в Python. Часто в работе
программы возникают ошибки, препятствующие её дальнейшему в ыполнению.
Вот простой пример такой ошибки:
> > > 1 0 / 0 T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 0 > " , l i n e 1 ,
i n < m o d u l e >
1 0 / 0
Z e r o D i v i s i o n E r r o r : d i v i s i o n b y z e r o

78Глава 3. Циклы
В данном случае интерпретатор сообщил нам об ошибкеZeroDivisionError,
то есть о делении на ноль. Также возможны и другие исключения, например,
несовпадающие типы:
> > > 1 + ’ a ’T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) :
F i l e " < p y s h e l l # 1 > " , l i n e 1 ,
i n < m o d u l e >
1 + ’ a ’
T y p e E r r o r : u n s u p p o r t e d o p e r a n d
t ype ( s ) for + : ’ i n t ’ and ’ s t r ’
Во всех таких случаях интерпретатор прерывает работу прогр аммы, посколь-
ку либо не может понять очередную инструкцию, либо предполаг ает, что полу-
ченное в её результате значение (например, при делении на но ль или взятии
логарифма отрицательного числа) недопустимо. Это считает ся правильным, по-
скольку указывает программисту на наличие ошибки. Однако и ногда в програм-
ме могут возникать ошибки, которые невозможно быстро попра вить, а работу
программы останавливать нельзя. В таком случае принято гов орить об исключе-
нии. Такие исключения можно обрабатывать, для чего используется конструк-
ция try–except . Пример применения этой конструкции:
a =
i nt (i nput ( ’Введите делимое = ’ ) )
b =
i nt (i nput ( ’Введите делитель = ’ ) )
try :
p rint ( a / b )
e x
ept Z e r o D i v i s i o n E r r o r :
print ( ’Деление на ноль ’ )
Надо понимать, что обработка исключений  это крайняя мера, которая ис-
пользуется, либо если иначе починить программу без существ енного переписы-
вания быстро нельзя, либо если программа зависит от сторонн их модулей, кото-
рые не могут быть исправлены, но способны вызвать ошибку. Зл оупотребление
конструкцией try–except быстро приводит программу в неработоспособное со-
стояние, поскольку эта конструкция в действительности ничего не исправляет, а
просто помогает игнорировать проблему в данном месте. В бол ьшинстве случаев
вместо try–except достаточно добавить просто проверку условия.
3.4 Отладка программы В большинстве случаев многие даже несложные программы, буд учи напи-
саны, работают не так, как предполагал автор. Возможно, вы уж е убедились в
этом при написании простеньких программ из предыдущей глав ы. Как минимум,
у половины из вас появлялись синтаксические ошибки (забыли поставить скобоч-
ку или кавычку). В этом разделе после изучения таких сравнит ельно сложных
конструкций, как циклы, количество ваших ошибок резко увел ичится. Но рас-
страиваться не стоит. Нужно всегда помнить, что процесс нап исания программы
состоит из двух этапов: кодирование (написание кода програ ммы, занимает менее
трети времени) и отладки (занимает более двух третей времен и).

3.4. Отладка программы79
Рис. 3.1. Пример ошибки, выявляемой препроцессором.
Все ошибки можно условно разделить на следующие три категори и, которые
разберём на примере программы, считающей сумму квадратов це лых чисел от 0
до N.
3.4.1 Ошибки, выявляемые препроцессором В интерпретатор Python встроена специальная программа  пр епроцессор.
У препроцессора несколько функций, в частности, он перевод ит текст програм-
мы в специальный байт-код, понятный для интерпретатора. В п роцессе перево-
да текста в байт-код препроцессор вынужден анализировать с интаксис вашей
программы, для чего используется синтаксический анализатор, проверяющий
ваш текст с целью понять, похож ли он на текст программы на Pyt hon по ря-
ду формальных признаков. Если препроцессор не может понять смысл тех или
иных символов в вашем тексте, он чаще всего указывает вам на о шибку типа
( SyntaxError ). При синтаксической ошибке возникает диалоговое окно, ко торое
предотвращает запуск интерпретатора (рис. 3.1), так как не т смысла запускать
то, что непохоже на программу.
Самый важный вид синтаксической ошибки с точки зрения препр оцессора
 это ошибка расстановки отступов, поскольку она нарушает в сю структуру
программы. Если вы попытаетесь запустить на исполнение вот такой код:
N =
i nt (i nput ( ’Введите N : ’ ) )
s = 0
f or i in range ( N ) :
s = s + i * * 2
i f s % 2 = = 0 :
p rint ( s )
то ничего не выйдет: вы получите сообщение unexpected indent неожидан-
ный отступ, и пробел перед ключевым словом forбудет подсвечен красным.
Исправить такую ошибку совсем несложно: нужно просто норма льно расставить
отступы в соответствии с логикою программы.
Ещё одна популярная ошибка на примере того же кода:

80Глава 3. Циклы
N = i nt (i nput ( ’Введите N : ’ ) )
s = 0
f or i in range ( N ) :
s = s + i * * 2
i f s % 2 = = 0 :
p rint ( s )
Интерпретатор выдаст: expected an indented block : нужен отступ для тех
команд, которые лежат внутри цикла forи условного оператора if.
Бывает, что в результате опечаток возникают недопустимые с т очки зрения
интерпретатора выражения. Например, можно допустить след ующую ошибку:
s = s + 2 i
С точки зрения правил Python выражение 2iникогда не может возникнуть:
имя переменной не может начинаться с цифры, а для интепретац ии2и iкак
разных сущностей между ними должен быть знак какой-нибудь а рифметической
или логической операции (чаще всего забывают знак умножения *, поскольку в
математических выражениях он обычно опускается).
Чуть сложнее разобраться с другим подвидом синтаксических ошибок, вы-
званных неверною расстановкою скобок:
N =
i nt (i nput ( ’Введите N : ’ )
s = 0
f or i in range ( N ) :
s = s + i * * 2
p rint ( s )
Такой пример вызовет ошибку invalid syntax, причём укажет на символ sв
начале второй строки, что может сбить вас с толку. На самом де ле проблема
в несоответствии числа открывающихся и закрывающихся скобок в предыду-
щей строке. Интерпретатор в поисках второй закрывающейся ск обки дошёл до
строки, следующей за тою, где совершена ошибка, и, поняв, что и скать дальше
бессмысленно (на новой строке по правилам её уже не может быт ь), выдал ошиб-
ку. При неверном числе скобок интерпретатор всегда выдаёт о шибку в начале
следующей строки.
3.4.2 Ошибки, выявляемые интерпретатором
Если вы успешно справились с синтаксисом, другие ошибки за в ас может
выявить интерпретатор во время исполнения программы. Инте рпретатор даже
напишет, что это за ошибка и в какой она строчке кода (рис. 3.2 ).
Ошибки, выявляемые интерпретатором, также называются ошибками време-
ни исполнения . Самые распространённые из них  ошибки пространства имён.
Это такие ошибки, когда имя функции, метода или введённой ва ми же перемен-
ной написано неверно. Кроме них часто возникают ошибки невер ной типизации и

3.4. Отладка программы81
Рис. 3.2. Пример ошибки, выявляемой интерпретатором во время исполнения.
ошибки, связанные с недопустимыми операциями с памятью ком пьютера. Далее
основные ошибки разобраны более подробно:
1. NameError  ошибка в имени. Вот пример неправильно написанного имени
стандартной функции range:
N =
i nt (i nput ( ’Введите N : ’ ) )
s = 0
f or i in r n a g e ( N ) :
s = s + i * * 2
При попытке выполнить этот код получится следующее:
Traceback (most recent call last): File "/home/paelius/test_error.py", line 3, in
for i in rnage(N):
NameError: name ’rnage’ is not defined
Как видим, интерпретатор, дойдя до строчки с ошибкою, указал нам, что
имя rnage ему неизвестно ( NameError: name ’rnage’ is not defined ). Найти
и исправить такие ошибки обычно довольно просто, в том числе , благодаря
тому, что все встроенные функции ( range,len ,sorted ,sum ,int и другие)
выделяются цветом (в IDLE это фиолетовый). Поэтому вы можете контро-
лировать себя уже на этапе написания кода: если rangeне подсветилось,
значит, вы написали что-то неверно. Аналогично другим  жёлт ым  цве-
том выделяются встроенные операторы и их части: in,for ,while ,if ,else ,
from ,import ,as ,with ,break ,continue , а также встроенные значения: True,
False иNone .
2. AttributeError  ошибочный атрибут. NameError не единственная лек-
сическая ошибка. Перепишем задачу так, что сначала положим все квад-
раты чисел в список, а затем воспользуемся стандартной функ циейsum:
l = [ ]
f or i in range ( N ) :

82Глава 3. Циклы
l . a p e n d ( i * * 2 )
p rint (sum ( l ) )
В этой программе есть одна трудно уловимая ошибка: в методе appendпро-
пущена одна буква p. В результате мы получим:
AttributeError:
Traceback (most recent call last): File "/home/paelius/test_error.py", line 4, in l.apend(i**2)
AttributeError: ’list’ object has no attribute ’apend’
Интерпретатор указывает нам, что объект данного типа не име ет атрибута
(метода или поля) apend. Поскольку методы даже стандартных объектов
таких, как список, никак не подсвечиваются, обнаружить эту о шибку за-
ранее сложно. Плюс в том, что исправление подобной ошибки не с оставит
труда. Есть, однако, один способ снизить вероятность их поя вления: для
длинных методов, имя которых вы плохо помните, лучше пользо ваться ав-
тодополнением.
3. TypeError  ошибка типов. Всегда следует помнить, что в третьей версии
Python функция input()возвращает строковую переменную. Если попро-
бовать написать что-то подобное:
a =
i nput ( )
b =
i nput ( )
print ( a / b )
то получим ошибку:
Traceback (most recent call last): File "E:/Python/1.py", line 3, in
print(a/b)
TypeError: unsupported operand type(s) for /: ’str’ and ’st r’
Для выявления подобных ошибок полезно выводить на экран тип перемен-
ной командою print(type(a)) .
4. ValueError  ошибка значения, являющаяся ещё одним видом ошибок,
связанных с типами данных. Она возникает, например, при поп ытке из-
влечь корень из отрицательного числа. Причём интересно, чт о ошибка бу-
дет выдана только при использовании функции sqrtиз модуля math, а при
возведении в степень стандартным образом с помощью операто ра**число
будет просто конвертировано в комплексное:

3.4. Отладка программы83
> > > ( - 3 ) * * ( 1 / 2 )
( 1 . 0 6 0 5 7 5 2 3 8 7 2 4 9 0 6 8 e - 1 6 + 1 . 7 3 2 0 5 0 8 0 7 5 6 8 8 7 7 2 j )
> > >
i mport m a t h
> > > m a t h . s q r t ( - 3 ) T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 2 > " , l i n e 1 ,
i n < m o d u l e >
m a t h . s q r t ( - 3 )
V a l u e E r r o r : m a t h d o m a i n e r r o r
5. IndexError  ошибка индекса. Появляется при обращении к несуществу-
ющему элементу строки или списка:
> > > L =
l ist (r ange ( 1 0 ) )
> > > L
[ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
> > > L [ 1 0 ]T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 5 > " , l i n e 1 ,
i n < m o d u l e >
L [ 1 0 ]
I n d e x E r r o r :
l ist i n d e x o u t o f r ange
6.OverflowError  ошибка переполнения. Возникает, когда в результате вы-
числений получается слишком большое действительное число :
p = 1 . 5
f or i in range ( 2 , 1 0 0 ) :
p = p * * i
p rint ( p )
В результате будет выдана ошибка: T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " E : / P y t h o n / 1 . p y " , l i n e 3 ,
i n < m o d u l e >
p = p * * i
O v e r f l o w E r r o r : ( 3 4 , ’ R e s u l t Ђ t o o Ђ l a r g e ’ )
3.4.3 Ошибки, выявляемые разработчиком Их ещё можно назвать логическими. Это такие ошибки, когда ва ша програм-
ма работает, но выдаёт что-то не то. Это наиболее сложный тип ошибок, потому
что их нужно не только устранять, но и выявлять самостоятель но, а для этого
необходимо думать.
Вернёмся к нашей программе расчёта суммы квадратов последо вательных
целых чисел:

84Глава 3. Циклы
Рис. 3.3. Пример логической ошибки, которая может быть выявлена только раз-
работчиком.
N =
i nt (i nput ( ’Введите N : ’ ) )
s = 0
f or i in range ( N ) :
s = s + i * 2
p rint ( s )
В окне интерпретатора вы увидите:
Введите N : 5 2 0
Казалось бы, всё неплохо: программа работает и выдаёт что-т о разумное. Но
не спешите радоваться, ведь на самом деле 02
+ 1 2
+ 2 2
+ 3 2
+ 4 2
= 30 , а вовсе не
20, как выдала наша программа (рис. 3.3). В чём же проблема?
Для выявления логических ошибок применяется такой приём, к ак тестиро-
вание. Вы уже неосознанно прибегали к нему ранее. Тестирова ние  это состав-
ление входных данных для программы, для которых вы можете са ми составить
выходные. Совокупность набора входных данных и соответств ующих им выход-
ных данных называется тестом. В нашем случае весь тест  эт о два числа:
входу 5 соответствует выход 30. Для сложных программ тесты б удут сложнее и
больше, и их понадобится не один, а много, чтобы охватить как можно больше
разных вариантов поведения программы.
Когда факт наличия ошибки установлен, нужно найти конкретн ое место, где
она возникла и устранить её. Для этого используется отладка . Отладка  это
пошаговое исполнение программы с выводом промежуточных ре зультатов, кото-
рое позволяет определить, в промежутке между какими операт орами произошла
логическая ошибка. В компилируемых языках программирован ия таких, напри-
мер, как Pascal и С, для отладки применяется специализирова нная программа-
отладчик. В интепретируемых языках, в частности в Python, в этом нет большой
необходимости, поскольку программа и так выполняется поша гово, и вы можете
вывести любые данные в любой момент с помощью стандартной функ ции print.
При отладке важно суметь сформулировать гипотезу: что нуж но проверить?

3.4. Отладка программы85
Иногда это удаётся не с первого раза. Попробуем рассмотретьэто на нашем при-
мере. Итак, первая гипотеза: счётчик iпринимает не те значения, попробуем
выводить его значения в цикле:
N =
i nt (i nput ( ’Введите N : ’ ) )
s = 0
f or i in range ( N ) :
print ( i )
s = s + i * 2
p rint ( s )
Получим:
Введите N: 5
0
1
2
3
4
20
Как видим, со счётчиком всё в порядке. Тогда проверим, всё ли в порядке с
очередным элементом суммы:
N =
i nt (i nput ( ’Введите N : ’ ) )
s = 0
f or i in range ( N ) :
s = s + i * 2
p rint ( i * 2 )
print ( s )
Получим:
0
2
4
6
8
20
Мы получили последовательность 0, 2, 4, 6, 8, в то время как до лжны были
получить 0, 1, 4, 9, 16, значит, наше предположение подтверд илось: очередной
элемент суммы вычисляется неверно. Честно говоря, уже на эт апе написания
отладочного вывода можно было заметить, что i*2это не совсем то, что нужно,
ведь вместо возведения в степень мы написали умножение (заб ыли одну звёзодч-
ку).

86Глава 3. Циклы
В более сложных программах, однако, вам часто придётся пров ерять по
нескольку гипотез и выводить значительное число отладочно й информации, что-
бы обнаружить точную причину ошибки. Помните: отладка  это мощный и эф-
фективный способ борьбы с логическими ошибками, но работае т он только тогда,
когда вы способны внятно сформулировать гипотезу, т. е. опр еделить, что про-
верять. Если начать выводить всё подряд, вы быстро потеряет есь в отладочной
информации и ничего не сможете найти.
Некоторые наиболее распространённые ошибки были прокласс ифицированы
нами в виде схемы, приведённой на рис. 3.4. Схема не претенду ет на полноту, но
будет полезна для начинающих во многих типичных случаях.
3.5 Задания на циклы
Пример задачи 11 Решим популярную задачу по нахождению всех про-
стых чисел до некоторого целого числа n. Классический алгоритм ре-
шения этой задачи носит название Решето Эратосфена. Для н ахож-
дения всех простых чисел не больше заданного числа n, следуя методу
Эратосфена, нужно выполнить следующие шаги:
1. Выписать подряд все целые числа от двух до n(2, 3, 4, . . .,n).
2. Пусть переменная pизначально равна двум  первому простому
числу.
3. Зачеркнуть в списке числа от 2p до n, считая шагами по p(это
будут числа кратные p: 2p , 3p , 4p , . . . ).
4. Найти первое незачёркнутое число в списке, большее, чем p , и при-
своить значению переменной pэто число.
5. Повторять шаги 3 и 4, пока возможно.
6. Теперь все незачёркнутые числа в списке  это все простые ч исла
от 2 до n.
Решение задачи 11 На практике алгоритм можно улучшить следующим об-
разом. На шаге №3 числа можно зачеркивать, начиная сразу с чи слаp2
, потому
что все составные числа меньше него уже будут зачеркнуты к эт ому времени. И,
соответственно, останавливать алгоритм можно, когда p2
станет больше, чем n.
f rom m a t h i mport s q r t
n =
i nt (i nput ( " вывод простых чисел до . . . " ) )
a =
l ist (r ange ( n ) )#создаём список из n элементов
# Вторым элементом является единица, которую не
# считают простым числом. Забиваем её нулем :
a [ 1 ] = 0

3.5. Задания на циклы87
Рис. 3.4. Возможные источники ошибок и алгоритм их нахождения.

88Глава 3. Циклы
#Перебор всех элементов до заданного числа :
f or p in range ( 2 , int ( s q r t ( n ) ) + 1 ) :
if a [ p ] ! = 0 :#если он не равен нулю, то
j = p * * 2 #удвоить: текущий элемент простое число
w hile j < n :
a [ j ] = 0 #заменить на 0
j = j + p #перейти в позицию на m больше
# Вывод простых чисел на экран :
b = [ ]
f or i in a :
if a [ i ] ! = 0 :
b . a p p e n d ( a [ i ] )
p rint ( b )
Вывод программы:
вывод простых чисел до числа ... 70
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67]
Задание 8 (Задания на цикл с условием) Выполнять три задания в за-
висимости от номера в списке группы в алфавитном порядке. Не обходи-
мо сделать задания № m, № m+5, № m+10 ,m=(n-1)%5+1 , гдеn номер в списке
группы.
1. Напишите программу, которая будет суммировать вводимые с клавиатуры
числа до тех пор, пока они положительны.
2. Напишите программу, которая будет суммировать вводимые с клавиатуры
числа до тех пор, пока они отрицательны.
3. Напишите программу, которая будет суммировать вводимые с клавиатуры
числа до тех пор, пока они не равны нулю.
4. Напишите программу, которая будет суммировать вводимые с клавиатуры
числа до тех пор, пока они чётные.
5. Дано число n. Напечатать те натуральные числа, квадрат которых не пре-
вышает n.
6. Дано число n. Найти первое натуральное число, квадрат которого больше n.
7. Дано число n. Среди чисел 1, 1 +1
2
,
1 + 1 2
+ 1 3
,
. . . найдите первое, большее
числа n.
8. Дано число a(1 a 1.5 ). Среди чисел 1 +1
2
,
1 + 1 3
,
1 + 1 4
,
. . . (заметим,
что каждое следующее число в последовательности меньше пред ыдущего)
найдите первое, меньшее a.

3.5. Задания на циклы89
9. Напишите программу, которая запрашивает у пользователячисла до тех
пор, пока каждое следующее число больше предыдущего. В конце програм-
ма сообщает, сколько чисел было введено.
10. Напишите программу, которая запрашивает у пользовател я числа до тех
пор, пока каждое следующее число меньше предыдущего. В конце програм-
ма сообщает, сколько чисел было введено.
11. Напишите программу, которая запрашивает у пользовател я числа до тех
пор, пока каждое следующее число целое. В конце программа соо бщает,
сколько чисел было введено.
12. Напишите программу, которая запрашивает у пользовател я числа до тех
пор, пока каждое следующее число меньше 10. В конце программа сообща-
ет, сколько чисел было введено.
13. Дано натуральное число, в котором все цифры различны. Оп ределить по-
рядковый номер его максимальной цифры, считая номера: от ко нца числа;
от начала числа.
14. Дано натуральное число, в котором все цифры различны. Оп ределить по-
рядковый номер его минимальной цифры, считая номера: от кон ца числа;
от начала числа.
15. Дано натуральное число. Определить, сколько раз в нем вс тречается мак-
симальная цифра (например, для числа 132233 ответ равен 3, д ля числа
46336  двум, для числа 12345  одному).
Задание 9 (Задания на цикл со счётчиком) Выполнять три задания в
зависимости от номера в списке группы в алфавитном порядке. Необ-
ходимо сделать задания № m, № m+5, № m+10 ,m=(n-1)%5+1 , гдеn номер в
списке группы.
1. Напишите программу, вычисляющую сумму всех чётных чисел в диапазоне
от 1 до 90 включительно.
2. Напишите программу, вычисляющую сумму всех чётных чисел в диапазоне
от aдо bвключительно (вводятся с клавиатуры).
3. Напишите программу, вычисляющую сумму всех нечётных чисе л в диапа-
зоне от 1 до 90 включительно.
4. Напишите программу, вычисляющую сумму всех нечётных чисе л в диапа-
зоне от aдо bвключительно (вводятся с клавиатуры).

90Глава 3. Циклы
5. Напечатайте таблицу умножения на 5, желательно печататьв виде:
1 × 5 = 5
2 × 5 = 10
. . .
9 × 5 = 45
Вместо знака умножения ×можно использовать строчную латинскую бук-
ву x.
6. Напечатайте таблицу умножения на 9, желательно печатать в виде:
1 × 9 = 9
2 × 9 = 18
. . .
9 × 9 = 81
Вместо знака умножения ×можно использовать строчную латинскую бук-
ву x.
7. Напечатайте таблицу умножения на целое число n,n вводится с клавиату-
ры ( 2 n 9), желательно печатать в виде:
1× n= . . .
2 × n= . . .
. . .
9 × n= . . .
Вместо знака умножения ×можно использовать строчную латинскую бук-
ву x. Внимание! Не нужно печатать символ n, вместо этого нужно печа-
тать введённое значение.
8. Напечатать таблицу стоимости 50, 100, 150, . . ., 1000 г сыра (стоимость 1 кг
сыра вводится с клавиатуры).
9. Напечатать таблицу стоимости 100, 200, 300, . . ., 2000 г конфет (стоимость
1 кг конфет вводится с клавиатуры).
10. Найти сумму всех целых чисел от 10 до 100;
11. Найти сумму всех целых чисел от aдо 100 включительно (значение aвво-
дится с клавиатуры).
12. Найти сумму всех целых чисел от 10 до bвключительно (значение bвво-
дится с клавиатуры).
13. Найти сумму всех целых чисел от aдо bвключительно (значения aи b
вводятся с клавиатуры).

3.5. Задания на циклы91
14. Найти произведение всех целых чисел от 10 до 100 включительно. Обратите
внимание, что Python может работать с целыми числами неогра ниченного
размера!
15. Найти произведение всех целых чисел от aдо bвключительно (значения a
и bвводятся с клавиатуры).
Задание 10 (Задания на комбинацию циклов со счётчиком и условием)
Выполнять одно задание с номером (n-1)%8+1в зависимости от номера
n в списке группы в алфавитном порядке.
1. За столом сидят nгостей (вводится с клавиатуры), перед которыми сто-
ит пирог. Пирог и его части можно делить только пополам. Опре делите,
сколько раз нужно делить пирог на ещё более мелкие части, что бы:
• каждому из гостей достался хотя бы 1 кусок;
• как минимум половине гостей досталось по 2 куска;
• каждому гостю досталось по 1 куску и при этом ещё хотя бы 10 кус ков
осталось в запасе.
2. Ученик 4-го класса Василий время от времени начинает прогу ливать школу.
Первый раз он прогуливает 2 дня в конце первого месяца, через месяц 
3 дня, ещё через месяц  4 дня и так далее. За каждый день прогул ов
Василию ставят по 2 двойки, плюс ещё по 3 двойки он получает в ме сяц
на занятиях. Сколько раз Василий может прогуливать школу (с колько раз
уйти в загул) и сколько дней прогуляет, чтобы не быть отчис ленным, если
отчисление грозит ему за 70 двоек? Продолжительность учебн ого года  9
месяцев, выйти из загула досрочно (не прогуляв положенно е число дней)
Василий не в состоянии, каникулами пренебречь.
3. В детском садике nдетей играют в следующую игру. Перед ними гора из m
кубиков, первый ребёнок вынимает из кучи 1 кубик, каждый пос ледующий
ребёнок  в два раза больше предыдущего и так по кругу. Если чи сло куби-
ков, которые нужно вынуть, превышает 25, из него вычитается 25 и отсчёт
идёт от уменьшенного числа, например, вместо 32 кубиков буд ет вынуто 7,
затем 14 и т. д. Проигравшим считается тот, кто не смог вытащи ть нужное
число кубиков (в куче осталось недостаточно). Определите п роигравшего.
4. Последовательность Фибоначчи определяется рекуррентн ым соотношени-
ем x
n+1 =
x
n +
x
n− 1, где
x
0 = 1
иx
1 = 1
. Найти первое число в последова-
тельности Фибоначчи, которое больше 1000.
5. Для n-го члена в последовательности Фибоначчи существует явная форму-
ла:
xn = 1
√5


1 + √
5
2 !
n+1

1− √
5
2 !
n+1 


92Глава 3. Циклы
Поскольку операции с вещественными числами происходят с конечной точ-
ностью, то с ростом n, результат вычисления по этой формуле будет все
больше отличаться от настоящего числа Фибоначчи. Найдите n, начиная с
которого, отличие от истинного значения превысит 0.001 .
6. Создайте программу, играющую с пользователем в орлянку. П рограмма
должна спрашивать у пользователя: орёл или решка. Если поль зователь
вводит 0, то выбирает орла, 1  решку, любое другое число  коне ц игры.
Программа должна вести учёт выигрышей и проигрышей и после к аждого
раунда сообщать пользователю о состоянии его счёта. Пусть в начале на
счету 3 рубля и ставка в каждом коне 1 рубль. Если денег у польз ователя
не осталось  игра прекращается. 3
7. Гражданин 1 марта открыл счет в банке, вложив 1000 руб. Чер ез каждый
месяц размер вклада увеличивается на 2% от имеющейся суммы. О преде-
лить:
•за какой месяц величина ежемесячного увеличения вклада пре высит
30 рублей;
• через сколько месяцев размер вклада превысит 1200 руб.
8. Начав тренировки, лыжник в первый день пробежал 10 км. Каж дый сле-
дующий день он увеличивал пробег на 10% от пробега предыдущег о дня.
Определить:
•в какой день он пробежит больше 20 км;
• в какой день суммарный пробег за все дни превысит 100 км.
3
Выпал орёл или решка, программа определяет с помощью функци иrandint(a, b) из стан-
дартного модуля random, которая возвращает случайное целое число n, a n b.

Глава 4
Функции
4.1 Функции в программированииФункции в программировании можно представить как изолиров анный блок
кода, обращение к которому в процессе выполнения программы может быть мно-
гократным. Зачем нужны такие блоки инструкций? В первую оче редь, чтобы со-
кратить объем исходного кода: рационально вынести часто по вторяющиеся вы-
ражения в отдельный блок и затем по мере надобности обращать ся к нему.
Для того, чтобы в полной мере осознать необходимость исполь зования функ-
ций, приведём сложный, но чрезвычайно полезный пример вычи сления корня
нелинейного уравнению с помощью метода деления отрезка поп олам.
Пусть на интервале [a ;b] имеется ровно 1 корень уравнения f(x ) = 0 . Значит,
f (a ) и f(b ) имеют разные знаки. Используем этот факт. Найдём f(c ), где c= a
+ b
2 .
Если f(c ) того же знака, что и f(a ), значит корень расположен между cи b, иначе
 между aи c.
Пусть теперь начало нового интервала (будь то aили cв зависимости от того,
где находится корень) обозначается a
1 (что означает после первой итерации), а
конец, соответственно, b
1 . Исходные начало и конец также будем обозначать
a
0
и b
0 для общности. В результате нам удасться снизить неопределё
нность того,
где находится корень, в два раза.
Такой процесс можно повторять сколько угодно раз (при расчё те на компью-
тере столько, сколько позволяет точность представления да нных ЭВМ), после-
довательно заужая интервал, в котором находится корень. Об ычно процесс за-
канчивают по достижении на n-ой итерации интервалом [a
n ;
b
n ]
величины менее
некоторого заранее заданного .
Итак, напишем программу для вычисления корня нелинейного у равнения
f (x ) = x2
− 4:
f rom m a t h i mport *
a = - 1 0
b = 1 0

94Глава 4. Функции
f(a )
f
(c )
f
(b )
f
(x )
a c
bx
f
(a )
f
(c )
f
(b )
f
(x )
a c
bx
Рис. 4.1. Иллюстрация к методу деления отрезка пополам.
w
hile ( b - a ) > 1 0 * * ( - 1 0 ) :
c = ( a + b ) / 2
f _ a = a * * 2 - 4
f _ b = b * * 2 - 4
f _ c = c * * 2 - 4
i f f _ a * f _ c > 0 :
a = c
e lse :
b = c
p rint ( ( a + b ) / 2 )
Если мы захотим вычислить корень другой нелинейной функции , например,
f (x ) = x2
+ 4 x+ 4 , то придётся переделывать выражения сразу в трёх строч-
ках. Кажется логичным выделить наше нелинейное уравнение в отдельный блок
программы. Перепишем программу с помощью функции:
f rom m a t h i mport *
def f u n k c i j a ( x ) :
f = x * * 2 + 4 * x + 4
r eturn f
a = - 1 0
b = 1 0
w hile ( b - a ) > 1 0 * * ( - 1 0 ) :

4.1. Функции в программировании95
c = ( a + b ) / 2
f _ a = f u n k c i j a ( a )
f _ b = f u n k c i j a ( b )
f _ c = f u n k c i j a ( c )
i f f _ a * f _ c > 0 :
a = c
e lse :
b = c
p rint ( ( a + b ) / 2 )
Программный код подпрограммы описывается единожды перед т елом основной
программы, затем из основной программы можно им пользовать ся многократно.
Обращение к этому программному коду из тела основной програ ммы осуществ-
ляется по его имени (имени подпрограммы).
Инструкция def это команда языка программирования Python, позволя-
ющая создавать функцию; funkcija это имя функции, которое (так же как
и имена переменных) может быть почти любым, но желательно осм ысленным.
После в скобках перечисляются параметры функции. Если их нет , то скобки
остаются пустыми. Далее идет двоеточие, обозначающее оконча ние заголовка
функции (аналогично с условиями и циклами). После заголовк а с новой строки
и с отступом следуют выражения тела функции. В конце тела функ ции обыч-
но присутствует инструкция return, после которой идёт значение или выраже-
ние, являющееся результатом работы функции. Именно оно буде т подставлено
в главной (вызывающей) программе на место функции. Принято г оворить, что
функция возвращает значение, в данном случае  результат вычисления вы-
ражения x2
+ 4 x+ 4 в конкретной точке x. В других языках программирования
такая инструкция называется также функцией, а инструкция, которая ничего
не возвращает, а только производит какие-то действия, назы ваетсяпроцеду-
рой 1
, например:
d ef p r o c e d u r a ( x ) :
f = x * * 2 + 4 * x + 4
p rint ( f )
Те же самые инструкции можно переписать в виде функции Bisection, кото-
рой передаются данные из основной программы, и которая возвр ащается корень
уравнения с заданной точностью:
f rom m a t h i mport *
def f u n c t i o n ( x ) :
f = x * * 2 - 4
1 На самом деле никакого разделения на функции и процедуры в Py thon нет. Просто те
функции, в которых возвращаемое значение не указано, возвр ащают специальное значение
None . Более того, даже если функция какой-то результат возвраща ет, вы можете его проигно-
рировать и использовать её как процедуру (в этом случае она, конечно, должна делать что-то
полезное кроме вычисления возвращаемого значения).

96Глава 4. Функции
r eturn f
def B i s e c t i o n ( a , b , e ) :
w hile ( b - a ) > e :
c = ( a + b ) / 2 f _ a = f u n c t i o n ( a )
f _ b = f u n c t i o n ( b )
f _ c = f u n c t i o n ( c )
i f f _ a * f _ c > 0 :
a = c
e lse :
b = c
r eturn ( ( a + b ) / 2 )
A = - 1 0
B = 1 0
E = 1 0 * * ( - 1 5 )
p rint ( B i s e c t i o n ( A , B , E ) )
Вывод программы:
-2.0000000000000004
В Python результатом функции может быть только одно значени е. Если необ-
ходимо в качестве результата выдать значения сразу несколь ких переменных,
используют кортеж. Продемонстрируем это, дополнив програм му вычислением
количества шагов, за которые достигается значения корня с з аданной точностью:
f rom m a t h i mport *
def f u n c t i o n ( x ) :
f = x * * 2 - 4
r eturn f
def B i s e c t i o n ( a , b , e ) :
n = 0
w hile ( b - a ) > e :
n = n + 1
c = ( a + b ) / 2 f _ a = f u n c t i o n ( a )
f _ b = f u n c t i o n ( b )
f _ c = f u n c t i o n ( c )
i f f _ a * f _ c > 0 :
a = c
e lse :
b = c
r eturn ( ( a + b ) / 2 , n )
A = - 1 0
B = 1 0
E = 1 0 * * ( - 1 5 )

4.2. Параметры и аргументы функций97
p rint ( B i s e c t i o n ( A , B , E ) )
В качестве результата выдаётся кортеж из двух чисел: значен ия корня и коли-
чества шагов, за которое был найден этот корень:
(-2.0000000000000004, 55)
Выражения тела функции выполняются лишь тогда, когда она выз ывается в
основной ветке программы. Так, например, если функция прис утствует в исход-
ном коде, но нигде не вызывается, то содержащиеся в ней инстр укции не будут
выполнены ни разу.
4.2 Параметры и аргументы функций
Часто функция используется для обработки данных, полученн ых из внешней
для нее среды (из основной ветки программы). Данные передают ся функции при
её вызове в скобках и называются аргументами. Однако чтобы фу нкция могла
взять передаваемые ей данные, необходимо при её создании описать парамет-
ры (в скобках после имени функции), представляющие собой пер еменные.
Пример:
d ef s u m m a ( a , b ) :
c = a + b
r eturn c
n u m 1 =
i nt (i nput ( ’Введите первое число : ’ ) )
n u m 2 =
i nt (i nput ( ’Введите второе число : ’ ) )
s u m m a ( n u m 1 , n u m 2 )
Здесь num1иnum2 сутьаргументы функции,aи bсуть параметры функции.
В качестве аргументов могут выступать как числовые или стро ковые кон-
станты вроде 12.3,-9 или ’Hello’ , так и переменные или выражения, например,
a+2*i .
4.2.1 Обязательные и необязательные аргументы Аргументы функции могут быть обязательными или необязатель ными. Для
всех необязательных аргументов необходимо указать значен ие по умолчанию.
Рассмотрим функцию, возводящую один свой параметр в степень , заданную
другим:
d ef D e g r e e ( x , a ) :
f = x * * a
r eturn f
Если мы попробуем вызвать эту функцию с одним аргументом вме сто двух, по-
лучим ошибку:

98Глава 4. Функции
> Degree(3)
Traceback (most recent call last):
File "", line 1, in Degree(3)
TypeError: Degree() missing 1 required positional argumen t: ’a’
Интерпретатор недоволен тем, что параметру с именем aне сопоставили ни од-
ного значения. Если мы хотим, чтобы по умолчанию функция воз водилаxв
квадрат, можно переопределить её следующим образом:
d ef D e g r e e ( x , a = 2 ) :
f = x * * a
r eturn f
Тогда наш вызов с одним аргументом станет корректным: > > > D e g r e e ( 3 )
9
При этом мы не теряем возможность использовать функцию Degreeдля воз-
ведения в произвольную степень:
> > > D e g r e e ( 3 , 4 )
8 1
В принципе, все параметры функции могут иметь значение по ум олчанию,
хотя часто это лишено смысла. Параметры, значение по умолча нию для кото-
рых не задано, называются обязательными. Важно помнить, что обязательный
параметр не может стоять после параметра, имеющего значение по умолчанию.
Попытка написать функцию, не удовлетворяющую этому требован ию, приведёт
к синтаксической ошибке:
> > >
d ef D e g r e e ( x = 2 , a ) :
f = x * * a
r eturn f
S y n t a x E r r o r : n o n - d e f a u l t a r g u m e n t f o l l o w s d e f a u l t a r g u m e n t
4.2.2 Именованные аргументы Бывает, что у функции много или очень много параметров. Или в ы забыли
порядок, в котором они расположены, но помните их смысл. Тог да можно об-
ратиться к функции, используя имена параметров как ключи. Пу сть у нас есть
следующая функция:
d ef C l o t h i n g ( D r e s s , C o l o r D r e s s , S h o e s , C o l o r S h o e s ) :
S = ’Сегодня я надену ’ + C o l o r D r e s s + ’ Ђ ’ \ + D r e s s + ’ Ђ и ’ + C o l o r S h o e s + ’ Ђ ’ + S h o e s
r eturn S

4.2. Параметры и аргументы функций99
Теперь вызовем нашу функцию, с аргументами не по порядку:
p rint ( C l o t h i n g ( C o l o r D r e s s = ’красное ’ , D r e s s = ’платье ’ ,
C o l o r S h o e s = ’чёрные ’ , S h o e s = ’туфли ’ ) )
Будет выведено:
Сегодня я надену красное платье и чёрные туфли
Как видим, результат получился верный, хотя аргументы пере числены не в том
порядке, что при определении функции. Это происходит потом у, что мы явно
указали, какие параметры соответствуют каким аргументам.
Следует отметить, что часто программисты на Python путают па раметры
со значением по умолчанию и вызов функции с именованными арг ументами.
Это происходит оттого, что синтаксически они плохо различи мы. Однако важ-
но знать, что наличие значения по умолчанию не обязывает вас использовать
имя параметра при обращении к нему. Также и отсутствие значе ния по умолча-
нию не означает, что к параметру нельзя обращаться по имени. Например, для
описанной выше функции Degreeвсе следующие вызовы будут корректными и
приведут к одинаковому результату:
> > > D e g r e e ( 3 )
9
> > > D e g r e e ( 3 , 2 )
9
> > > D e g r e e ( 3 , a = 2 )
9 > > > D e g r e e ( x = 3 , a = 2 )
9
> > > D e g r e e ( a = 2 , x = 3 )
9
Чего нельзя делать, так это ставить обязательные аргументы после необяза-
тельных, если имена параметров не указаны:
> > > D e g r e e ( a = 2 , 3 )S y n t a x E r r o r : n o n - k e y w o r d a r g a f t e r k e y w o r d a r g
4.2.3 Произвольное количество аргументов Иногда возникает ситуация, когда вы заранее не знаете, како е количество ар-
гументов будет необходимо принять функции. Для такого случ ая есть специаль-
ный синтаксис: все параметры обозначаются одним именем (обы чно используется
имя args ) и перед ним ставится звёздочка *. Например:
d ef u n k n o w n ( * a r g s ) :
for a r g u m e n t in a r g s :

100Глава 4. Функции
p rint ( a r g u m e n t )
u n k n o w n ( ’Что ’ , ’происходит ’ , ’ ? ’ )
u n k n o w n ( ’Не знаю ! ’ )
Вывод программы:
Что
происходит
?
Не знаю!
При этом тип значения args кортеж, содержащий все переданные аргументы
по порядку.
4.3 Локальные и глобальные переменные
Если записать в IDLE приведённую ниже функцию, и затем попроб овать вы-
вести значения переменных, то обнаружится, что некоторые и з них почему-то не
существуют:
> > >
d ef m a t h e m ( a , b ) :
a = a / 2
b = b + 1 0
p rint ( a + b )
> > > n u m 1 = 1 0 0
> > > n u m 2 = 1 2
> > > m a t h e m ( n u m 1 , n u m 2 )
7 2 . 0
> > > n u m 1 > > > 1 0 0
> > > n u m 2
1 2 > > > aT r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) :
F i l e " < p y s h e l l # 1 0 > " , l i n e 1 ,
i n < m o d u l e >
a N a m e E r r o r : n a m e ’ a ’
i s not d e f i n e d
> > > b T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) :
F i l e " < p y s h e l l # 1 1 > " , l i n e 1 ,
i n < m o d u l e >
b N a m e E r r o r : n a m e ’ b ’
i s not d e f i n e d
> > >
Переменные num1иnum2 не изменили своих первоначальных значений. Дело в
том, что в функцию передаются копии значений. Прежние значен ия из основной
ветки программы остались связанны с их переменными.

4.3. Локальные и глобальные переменные101
А вот переменныхaи b, оказывается, нет и в помине (ошибка name ’b’ is
not defined переводится как "переменная b не определена" ). Эти переменные су-
ществуют лишь в момент выполнения функции и называются локальными. В
противовес им, переменные num1иnum2 видны не только во внешней ветке, но и
внутри функции:
> > >
d ef m a t h e m 2 ( ) :
p rint ( n u m 1 + n u m 2 )
> > > m a t h e m 2 ( )
1 1 2 > > >
Переменные, определённые в основной ветке программы, явля ютсяглобаль-
ными . Итак, в Python две базовых области видимости переменных:
1. глобальные переменные,
2. локальные переменные. Переменные, объявленные внутри тела функции, имеют локальн ую область
видимости, те, что объявлены вне какой-либо функции, имеют г лобальную об-
ласть видимости. Это означает, что доступ к локальным перем енным имеют
только те функции, в которых они были объявлены, в то время ка к доступ к
глобальным переменным можно получить по всей программе в люб ой функции.
Например:
P l a c e = ’Солнечная система ’ #Глобальная переменная
d ef g l o b a l _ P o s i t i o n ( ) :
p rint ( P l a c e )
def l o c a l _ P o s i t i o n ( ) :
P l a c e = ’Земля ’ #Локальная переменная
p rint ( P l a c e )
S =
i nput ( )
if S = = ’система ’ :
g l o b a l _ P o s i t i o n ( )
e lse :
l o c a l _ P o s i t i o n ( )
Вывод программы при двух последовательных запусках: система
Солнечная система > > >= = = = = = = = = = = R E S T A R T : / h o m e / p a e l i u s / P y t h o n / 1 . p y = = = = = = = = = = =
планета Земля

102Глава 4. Функции
Важно помнить, что для того чтобы получить доступ к глобальн ой перемен-
ной на чтение, достаточно лишь указать её имя. Однако если пе ред нами стоит
задача изменить глобальную переменную внутри функции, нео бходимо исполь-
зовать ключевое слово global. Например:
N u m b e r = 1 0
d ef c h a n g e ( ) :
g lobal N u m b e r
N u m b e r = 2 0
p rint ( N u m b e r )
c h a n g e ( )
p rint ( N u m b e r )
Вывод программы:
10
20
Если забыть написать строчку global Number, то интерпретатор выдаст следу-
ющее:
10
10
4.4 Программирование сверху вниз
Вряд ли стоило бы уделять много внимания функциям, если бы за ними не
скрывались важные и основополагающие идеи. В действительно сти, функции
оказывают решающее влияние на стиль и качество работы програм миста. Функ-
ция  это не только способ сокращения текста, но что более важ но, средство
разложения программы на логически связанные, замкнутые ко мпоненты, опре-
деляющие её структуру.
Представьте себе программу, содержащую, например, 1000 стр ок кода (это
ещё очень маленькая программа). Обозреть такое количество строк и понять,
что делает программа, было бы практически невозможно без фу нкций.
Большие программы строятся методом последовательных уточ нений. На пер-
вом этапе внимание обращено на глобальные проблемы, и в перв ом эскизном про-
екте упускаются из виду многие детали. По мере продвижения пр оцесса создания
программы глобальные задачи разбиваются на некоторое число подзадач. Те, в
свою очередь, на более мелкие подзадачи и т.д., пока решать к аждую подзадачу
не станет достаточно просто. Такая декомпозиция и одноврем енная детализация
программы называется нисходящим методомпрограммирования или програм-
мированием сверху вниз .
Концепция функций позволяет выделить отдельную подзадачу как отдель-
ную подпрограмму. Тогда на каждом этапе можно придумать име на функций
для подзадач, вписывать в раздел описаний их заголовки и, ещ ё не добавляя к

4.5. Рекурсивный вызов функции103
ним тело функции, уже использовать их вызовы для создания каркаса програм-
мы так, будто они уже написаны. Например, на численных методах студенты решают задачу сравн ения двух
методов поиска корня уравнения: уже расписанного выше мето да деления отрез-
ка пополам и метода Ньютона. Необходимо понять, какой из мето дов быстрее
сходится к корню с заданной точностью.
Концепция программирования сверху вниз предусматривае т, что вначале
студенты напишут скелет программы, а уже потом начнут раз бираться, как
какая функция функционирует в отдельности:
d ef F u n c t i o n ( X )#Наше нелинейное уравнение
d ef N e w t o n ( a , b , E )#Метод Ньютона
d ef B i s e c t i o n ( a , b , E )#Метод деления отрезка пополам
A = ?
B = ?
E = ? B i s e c t i o n ( A , B , E ) #Вызов функции метода деления отрезка пополам #
N e w t o n ( A , B , E ) #Вызов функции метода Ньютона #
Какие именно инструкции будут выполняться функциями Bisectionи
Newton пока не сказано, но уже известно, что они принимают на вход и чт о долж-
ны возвращать. Это следующий этап написания программы. Пото м нам известно,
что наше нелинейное уравнение, корень которого необходимо найти, желатель-
но оформить в виде отдельной функции. Так появляется функци яFunction ,
которая будет вызываться внутри функций BisectionиNewton .
Когда каркас создан, остаётся только написать тела функций . Преимущество
такого подхода в том, что, создавая тело каждой из функций, м ожно не думать об
остальных функциях, сосредоточившись на одной подзадаче. Кроме того, когда
каждая из функций имеет понятный смысл, гораздо легче, взгл янув на програм-
му, понять, что она делает. Это в свою очередь позволит: (а) д опускать меньше
логических ошибок и (б) организовать совместную работу нес кольких програм-
мистов над большой программой. Важной идеей при таком подходе становится использование ло кальных пере-
менных. В глобальную переменную можно было бы записать резу льтат работы
функции, однако это будет стилистической ошибкой. Весь обм ен информацией
функция должна вести исключительно через параметры. Такой п одход позволя-
ет сделать решение каждой подзадачи максимально независим ым от остальных
подзадач, упрощает и упорядочивает структуру программы.
4.5 Рекурсивный вызов функции
Рекурсия в программировании  это вызов функции из неё же сам ой непо-
средственно (простая рекурсия) или через другие функции (с ложная или кос-
венная рекурсия), например, функция Aвызывает функцию B, а функция B

104Глава 4. Функции
функциюA. Количество вложенных вызовов функции или процедуры назыв ается
глубиной рекурсии. Рекурсивная программа позволяет описа ть повторяющееся
или даже потенциально бесконечное вычисление, причём без я вных повторений
частей программы и использования циклов. Принцип работы рекурсивной функции удобнее всего объяснят ь на приме-
ре матрёшек (рис. 4.2). Пусть есть набор нераскрашенных мат рёшек. Нужно
узнать, в какие цвета покрасить самую большую матрёшку. При этом раскраше-
на только самая маленькая матрёшка, которая не раскрываетс я. Необходимо по-
следовательно раскрывать матрёшки, пока не дойдём до той, к оторую раскрыть
не получается  это раскрашенная матрёшка. Далее можно раск рашивать каж-
дую следующую матрёшку по возрастанию, держа перед собою пред ыдущую как
пример и затем вкладывать все меньшие, раскрашенные ранее, во вновь раскра-
шенную. От матрёшек можно перейти к классическому примеру рекурсии , которым
может послужить функция вычисления факториала числа:
d ef f a c t ( n u m ) :
if n u m = = 0 :
r eturn 1
else :
r eturn n u m * f a c t ( n u m - 1 )
n =
i nt (i nput ( ’Введите число ’ ) )
print ( f a c t ( n ) )
Структурно рекурсивная функция на верхнем уровне всегда пр едставляет
собой команду ветвления (выбор одной из двух или более альте рнатив в зависи-
мости от условия (условий), которое в данном случае уместно назвать условием
прекращения рекурсии, имеющей две или более альтернативны е ветви, из ко-
торых хотя бы одна является рекурсивной и хотя бы одна  терминальной.
В вышеприведённых примерах с матрёшками и с вычислением фак ториала
условия если матрёшка не раскрывается и if num==0являются командами
ветвления, ветвь return 1(или самая маленькая раскрашенная матрёшка) яв-
ляется терминальной, а ветвь return num*fact(num-1)(постепенное раскраши-
вание и закрывание матрёшек)  рекурсивной.
Рекурсивная ветвь выполняется, когда условие прекращения рекурсии лож-
но, и содержит хотя бы один рекурсивный вызов  прямой или опо средованный
вызов функцией самой себя. Терминальная ветвь выполняется , когда условие
прекращения рекурсии истинно; она возвращает некоторое зн ачение, не выпол-
няя рекурсивного вызова. Правильно написанная рекурсивна я функция должна
гарантировать, что через конечное число рекурсивных вызов ов будет достигнуто
выполнение условия прекращения рекурсии, в результате чег о цепочка последо-
вательных рекурсивных вызовов прервётся и выполнится возв рат.
Помимо функций, выполняющих один рекурсивный вызов в каждой рекур-
сивной ветви, бывают случаи параллельной рекурсии, когда на одной рекур-
сивной ветви делается два или более рекурсивных вызова. Пар аллельная ре-

4.5. Рекурсивный вызов функции105
Рис. 4.2. Наглядное представление принципа работы рекурсивной функции.

106Глава 4. Функции
курсия типична при обработке сложных структур данных, таки х как деревья.
Простейший пример параллельно-рекурсивной функции – вычи сление ряда Фи-
боначчи, где для получения значения n-го члена необходимо вычислить (n − 1)-й
и (n − 2)-й:
d ef f i b ( n ) :
if n < 3 :
r eturn 1
return f i b ( n - 1 ) + f i b ( n - 2 )
n =
i nt (i nput ( ’Введите число : ’ ) )
print ( f i b ( 1 0 ) )
Реализация рекурсивных вызовов функций в практически прим еняемых язы-
ках и средах программирования, как правило, опирается на ме ханизм стека вы-
зовов  адрес возврата и локальные переменные функции запис ываются в стек,
благодаря чему каждый следующий рекурсивный вызов этой функ ции пользу-
ется своим набором локальных переменных и за счёт этого рабо тает корректно.
Оборотной стороной этого довольно простого по структуре ме ханизма является
то, что на каждый рекурсивный вызов требуется некоторое кол ичество опера-
тивной памяти компьютера, и при чрезмерно большой глубине ре курсии может
наступить переполнение стека вызовов. Вопрос о желательности использования рекурсивных функций в программи-
ровании неоднозначен: с одной стороны, рекурсивная форма м ожет быть струк-
турно проще и нагляднее, в особенности, когда сам реализуем ый алгоритм, по
сути, рекурсивен. Кроме того, в некоторых декларативных ил и чисто функци-
ональных языках (таких, как Пролог или Haskell) просто нет си нтаксических
средств для организации циклов, и рекурсия в них  единствен ный доступный
механизм организации повторяющихся вычислений. С другой ст ороны, обычно
рекомендуется избегать рекурсивных программ, которые при водят (или в некото-
рых условиях могут приводить) к слишком большой глубине рек урсии. Так, ши-
роко распространённый в учебной литературе пример рекурси вного вычисления
факториала является, скорее, примером того, как не надо при менять рекурсию,
так как приводит к достаточно большой глубине рекурсии и име ет очевидную
реализацию в виде обычного циклического алгоритма.
4.6 Примеры решения заданий
Пример задачи 12 Напишите функцию, вычисляющую значения экспо-
ненты по рекуррентной формуле ex
= 1 + x+ x
2
2! + x
3 3! +
· · · =P

n=0 x
n n
!. Ре-
ализуйте контроль точности вычислений с помощью дополните льного
параметра со значением по умолчанию (следует остановить вычисле-
ния, когда очередное приближение будет отличаться от преды дущего
менее, чем на 10−
10
).
Реализуйте вызов функции различными способами:

4.6. Примеры решения заданий107
•с одним позиционным параметром (при этом будет использован о
значение по умолчанию);
• с двумя позиционными параметрами (значение точности будет пе-
редано как второй аргумент);
• передав значение как именованный параметр.
Решение задачи 12
d ef E X P O N E N T A ( x , e p s = 1 0 * * ( - 1 0 ) ) :
e x = 1 #будущий результат
d x = x #приращение
i = 2 #номер приращения
w hile abs ( d x ) > e p s :
e x = e x + d x
d x = d x * x / i
i = i + 1
r eturn e x
# Основная программа
A =
f loat (input ( ’Введите показатель экспоненты : ’ ) )
print ( E X P O N E N T A ( A ) )
print ( E X P O N E N T A ( A , 1 0 * * ( - 4 ) ) )
print ( E X P O N E N T A ( x = A )
Пример задачи 13 Сделайте из функции процедуру (вместо того, что-
бы вернуть результат с помощью оператора return, выведите его внут-
ри функции с помощью функции print).
Решение задачи 13
d ef E X P O N E N T A ( x , e p s = 1 0 * * ( - 1 0 ) ) :
e x = 1 #будущий результат
d x = x #приращение
i = 2 #номер приращения
w hile abs ( d x ) > e p s :
e x = e x + d x
d x = d x * x / i
i = i + 1
p rint ( e x )
# Основная программа
A =
f loat (input ( ’Введите показатель экспоненты : ’ ) )
E X P O N E N T A ( A )

108Глава 4. Функции
4.7 Задания на функции
Задание 11Выполнять одно задание в зависимости от номера в спис-
ке: (n-1)%10+1 , гдеn номер в списке. Напишите функцию, вычисляю-
щую значения одной из следующих специальных функций по рекур рент-
ной формуле. Реализуйте контроль точности вычислений с пом ощью до-
полнительного параметра со значением по умолчанию (следует оста-
новить вычисления, когда очередное приближение будет отли чаться от
предыдущего менее, чем на 10−
10
). Реализуйте вызов функции различны-
ми способами:
•с одним позиционным параметром (при этом будет использован о
значение по умолчанию);
• с двумя позиционными параметрами (значение точности будет пе-
редано как второй аргумент);
• передав значение как именованный параметр.
Сделайте из функции процедуру (вместо того, чтобы вернуть р езуль-
тат с помощью оператора return, выведите его внутри функции с по-
мощью функции print).
1. Косинус cos(x) = 1 −x
2
2! + x
4 4! − · · ·
=P

n=0 (
− 1) n
x2
n (2 n)! . Формула хорошо ра-
ботает для −2 x 2 , поскольку получена разложением в ряд Тейлора
возле ноля. Для прочих значений xследует воспользоваться свойствами
периодичности косинуса: cos(x) = cos(2 + 2 n), где nесть любое целое
число, тогда cos(x) = cos(x%(2*math.pi)) . Для проверки использовать
функцию math.cos(x) .
2. Синус sin(x) = x− x
3
3! + x
5 5! +
· · · =P

n=0 (
− 1) n
x2
n +1 (2 n+1)! . Формула хорошо ра-
ботает для −2 x 2 , поскольку получена разложением в ряд Тейлора
возле ноля. Для прочих значений xследует воспользоваться свойствами пе-
риодичности косинуса: sin(x) = sin(2 + 2 n), где nесть любое целое число,
тогда sin(x) = sin(x%(2*math.pi)) . Для проверки использовать функцию
math.sin(x) .
3. Гиперболический косинус ch(x) = 1 + x
2
2! + x
4 4! +
· · · =P

n=0 x
2
n (2 n)! . Для про-
верки использовать функцию math.cosh(x).
4. Гиперболический косинус по формуле для экспоненты, оста вляя только
слагаемые с чётными n. Для проверки использовать функцию math.cosh(x).
5. Гиперболический синус sh(x) = x+ x
3
3! + x
5 5! +
· · · =P

n=0 x
2
n +1 (2 n+1)! . Для про-
верки использовать функцию math.sinh(x).

4.7. Задания на функции109
6. Гиперболический синус по формуле для экспоненты, оставляя только сла-
гаемые с нечётными n. Для проверки использовать функцию math.sinh(x).
7. Натуральный логарифм (формула работает при 0< x 2):
ln( x) = ( x− 1) − (
x − 1)2
2 +
(
x − 1)3 3 −
(
x − 1)4 4 +
· · · =∞
X
n =1 (
− 1) n
− 1(
x − 1)n n
Чтобы найти логарифм для x >2, необходимо представить его в виде
ln( x) = ln( y·2p
) = pln(2) + ln( y), где y <2, а pнатуральное число. Чтобы
найти pи y, нужно в цикле делить xна 2 до тех пор, пока результат больше
2. Когда очередной результат деления станет меньше 2, этот р езультат и
есть y, а число делений, за которое он достигнут – это p. Для проверки
использовать функцию math.log(x).
8. Гамма-функция (x) по формуле Эйлера:
(x) = 1
x∞
Y
n =1
1 + 1
n
x
1 + x n
Формула справедлива для x /∈ { 0,− 1,− 2, . . . }. Для проверки можно исполь-
зовать math.gamma(x) . Также, поскольку (x+ 1) = x! для натуральных x,
то для проверки можно использовать функцию math.factorial(x).
9. Функция ошибок, также известная как интеграл ошибок, инт еграл вероят-
ности, или функция Лапласа:
erf (x) = 2
√Z
x
0 e

t2
dt = 2 √∞
X
n =0 x 2
n + 1 n
Y
i =1 −
x2 i
Для проверки использовать функцию scipy.special.erf(x).
10. Дополнительная функция ошибок:
erfc(x) = 1 −erf ( x) = 2
√Z

x e

t2
dt = e

x2 x √ ∞
X
n =0 (
− 1) n
(2
n)! n!(2 x)2
n
Для проверки использовать функцию scipy.special.erf(x).
Задание 12 (Танцы) Выполнять в каждом разделе по одному заданию
в зависимости от номера в списке группы: (n-1)%5+1, гдеn номер в
списке.
1. два списка имён: первый  мальчиков, второй  девочек;
2. один список имён и число мальчиков, все имена мальчиков ст оят в
начале списка;

110Глава 4. Функции
3. один список имён и число девочек, все имена девочек стоят в начале
списка;
4. словарь, в котором в качестве ключа используется имя, а в ка че-
стве значения символ м для мальчиков и символ ж для девоч ек;
5. словарь, в котором в качестве ключей выступают символы м и ж, а в качестве соответствующих им значений  списки маль-
чиков и девочек соответственно.
Проверьте работу функции на разных примерах: •когда мальчиков и девочек поровну,
• когда мальчиков больше, чем девочек, и наоборот,
• когда есть ровно 1 мальчик или ровно 1 девочка,
• когда либо мальчиков, либо девочек нет вовсе.
Модифицируйте функцию так, чтобы она принимала второй необя за-
тельный параметр  список уже составленных пар, участников кото-
рых для составления пар использовать нельзя. В качестве зна чения по
умолчанию для этого аргумента используйте пустой список. П роверьте
работу функции, обратившись к ней:
•как и ранее (с одним аргументом), в этом случае результат дол жен
совпасть с ранее полученным;
• передав все аргументы позиционно без имён;
• передав последний аргумент (список уже составленных пар) п о име-
ни;
• передав все аргументы по имени в произвольном порядке.
Задание 13 (Создание списков) Напишите функцию, принимающую от
1 до 3 параметров  целых чисел (как стандартная функция range).
Единственный обязательный аргумент  последнее число. Есл и поданы
2 аргумента, то первый интерпретируется как начальное числ о, второй
 как конечное (не включительно). Если поданы 3 аргумента, то тре-
тий аргумент интерпретируется как шаг. Функция должна выда вать
один из следующих списков:
1. квадратов чисел;
2. кубов чисел;
3. квадратных корней чисел;

4.7. Задания на функции111
4. логарифмов чисел;
5. чисел последовательности Фибоначчи с номерами в указанных пре-
делах.
Запускайте вашу функцию со всеми возможными вариантами по ч ислу
параметров: от 1 до 3.
Подсказка: проблему переменного числа параметров, из кото рых
необязательным является в том числе первый, можно решить 2- мя
способами. Во-первых, можно сопоставить всем параметрам н ечисло-
вые значения по умолчанию, обычно для этого используют специа льное
значение None. Тогда используя условный оператор можно определить,
сколько параметров реально заданы (не равны None). В зависимости от
этого следует интерпретировать значение первого аргумент а как: конец
последовательности, если зада только 1 параметр; как начал о, если за-
даны 2 или 3. Во-вторых, можно проделать то же, используя син таксис
функции с произвольным числом параметров; в таком случае за давать
значения по умолчанию не нужно, а полезно использовать стан дартную
функцию len, которая выдаст количество реально используемых пара-
метров.
Задание 14 (Интернет-магазин) Решите задачу об интернет-торговле.
Несколько покупателей в течении года делали покупки в интер нет-
магазине. При каждой покупке фиксировались имя покупателя (строка)
и потраченная сумма (действительное число). Напишите функ цию, рас-
считывающую для каждого покупателя и выдающую в виде словаря п о
всем покупателям (вида имя:значение) один из следующих пара метров:
1. число покупок;
2. среднюю сумму покупки;
3. максимальную сумму покупки;
4. минимальную сумму покупки;
5. общую сумму всех покупок.
На вход функции передаётся:
•либо 2 списка, в первом из которых имена покупателей (могут п о-
вторяться), во втором – суммы покупок;
• либо 1 список, состоящий из пар вида (имя, сумма);
• либо словарь, в котором в качестве ключей используются имена, а
в качестве значений  списки с суммами.

Глава 5
Массивы. Модульnumpy
Сам по себе чистый Python пригоден только для несложных вы числений.
Ключевая особенность Python  его расширяемость. Это, пожал уй, самый рас-
ширяемый язык из получивших широкое распространение. Как с ледствие этого
для Python не только написаны и приспособлены многочисленн ые библиотеки
алгоритмов на C и Fortran, но и имеются возможности использов ания других
программных средств и математических пакетов, в частности , R и SciLab, а так-
же графопостроителей, например, Gnuplot и PLPlot.
Ключевыми модулями для превращения Python в математический пакет яв-
ляются numpyиmatplotlib .
numpy  это модуль (в действительности, набор модулей) языка Pyth on, до-
бавляющая поддержку больших многомерных массивов и матриц, вместе с боль-
шим набором высокоуровневых (и очень быстрых) математичес ких функций для
операций с этими массивами.
matplotlib  модуль (в действительности, набор модулей) на языке про-
граммирования Python для визуализации данных двумерной (2 D) графикой (3D
графика также поддерживается). Получаемые изображения мо гут быть исполь-
зованы в качестве иллюстраций в публикациях.
Кроме numpyиmatplotlib популярностью пользуются scipyдля специализи-
рованных математических вычислений (поиск минимума и корн ей функции мно-
гих переменных, аппроксимация сплайнами, вейвлет-преобр азования),sympyдля
символьных вычислений (аналитическое взятие интегралов, упрощение матема-
тических выражений), ffnetдля построения искусственных нейронных сетей,
pyopencl /pycuda для вычисления на видеокартах и некоторые другие. Возмож-
ности numpy иscipy покрывают практически все потребности в математических
алгоритмах.

5.1. Создание и индексация массивов113
(a)(b)
Рис. 5.1. Одномерный  (a) и двумерный  (b) массивы.
5.1 Создание и индексация массивов Массив  упорядоченный набор значений одного типа, располо женных в па-
мяти непосредственно друг за другом. При этом доступ к отдел ьным элемен-
там массива осуществляется с помощью индексации, то есть че рез ссылку на
массив с указанием номера (индекса) нужного элемента. Это в озможно потому,
что все значения имеют один и тот же тип, занимая одно и то же кол ичество
байт памяти; таким образом, зная ссылку и номер элемента, мо жно вычислить,
где он расположен в памяти. Количество используемых индекс ов массива может
быть различным: массивы с одним индексом называют одномерны ми, с двумя 
двумерными, и т. д. Одномерный массив (колонка, столбец ) примерно соот-
ветствует вектору в математике (на рис. 5.1(а) a[4] == 56, т.е. четвёртый эле-
мент массива а равен 56); двумерный  матрице (на рис. 5.1(b) можно писать
A[1][6] == 22 , можноA[1, 6] == 22 ). Чаще всего применяются массивы с од-
ним или двумя индексами; реже  с тремя; ещё большее количест во индексов
встречается крайне редко.
Как правило, в программировании массивы делятся на статическиеиди-
намические .Статический массив  массив, размер которого определяется на
момент компиляции программы. В языках с динамической типиз ацией таких,
как Python, они не применяются. Динамический массив массив, размер кото-
рого задаётся во время работы программы. То есть при запуске программы этот
массив не занимает нисколько памяти компьютера (может быть, за исключе-
нием памяти, необходимой для хранения ссылки). Динамическ ие массивы могут
поддерживать и не поддерживать изменение размера в процесс е исполнения про-
граммы. Массивы в Python не поддерживают явное изменение раз мера: у них, в
отличие от списков, нет методов appendиextend , позволяющих добавлять эле-
менты, и методов popиremove , позволяющих их удалять. Если нужно изменить
размер массива, это можно сделать путём переприсваивания и мени переменной,

114Глава 5. Массивы. Модульnumpy
обозначающей массив, нового значения, соответствующего нов ой области памя-
ти, больше или меньше прежней разными способами.
Базовый оператор создания массива называется array. С его помощью можно
создать новый массив с нуля или превратить в массив уже сущес твующий список.
Вот пример:
f rom n u m p y i mport *
A = a r r a y ( [ 0 . 1 , 0 . 4 , 3 , - 1 1 . 2 , 9 ] )
p rint ( A )
print (type ( A ) )
В первой строке из модуля numpyимпортируются все функции и константы.
Вывод программы следующий:
[0.1 0.4 3. -11.2 9. ]

Функция array()трансформирует вложенные последовательности в много-
мерные массивы. Тип элементов массива зависит от типа элеме нтов исходной
последовательности:
B = a r r a y ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] )
p rint ( B )
Вывод:
[[1 2 3] [4 5 6]]
Тип элементов массива можно определить в момент создания с п омощью име-
нованного аргумента dtype. Модуль numpyпредоставляет выбор из следующих
встроенных типов: bool(логическое значение), character(символ),int8,int16 ,
int32 ,int64 (знаковые целые числа размеров в 8, 16, 32 и 64 бита соответст вен-
но), uint8 ,uint16 ,uint32 ,uint64 (беззнаковые целые числа размеров в 8, 16, 32
и 64 бита соответственно), float32иfloat64 (действительные числа одинарной
и двойной точности), complex64иcomplex128 (комплексные числа одинарной и
двойной точности), а также возможность определить собстве нные типы данных,
в том числе и составные.
C = a r r a y ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] , d t y p e =
f loat )
print ( C )
Вывод:
[[ 1. 2. 3.] [ 4. 5. 6.]]
Можно создать массив из диапазона:

5.1. Создание и индексация массивов115
f rom n u m p y i mport *
L =
r ange ( 5 )
A = a r r a y ( L )
p rint ( A )
Вывод:
[0 1 2 3 4]
Отсюда видно, что в первом случае массив состоит из действит ельных чисел,
так как при определении часть его значений задана в виде деся тичных дробей. В
numpy есть несколько действительнозначных типов, базовый тип со ответствует
действительным числам Python и называется float64. Второй массив состоит
из целых чисел, потому что создан из диапазона range, в который входят толь-
ко целые числа. На 64-битных операционных системах элемент ы такого списка
будут автоматически приведены к целому типу int64, на 32-битных  к типу
int32 .
В numpy есть функция arange, позволяющая сразу создать массив-диапазон,
причём можно использовать дробный шаг. Вот программа, расс читывающая зна-
чения синуса на одном периоде с шагом /6:
f rom n u m p y i mport *
a 1 = a r a n g e ( 0 , 2 * p i , p i / 6 )
s 1 = s i n ( a 1 )
f or j in range (len ( a 1 ) ) :
p rint ( a 1 [ j ] , s 1 [ j ] )
А вот её вывод:
0.0 0.0
0.523598775598 0.5
1.0471975512 0.866025403784
1.57079632679 1.0
2.09439510239 0.866025403784
2.61799387799 0.5
3.14159265359 1.22464679915e-16
3.66519142919 -0.5
4.18879020479 -0.866025403784
4.71238898038 -1.0
5.23598775598 -0.866025403784
5.75958653158 -0.5
Кроме arange есть ещё функция linspace, тоже создающая массив-диапазон.
Её первые два аргумента те же, что и у arange: начало и конец диапазона, а
третий аргумент  количество элементов в диапазоне. К сожал ению, по умолча-
нию эти функции по разному обрабатывают второй аргумент: arangeберёт его
невключительно, linspace включительно. Это можно поправить с помощью

116Глава 5. Массивы. Модульnumpy
A[:, 0]
A[2:, 2:5]
A[0, 3:]
Рис. 5.2. Примеры срезов массивов: чёрным  срезы, в результ ате которых из
двумерного массива получаются одномерные (из столбца и стро ки исходного мас-
сива соответственно); тёмносерым  срез, в результате кото рого получается дву-
мерный массив меньшего размера.
опционного, четвёртого аргумента linspace, если установить его в False. Вот
пример задания одинаковых массивов с помощью arangeиlinspace :
> > > a = n u m p y . a r a n g e ( 0 , 2 , 0 . 2 5 )
> > >
p rint ( a )
[ 0 . 0 . 2 5 0 . 5 0 . 7 5 1 . 1 . 2 5 1 . 5 1 . 7 5 ]
> > > b = n u m p y . l i n s p a c e ( 0 , 2 , 8 , F a l s e )
> > >
p rint ( a )
[ 0 . 0 . 2 5 0 . 5 0 . 7 5 1 . 1 . 2 5 1 . 5 1 . 7 5 ]
Массивы построены на базе списков и сохраняют некоторые их че рты. В част-
ности, массивы можно обходить циклом любым из изложенных выш е способов, а
функция lenвозвращает длину массива. Важным свойством массивов являе тся
то, что над ними можно производить операции как над простыми числами, при
этом операция, в нашем случае вычисление синуса, будет прои зведена с каждым
элементом массива.
Модуль numpyдублирует и расширяет функционал модуля math, он содержит
все основные тригонометрические, логарифмические и прочи е функции, а также
константы, поэтому при работе с numpyнадобности в mathобычно не возникает.
Одна из важнейших особенностей массивов  возможность дела ть срезы (см.
рис. 5.2). Срез представляет собою массив из части элементо в исходного массива,

5.1. Создание и индексация массивов117
взятых по некоторому простому правилу, например, каждый второй или первые
десять. Вот небольшая программа, иллюстрирующая создание ср езов массивов:
f rom n u m p y i mport *
a 1 = a r a n g e ( 0 , 4 , 0 . 5 )
p rint ( a 1 )
a 2 = a 1 [ 0 : 4 ]
p rint ( a 2 )
a 3 = a 1 [ 0 :
l en ( a 1 ) : 2 ]
p rint ( a 3 )
Массив a2состоит из первых четырёх (от нулевого включительно до чет-
вёртого невключительно) элементов массива a1, массив a3 из всех чётных
элементов a1(элементы от нулевого до последнего с шагом 2). Для обозначе ния
индексации используются двоеточия, сначала ставится номер начального индек-
са, потом конечного, потом шаг, все они  целые числа (точно в том же порядке,
как и в функциях rangeиarange ). Если шаг и стоящее перед ним двоеточие
опустить, шаг будет автоматически единичным. Вот вывод про граммы:
[ 0. 0.5 1. 1.5 2. 2.5 3. 3.5]
[ 0. 0.5 1. 1.5]
[ 0. 1. 2. 3.]
Нужно отметить, что массив-срез делит с исходным массивом п амять. Это
значит, что копирование элементов в новый массив не происхо дит, вместо этого
просто делается сложная ссылка. Поэтому изменение элемент ов исходного мас-
сива приводит к изменению элементов массива-среза и наобор от. Чтобы скопи-
ровать элементы, нужно воспользоваться функцией copy. Здесь у внимательных
читателей должен возникнуть эффект d´ej`a vu, потому что не что подобное уже
было в разделе про списки.
f rom n u m p y i mport *
a 1 = a r a n g e ( 0 , 0 . 6 , 0 . 1 )
a 2 = a 1 [ :
l en ( a 1 ) / 2 ]
p rint ( a 1 , a 2 )
a 1 [ 0 ] = 1 0
a 1 [ - 1 ] = a 1 [ - 1 ] + 3
p rint ( a 1 , a 2 )
a 2 [ 1 ] = 0
p rint ( a 1 , a 2 )
Вывод программы:
[0. 0.1 0.2 0.3 0.4 0.5] [ 0. 0.1 0.2]
[10. 0.1 0.2 0.3 0.4 3.5] [10. 0.1 0.2]
[10. 0. 0.2 0.3 0.4 3.5] [10. 0. 0.2]

118Глава 5. Массивы. Модульnumpy
В приведённом примере мы поменяли нулевой и последний элеме нты массиваa1,
в результате в массиве a2нулевой элемент тоже изменился, затем мы поменяли
первый элемент a2, и первый элемент a1также изменился. Теперь тот же пример,
но с использованием функции copy:
f rom n u m p y i mport *
a 1 = a r a n g e ( 0 , 0 . 6 , 0 . 1 )
a 2 = c o p y ( a 1 [ :
l en ( a 1 ) / 2 ] )
p rint ( a 1 , a 2 )
a 1 [ 0 ] = 1 0
a 1 [ - 1 ] = a 1 [ - 1 ] + 3
p rint ( a 1 , a 2 )
a 2 [ 1 ] = 0
p rint ( a 1 , a 2 )
Теперь в выводе видно, что изменение одного из массивов не пр иводит к изме-
нению другого:
[0. 0.1 0.2 0.3 0.4 0.5] [0. 0.1 0.2]
[10. 0.1 0.2 0.3 0.4 3.5] [0. 0.1 0.2]
[10. 0.1 0.2 0.3 0.4 3.5] [0. 0. 0.2]
В приведённых примерах было использовано ещё одно свойство индексации:
если номер начального элемента опустить, то автоматически подставляется ноль,
если опустить номер конечного  длина массива. Функция array()не единственная функция для создания массивов. Обычно
элементы массива вначале неизвестны, а массив, в котором он и будут хранить-
ся, уже нужен. Поэтому имеется несколько функций для того, ч тобы создавать
массивы с каким-то исходным содержимым (по умолчанию тип эл ементов созда-
ваемого массива  float64):ones создаёт массив из единиц, zeros массив из
нулей, empty массив, значения элементов которого могут быть какими уго д-
но (берётся то, что лежало в ячейках памяти до того, как в них б ыл размещён
массив). Все эти функции принимают единственный параметр  д лину вновь
создаваемого массива. Вот пример их работы:
f rom n u m p y i mport *
a 1 = o n e s ( 5 )
a 2 = z e r o s ( 3 )
a 3 = e m p t y ( 4 )
p rint ( a 1 )
print ( a 2 )
print ( a 3 )
Вывод:
[1. 1. 1. 1. 1.]
[0. 0. 0.]
[4.39718425e-322 0.00000000e+000 0.00000000e+000 2.842 36875e-316]

5.1. Создание и индексация массивов119
Видно, что вa3помещены 4 произвольных числа. В нашем случае они получи-
лись равными или близкими к нулю, но рассчитывать на это в обще м случае не
приходится.
Можно вручную задать тип данных:
a 3 = e m p t y ( 5 , d t y p e =
i nt )
p rint ( a 3 )
Вывод:
[500 0 0 0 0]
В данном примере как раз хорошо видно, что нулевой элемент ма ссива далеко
не равен нулю.
Если массив слишком большой, чтобы его печатать, numpyавтоматически
скрывает центральную часть массива и выводит только его уго лки:
A = a r a n g e ( 0 , 3 0 0 0 , 1 )
p rint ( A )
Вывод:
[ 0 1 2 ..., 2997 2998 2999]
Если вам действительно нужно увидеть весь массив, использу йте функцию
numpy.set_printoptions :
A = a r a n g e ( 0 , 3 0 0 0 , 1 ) s e t _ p r i n t o p t i o n s ( t h r e s h o l d = n a n )
p rint ( A )
И вообще, с помощью этой функции можно настроить печать масс ивов под се-
бя. Функция numpy.set_printoptions принимает несколько аргументов? опи-
сание которых при необходимости можно с лёгкостью найти в оф ициальной до-
кументации к numpyв интернете.
Действительные числа из numpyтипаfloat64 обладают практически всеми
теми же свойствами, что и встроенные числа Python, но могут п ринимать три
дополнительных специальных значения: inf,-inf илиnan, что можно перевести
как бесконечность, минус бесконечность и неопределённост ь. Если поделить дей-
ствительное число типа numpy.float64на 0, получится inf -infв зависимости
от его знака, а вместо ошибки будет выдано только предупрежд ение, которое
позволит продолжить вычисления. Программа:
a = n p . a r r a y ( [ 2 . , 0 . , 5 . ] )
f or e l in a :
p rint ( 1 . / e l )
выдаст:

120Глава 5. Массивы. Модульnumpy
0.5
/usr/bin/ipython3:2: RuntimeWarning: divide by zero enco untered in
double_scalars
inf
0.2
5.2 Арифметические операции и функции с массивами
Python  объектно-ориентированный язык программирования . Каждая пе-
ременная Python  объект, хотя часто это совсем незаметно. П оэтому многие
переменные Python имеют встроенные методы  присущие им функ ции  и
свойства. Так, массивы имеют ряд очень простых, но полезных м етодов, сильно
упрощающих жизнь при написании сложных программ. Собственн о, именно по-
этому в сложных программах удобнее использовать именно мас сивы, а не списки.
Самые часто используемые занесены в таблицу 5.1. Пусть у нас есть массив вида
a=numpy.array([0.1, 0.25, -1.75, 0.4, -0.9]) :
Таблица 5.1. Некоторые методы массивов
Метод Описание
a.sum() Сумма элементов массива:
len( a)
X
i =0 a
i = 0
.1 + 0 .25 −1.75 + 0 .4 − 0.9 = −1.9
a.mean() Среднее элементов массива:
a = 1 len(
a) len(
a)
X
i =0 a
i = (0
.1 + 0 .25 −1.75 + 0 .4 − 0.9) /5 = −0.38
a.min() Минимальный элемент массива: −1.75
a.min() Максимальный элемент массива: 0.4
a.var() Дисперсия элементов массива:
2
a = 1
len(
a) len(
a)
X
i =0 (
a
i − a
) = ((0 .1 + 0 .38) 2
+ (0 .25 + 0 .38) 2
(− 1.78 +
0 .38) 2
+ (0 .4 + 0 .38) 2
+ ( −0.9 + 0 .38) 2
)/ 5 = 0 .6766
a.std() Среднеквадратичное отклонение элементов массива от средн его:
a = 0
.822556988907
Вот небольшая программа, показывающая, как эти функции рабо тают:
f rom n u m p y i mport *
a = a r r a y ( [ 0 . 1 , 0 . 2 5 , - 1 . 7 5 , 0 . 4 , - 0 . 9 ] )
p rint ( a . sum ( ) )
p rint ( a . m e a n ( ) )
print ( a . min ( ) )

5.2. Арифметические операции и функции с массивами121
p rint ( a . max ( ) )
p rint ( a . v a r ( ) )
print ( a . s t d ( ) )
Вывод программы:
-1.9
-0.38
-1.75
0.4
0.6766
0.822556988907
Обратите внимание на круглые скобки после имени каждой функ ции  они
указывают, что вызывается и исполняется соответствующая фун кция. Если скоб-
ки забыть, никаких вычислений не будет произведено, а вмест о их результа-
тов будут напечатаны строки документации соответствующих ф ункций. То есть
a.min()  это результат вычисления, минимальный элемент массива a, но a.min
 это сам метод вычисления:
p rint ( a . min )
Вывод:

Поскольку Python язык очень глубоко объектный, сами по себе методы, как
и их параметры и результаты, тоже являются объектами. Тип рез ультата встро-
енных функций определяется их природою: min,max иsum всегда того же типа,
что и элементы массива, а вот var,mean иstd всегда действительнозначные,
поскольку для их вычисления выполняются деление и  для std извлечение
квадратного корня.
Библиотека numpyунаследовала от Fortran ряд особенностей работы с мас-
сивами, не присущих C, Pascal, Java, C# и прочим распростран ённым языкам
общего назначения: массивы numpyможно складывать, как простые числа, при-
бавлять к ним число, умножать и делить друг на друга и на число . При этом
все операции происходят поэлементно. Вот пример программы сложения двух
массивов и умножения массива на число:
f rom n u m p y i mport *
a = a r r a y ( [ 0 . 1 , 0 . 2 5 , - 1 . 7 5 , 0 . 4 , - 0 . 9 ] )
b = a r r a y ( [ 0 . 9 , 1 . 7 5 , - 0 . 1 5 , 0 . 4 , 0 . 4 ] )
c = a + b
p rint ( c )
d = a + 1 . 5
p rint ( d )
Программа выведет:

122Глава 5. Массивы. Модульnumpy
[ 1. 2. -1.9 0.8 -0.5]
[ 1.6 1.75 -0.25 1.9 0.6 ]
Такие операции называются иногда векторными в том смысле, что оди-
наковые действия производятся сразу с большим набором данн ых. Складывать
можно только массивы одинаковой длины. Аналогично можно пер емножать мас-
сивы. Число можно прибавлять к любому массиву или умножать ма ссив на чис-
ло, в результате получается массив того же размера, что и исх одный, а каждый
его элемент есть результат сложения (или умножения) соотве тствующего элемен-
та исходного массива и числа. Такой синтаксис операций позв оляет существенно
упростить запись сложных программ, избежав множества цикл ов, которые при-
шлось бы писать на С или Pascal. В векторных операциях можно использовать как целые массивы , так и их
срезы:
f rom n u m p y i mport *
a = a r r a y ( [ 0 . 1 , 0 . 2 5 , - 1 . 7 5 , 0 . 4 , - 0 . 9 ] )
b = a r r a y ( [ 0 . 9 , 1 . 7 5 , - 0 . 1 5 , 0 . 4 , 0 . 4 ] )
c = a [ : 3 ] + b [ 1 : 4 ]
p rint ( c )
d = a [ 2 : 4 ] * a [ 0 : 2 ]
p rint ( d )
Вот вывод программы:
[ 1.85 0.1 -1.35]
[-0.175 0.1 ]
Обратите внимание ещё раз: при перемножении массивов дейст вия производятся
поэлементно, в результате чего получается новый массив той же длины, а вовсе
не их векторное произведение, как это принято в некоторых ма тематических
пакетах. Вот пример:
> > >
i mport n u m p y
> > > n u m p y . a r r a y ( [ - 1 . 7 5 , 0 . 4 ] ) * n u m p y . a r r a y ( [ 0 . 1 , 0 . 2 5 ] )
a r r a y ( [ - 0 . 1 7 5 , 0 . 1 ] )
в то время как в результате скалярного произведения должно б ыло получиться:
-1.75*0.1 + 0.4*0.25 = -0.075 .
Кроме арифметических операций над массивами можно также ве кторно вы-
полнять все заложенные в numpyфункции, например, взять синус или логарифм
от массива (если написать просто log(X), то получится натуральный логарифм,
иначе нужно написать основание логарифма вторым аргументо мlog(X, 10) ).
Вот пример такой программы:
f rom n u m p y i mport *
t = a r a n g e ( 0 , p i , p i / 6 )
x = s i n ( t )

5.2. Арифметические операции и функции с массивами123
y = l o g ( t )
p rint ( t )
print ( x )
print ( y )
Вывод:
[0. 0.52359878 1.04719755 1.57079633 2.0943951 2.6179938 8]
[0. 0.5 0.8660254 1. 0.8660254 0.5]
[-inf -0.64702958
0.0461176 0.45158271 0.73926478 0.96240833]
Здесь мы протабулировали (вычислили значения функций при и зменении ар-
гумента в некоторых пределах) две функции: sin(t) и ln( t) на полуинтервале
[0; ) с шагом /6. Как видим, можно проделывать над массивами сколь угодно
сложные векторные операции. Так как натуральный логарифм н уля равен минус
бесконечности, то получился соответствующий ответ: -inf.
Массивы numpyможно обходить циклом, как списки. Чтобы сделать наше
табулирование более удобным и привычным для чтения, модифи цируем преды-
дущую программу, чтобы она выдавала результат своей работы в три столбца.
Для этого заменим последнюю строку, где стоят операторы print, на две новые:
f or i in range (len ( t ) ) :
p rint ( t [ i ] , x [ i ] , y [ i ] )
Вывод программы:
0.0 0.0 -inf
0.523598775598 0.5 -0.647029583379
1.0471975512 0.866025403784 0.0461175971813
1.57079632679 1.0 0.451582705289
2.09439510239 0.866025403784 0.739264777741
2.61799387799 0.5 0.962408329055
Полученные столбцы чисел выглядят понятно, но не очень през ентабельно,
поскольку каждая запись выглядит по-своему  все они имеют ра зное число
знаков после точки. Для получения стройных колонок можно во спользоваться
встроенным методом форматирования, поменяв последнюю стро ку приведённой
программы на следующую:
p rint ( " { : 1 2 . 8 f } \ t { : 1 2 . 8 f } \ t { : 1 2 . 8 f } " . f ormat ( t [ i ] ,
x [ i ] , y [ i ] ) )
Здесь символ ’\t’означает табуляцию, впереди идёт строка форматирования,
где :12.8f означает, что на это место будет подставлено действительно е чис-
ло (на это указывает f) с 12 знаками, из них после десятичной точки 8. Три
подставляемых числа взяты в скобки. Вывод программы:

124Глава 5. Массивы. Модульnumpy
0.00000000 0.00000000 -inf
0.52359878 0.50000000 -0.64702958
1.04719755 0.86602540 0.04611760
1.57079633 1.00000000 0.45158271
2.09439510 0.86602540 0.73926478
2.61799388 0.50000000 0.96240833
В Python есть специальные операторы +=,-= , которые увеличивают и умень-
шают одно число на другое, а также операторы *=и/= , которые умножают и
делят одно число на другое, например:
> > > a = 1 0
> > > a + = 4
> > >
p rint ( a )
1 4 > > > a - = 8
> > >
p rint ( a )
6
По сути эти инструкции аналогичны инструкциям типа a = a + bилиa = a -
b , где b число, на которое нужно увеличить или уменьшить a. Преимущество
использования операторов +=,-= кроме краткости записи состоит в том, что при
их использовании новый объект не создаётся, а только модифи цируется исход-
ный, в то время как запись a = a + bилиa = a - b приводит к уничтожению
старого объекта с именем a(его должен будет удалить из памяти сборщик мусо-
ра) и созданию нового с тем же именем. Поэтому использование операторов+=,
-= наиболее актуально при работе со сложными типами вроде масс ивовnumpy ,
так как на их создание и размещение в памяти, а также удаление тратится го-
раздо больше ресурсов. Вот пример:
> > > x = n u m p y . a r r a y ( [ 0 . , 2 . , 0 . 5 , - 1 . 7 , 3 . ] )
> > > x
a r r a y ( [ 0 . , 2 . , 0 . 5 , - 1 . 7 , 3 . ] ) > > > x + = 1
> > >
p rint ( x )
[ 1 . 3 . 1 . 5 - 0 . 7 4 . ] > > > x - = 2 . 5
> > >
p rint ( x )
[ - 1 . 5 0 . 5 - 1 . - 3 . 2 1 . 5 ] > > > x + = n u m p y . l i n s p a c e ( 0 , 4 , 5 )
> > >
p rint ( x )
[ - 1 . 5 1 . 5 1 . - 0 . 2 5 . 5 ]
Как видим, прибавлять и вычитать из массивов таким образом м ожно как числа,
так и другие массивы (нужно, чтобы совпал размер). Использование операторов +=,-= в ряде случаев позволяет избежать некото-
рых сложно уловимых ошибок с именами переменных и, иногда, с их типами.

5.3. Двумерные массивы, форма массивов125
Скажем, нужно увеличить переменную со сложным именем, а затем использо-
вать её в дальнейших вычислениях. Вот пример, когда перемен ная со сложным
названием komputilo_de_nombro_de_eventoj используется в качестве счётчика
событий (нужно посчитать число положительных элементов ма ссиваx, описан-
ного ранее):
> > > k o m p u t i l o _ d e _ n o m b r o _ d e _ e v e n t o j = 0
> > >
f or e l a in x :
if e l a > 0 :
k o m p u t i l o _ d e _ n p m b r o j _ d e _ e v e n t o j = \
k o m p u t i l o _ d e _ n o m b r o _ d e _ e v e n t o j + 1
> > >
p rint ( k o m p u t i l o _ d e _ n o m b r o _ d e _ e v e n t o j )
0
Программа отработала без сообщений об ошибках, но результа т получил-
ся неверный: 0 вместо 3. Всё дело в том, что мы ошиблись в имени пере-
менной в строке внутри условного оператора. В результате на каждом ша-
ге цикла, когда условие оказалось истинно, создавалась нов ая переменная
komputilo_de_npmbroj_de_eventoj , которой каждый раз присваивалось одно
и то же значение 1 (поскольку исходная переменная-счётчик б ыла равна 0, а к
ней прибавлялось 1), нужная же переменная komputilo_de_nombro_de_eventoj
не изменялась. Эта ошибка была бы невозможна при использова нии оператора
-= :
> > > k o m p u t i l o _ d e _ n o m b r o _ d e _ e v e n t o j = 0
> > >
f or e l a in x :
if e l a > 0 :
k o m p u t i l o _ d e _ n p m b r o j _ d e _ e v e n t o j + = 1
T r a c e b a c k ( m o s t r e c e n t c a l l l a s t ) : F i l e " < p y s h e l l # 9 2 > " , l i n e 3 ,
i n < m o d u l e >
k o m p u t i l o _ d e _ n p m b r o j _ d e _ e v e n t o j + = 1
N a m e E r r o r : n a m e ’ k o m p u t i l o _ d e _ n p m b r o j _ d e _ e v e n t o j ’
i s not
d e f i n e d
В результате мы получили сообщение об ошибке NameError, сразу локализовав
возникшую проблему. Такие ошибки могут быть очень коварны в случае, если
полученное на данном этапе значение используется в дальней ших вычислениях.
5.3 Двумерные массивы, форма массивов Никакие сложные вычисления не могут обойтись без двумерных массивов,
часто называемых матрицами. Модуль numpyпозволяет оперировать с массива-
ми произвольной размерности: одномерными, двумерными, тр ёхмерными и т. д.
Чтобы работать с массивами произвольной размерности, удоб но пользоваться

126Глава 5. Массивы. Модульnumpy
понятием формы (shape). Форма  совокупность длин массива по каждому из-
мерению. Обычно форма задаётся в виде кортежа из нескольких ч исел: двух для
двумерного, трёх для трёхмерного и т. д. Форма  свойство мас сива и обозначает-
ся shape . Форму массива можно задать при его создании. Если массив со здаётся
при помощи какой-нибудь встроенной функции numpy, его форма определяется
этой функцией. Для одномерных массивов форма  это просто ег о длина.
f rom n u m p y i mport *
x = z e r o s ( ( 2 , 3 ) )
y = e y e ( 3 )
p rint ( x )
print ( y )
print ( x . s h a p e )
print (len ( x ) )
p rint ( y . s h a p e )
Вот вывод программы:
[[ 0. 0. 0.] [ 0. 0. 0.]]
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
(2, 3)
2
(3, 3)
В приведённом примере мы создали матрицу размера 2× 3из нулей с помощью
функции zeros(в качестве аргумента передаём кортеж из двух числе (2, 3));
аналогично можно создать матрицу произвольного размера. Ф ункцияeyeпри-
нимает единственный скалярный аргумент, поскольку она соз даёт единичную
квадратную матрицу заданного размера. Видно, что длина мас сива (len)  это
его первая размерность (в ранних версиях numpyдлина соответствовала общему
числу элементов, т. е. произведению размерностей).
Также к двумерным массивам применимы операции sum,mean ,max и т. д. По
умолчанию, эти операции применяются к массиву, как если бы он б ыл линейным
списком всех чисел, независимо от его формы. Однако, указав параметрaxis,
можно применить операцию для указанной оси массива:
f rom n u m p y i mport *
a = a r r a y ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] )
p rint ( a . sum ( ) )
p rint ( a . sum ( a x i s = 0 ) )
p rint ( a . sum ( a x i s = 1 ) )
p rint ( a . min ( ) )
p rint ( a . min ( a x i s = 0 ) )
p rint ( a . min ( a x i s = 1 ) )

5.3. Двумерные массивы, форма массивов127
Вывод программы:
21
[5 7 9]
[ 6 15]
1
[1 2 3]
[1 4]
Видно, чтоaxis=0работает с каждым столбцом отдельно, а axis=1 с каждою
строкою отдельно.
Итерирование многомерных массивов начинается с нулевой ос и:
f rom n u m p y i mport *
a = a r r a y ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] )
f or e l e m e n t in a :
p rint ( e l e m e n t )
Вывод:
[1 2 3]
[4 5 6]
Однако если нужно перебрать поэлементно весь массив, как ес ли бы он был
одномерным, для этого можно использовать атрибут flat:
f or e l e m e n t in a . f l a t :
p rint ( e l e m e n t )
Вывод:
1
2
3
4
5
6
Несколько массивов могут быть объединены вместе вдоль разн ых осей с по-
мощью функций hstackиvstack :hstack() объединяет массивы по начальному
индексу, vstack()  по последнему:
f rom n u m p y i mport *
a = a r r a y ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] )
b = a r r a y ( [ [ 5 , 6 , 7 ] , [ 8 , 9 , 1 0 ] ] )
p rint ( v s t a c k ( ( a , b ) ) )
print ( h s t a c k ( ( a , b ) ) )
Вывод:

128Глава 5. Массивы. Модульnumpy
A
a
1,0 a1,1
a
0,0 a0,1
a3,0 a3,1
a2,0 a2,1
b1,1 b1,2
b
0,1 b0,2
b1,0
b0,0
B
c0,0
c
1,1
c0,1
c2,1
c3,1
c
1,2
c3,0 c 3,2
c
1,0
c2,0
c 0,2
c2,2 C
Рис. 5.3. Схема матричного умножения: C=A× B.
[[ 1 2 3] [ 4 5 6]
[ 5 6 7]
[ 8 9 10]]
[[ 1 2 3 5 6 7] [ 4 5 6 8 9 10]]
Используя hsplit()вы можете разбить массив вдоль горизонтальной оси,
указав либо число возвращаемых массивов одинаковой формы, либо номера
столбцов, после которых массив разрезается ножницами. Н о лучше для этого
использовать срезы. Например, выведем первый столбец масс иваa:
p rint ( a [ : , 1 ] )
Вывод:
[2 5]
Модуль numpyпредоставляет множество различных функций для работы с
многомерными массивами, одна из самых популярных  функция dot. Для мат-
риц и одномерных массивов-векторов эта функция соответств ует функции мат-
ричного умножения, см. рис. 5.3 (скалярное произведение дл я двух одномерных
массивов):
f rom n u m p y i mport *
a = a r r a y ( [ [ 1 , 0 ] , [ 0 , 1 ] ] )
b = a r r a y ( [ [ 4 , 1 ] , [ 2 , 2 ] ] )
p rint ( d o t ( a , b ) )
x = a r r a y ( [ - 4 , 1 , 3 , 2 ] )
y = a r r a y ( [ - 1 , 8 , 1 , - 2 ] )

5.3. Двумерные массивы, форма массивов129
p rint ( d o t ( x , y ) )
z = a r r a y ( [ 5 , - 2 ] )
p rint ( d o t ( z , b ) )
print ( d o t ( b , z ) )
Вывод программы показывает, что одномерный массив интерпр етируется как
вектор-столбец или вектор-строка в зависимости от контекс та (об этом не нужно
заботиться дополнительно):
[[4 1] [2 2]]
11
[16 1]
[18 6]
В версиях Python, начиная с 3.5 и новее для обозначения матри чного умножения
вместо функции dotможно использовать символ @:
> > >
f rom n u m p y i mport *
> > > a = a r r a y ( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] , [ 7 , 8 , 9 ] ] )
> > > a @ a
a r r a y ( [ [ 3 0 , 3 6 , 4 2 ] , [ 6 6 , 8 1 , 9 6 ] ,
[ 1 0 2 , 1 2 6 , 1 5 0 ] ] )
Существуют две очень простые в использовании и чрезвычайно п олезные
функции в numpy, которые легко позволяют перейти от задач чисто учебных
к задачам практически важным. Дело в том, что на практике все данные хра-
нятся в файлах, чаще всего текстовых. Функция loadtxtпозволяет загрузить
данные из текстового файла в двумерный или одномерный, если в исходном
файле данные представлены в 1 столбец или строку, массив. Фу нкцияsavetxt в
свою очередь позволяет записать массив в текстовый файл. Пр имер работы этих
функций приведён ниже:
f rom n u m p y i mport *
a = e y e ( 3 )
b = a r a n g e ( 0 , 1 0 , 1 ) s a v e t x t ( ’ e y e 3 . t x t ’ , a )
s a v e t x t ( ’ M a s . t x t ’ , b )
a 2 = l o a d t x t ( ’ e y e 3 . t x t ’ )
p rint ( a 2 )
b 2 = l o a d t x t ( ’ M a s . t x t ’ )
p rint ( b 2 )
По выводу программы видно, что чтение в переменную a2произошло успеш-
но:

130Глава 5. Массивы. Модульnumpy
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
Наличие файлов ’eye3.txt’и’Mas.txt’ на диске и его содержимое вы можете
проверить с помощью вашего файлового менеджера.
5.4 Примеры решения задач
Пример задачи 14 Создайте и выведите на экран квадратную матрицу
размера n× n, где на главной диагонали стоят нули, элементы выше
неё  единицы, ниже  минус единицы. Затем сохраните получив шийся
массив в текстовый файл.
Решение задачи 14
f rom n u m p y i mport *
n =
i nt (i nput ( ’Размер матрицы : ’ ) )
x = z e r o s ( ( n , n ) )
f or i in range ( n ) :
x [ i , : i ] = - 1
x [ i , i + 1 : ] = 1
p rint ( x )
s a v e t x t ( ’ M a s . t x t ’ , x )
Вывод программы:
Размер матрицы: 3
[[ 0. 1. 1.] [-1. 0. 1.]
[-1. -1. 0.]]
Заметим, что здесь мы воспользовались срезами, попутно сок ратив 1 цикл и
убрав условный оператор.
Пример задачи 15 С помощью функции loadtxtзагрузите из файла, со-
зданного в предыдущем задании, данные в массив y. Убедитесь, что но-
вый массив получился двумерным. Создайте одномерный масси в-диапазон
и прибавьте его к вашей матрице. Посмотрите, что получилось . Опре-
делите максимальный и минимальный элементы массива. Посчи тайте
сумму элементов по каждой строке массива. Запишите в два отд ельных
текстовых файла ваш массив-матрицу и массив-вектор.
Решение задачи 15

5.4. Примеры решения задач131
f rom n u m p y i mport *
y = l o a d t x t ( ’ M a s . t x t ’ )
p rint ( y . s h a p e )
a = a r a n g e ( 0 , n , 1 )
y = y + a
p rint ( y )
print ( y . min ( ) )
p rint ( y . max ( ) )
p rint ( y . sum ( a x i s = 1 ) )
s a v e t x t ( ’ M a t r i x . t x t ’ , y )
s a v e t x t ( ’ V e c t o r . t x t ’ , a )
Вывод программы:
(3, 3)
[[ 0. 2. 3.] [-1. 1. 3.]
[-1. 0. 2.]]
-1.0
3.0
[ 5. 3. 1.]
Пример задачи 16 Протабулируйте (вычислите значения функций при
изменении аргумента в некоторых пределах с заданным шагом) функцию
на отрезке [− ; ].
Решение задачи 16
f rom n u m p y i mport *
t = a r a n g e ( - p i , p i , p i / 6 )
x = s i n ( t )
f or i in range (len ( t ) ) :
p rint ( " { : 1 2 . 8 f } \ t { : 1 2 . 8 f } " . f ormat ( t [ i ] , x [ i ] ) )
Вывод программы:
-3.14159265 -0.00000000
-2.61799388 -0.50000000
-2.09439510 -0.86602540
-1.57079633 -1.00000000
-1.04719755 -0.86602540
-0.52359878 -0.50000000
-0.00000000 -0.00000000 0.52359878 0.50000000
1.04719755 0.86602540

132Глава 5. Массивы. Модульnumpy
1.57079633 1.00000000
2.09439510 0.86602540
2.61799388 0.50000000
5.5 Задания на массивы, модуль numpy
В заданиях 15 и 17 следует выполнить три пункта в зависимости от номера в
списке группы в алфавитном порядке. Необходимо сделать зад ания №m, № m+ 5 ,
№ m + 10 ,m = ( n− 1)%5 + 1 , гдеn номер в списке группы.
Задание 15 Создайте и выведите на экран массивы. Получившиеся мат-
рицы сохраните в текстовые файлы.
1. из нулей одномерные длины 10 и 55, матрицу размерами 3× 4, трёхмерный
массив формы 2× 4× 5;
2. из единиц одномерные длины 10 и 55, матрицу размерами 3× 4, трёхмерный
массив формы 2× 4× 5;
3. из девяток одномерные длины 10 и 55, матрицу размерами 3× 4, трёхмерный
массив формы 2× 4× 5;
4. одномерные длины 10 и 55, матрицу размерами 3× 4, трёхмерный массив
формы 2× 4× 5, все состоящие целиком из значений 0.25;
5. массив-диапазон от −10 до 10с шагом 0.1 ;
6. массив-диапазон от −e до eс шагом e/50 ;
7. массив-диапазон от −15 до 15с шагом pi/12;
8. единичную матрицу размера 5× 5;
9. диагональную матрицу размера 5× 5, все значения на главной диагонали
которой равны 0.5;
10. матрицу размера 5× 5, где на главной диагонали стоят единицы, а прочие
элементы равны 2;
11. матрицу размера 5× 5, где в первом столбце стоят единицы, во втором 
двойки, в третьем  тройки и т. д.
12. матрицу размера 5× 5, где в первой строке стоят единицы, во втором 
двойки, в третьем  тройки и т. д.
13. матрицу размера 5× 5, где на главной диагонали стоят нули, элементы
выше неё  единицы, ниже  минус единицы;

5.5. Задания на массивы, модульnumpy 133
14. верхнюю треугольную матрицу5× 5, где все элементы выше главной диа-
гонали равны −2, а на ней  единицы;
15. нижнюю треугольную матрицу 5× 5, где все элементы ниже главной диа-
гонали равны 2, а на ней  единицы.
Внимание: задания 10–15 требуют умения манипулировать с отдельными
столбцами или строками двумерного массива!
Задание 16 Загрузите из файла, созданного в предыдущем задании, дан-
ные в массив. Убедитесь, что новый массив получился двумерн ый. Со-
здайте одномерный массив-диапазон и прибавьте его к вашей м атрице.
Посмотрите, что получилось. Определите максимальный и мин ималь-
ный элементы массива. Посчитайте сумму элементов по каждой стро-
ке массива. Запишите в два отдельных текстовых файла ваши ма ссив-
матрицу и массив-вектор.
Задание 17 Протабулируйте (вычислите значения функций при измене-
нии аргумента в некоторых пределах с заданным шагом) функци и:
1. x2
на отрезке x∈ [− 2; 2] с шагом 0.01, с шагом 0.1, с шагом 0.25;
2. x3
на отрезке x∈ [− 2; 2] с шагом 0.01, с шагом 0.1, с шагом 0.25;
3. x4
на отрезке x∈ [− 2; 2] с шагом 0.01, с шагом 0.1, с шагом 0.25;
4. cos(2 t)на отрезке t∈ [− 10; 10] с шагом 1 и с шагом 0.25;
5. 1
t
cos(2
t)на отрезке t∈ [1; 10] с шагом 1 и с шагом 0.25;
6. e−
t
cos(2 t)на отрезке t∈ [− 10; 10] с шагом 1 и с шагом 0.25;
7. 4 sin( t+/ 8) −1на отрезке t∈ [− 10; 10] с шагом 1 и с шагом 0.25;
8. 2 cos( t− 2) + sin(2 ∗t− 4) на отрезке t∈ [− 20 ; 10 ] с шагом и с шагом
/ 12;
9. ln(x+ 1) на отрезке x∈ [0; e− 1] с шагом 0.01 и с шагом 0.001;
10. log
2(
|x |) на отрезке x∈ [− 4; 4] за исключением точки x= 0 с шагом 0.1 и с
шагом 0.25;
11. 2x
на отрезке x∈ [− 2; 2] с шагом 0.01, с шагом 0.1, с шагом 0.25;
12. ex
на отрезке x∈ [− 2; 2] с шагом 0.01, с шагом 0.1, с шагом 0.25;
13. 2−
x
на отрезке x∈ [− 2; 2] с шагом 0.01, с шагом 0.1, с шагом 0.25;
14. 3

x
на отрезке x∈ [1; 125] с шагом 1 и с шагом 5, но так, чтобы значения 1
и 5 присутствовали среди аргументов;
15. 5

x
на отрезке x∈ [1; 32] с шагом 1 и с шагом 0.25.

Глава 6
Графики. Модульmatplotlib
Построение графиков  один из главных этапов обработки данн ых. Все со-
временные компьютерные программы, предоставляющие функцию построения
графиков, условно можно разделить на две категории: програ ммы с визуаль-
ным интерфейсом, где построение и редактирование графика о существляется
средствами разного рода меню, полей ввода, лист-боксов, чек -боксов и других
виджетов, и программы, где для построения графика необходи мо писать коман-
ды, объединяемые в так называемы скрипты. К первой категори и относятся,
например, Origin, MS Excel, OpenOffice/LibreOffice Calc, Stat istica, Grapher, ко
второй  gnuplot, многие математические пакеты, например, MATLAB и SciLab
и различные библиотеки вроде PGPlot и PLPlot, имеющие поддер жку во многих
языках программирования.
Основное преимущество скриптового способа построения гра фика в том, что
вы можете встроить его без проблем в вашу программу, произво дящую вычис-
ления. Кроме того, скрипты позволяют легко перестраивать гр афики с новыми
данными, автоматизировать построение графиков, дают почти неограниченный
контроль над точностью позиционирования и размером детале й.
Модуль matplotlib  специализированная библиотека для языка Python. Хо-
тя основное её преимущество в простоте и быстроте использов ания, она позволя-
ет делать графики очень высокого типографского качества. М одульmatplotlib
базируется на возможностях numpy, установка которого обязательна для функ-
ционирования matplotlib.
6.1 Простые графики Непосредственно за построение графиков отвечает библиоте каpyplot модуля
matplotlib . Основная команда для построения графиков  команда plot. У
команды plotсуществует множество вариантов синтаксиса, в простейшем с лучае
она требует единственный аргумент  массив, но подойдёт и сп исок, кортеж или
даже диапазон. Вот пример построения простейшего графика ( см. рис. 6.1(a)):

6.1. Простые графики135
f rom m a t p l o t l i b . p y p l o t i mport *
x = [ 3 , 4 , 6 , 1 2 . 5 , 1 3 . 4 , 8 . 9 , 7 . 1 ] p l o t ( x )
s h o w ( )
Команда show()даётся без аргументов и нужна для того, чтобы вывести на
экран содержимое графического буфера, куда заносятся резу льтаты ваших дей-
ствий. В приведённом примере получился график в виде ломано й, где по оси
абсцисс отложены номера элементов списка x, а по оси ординат  сами эти эле-
менты. Чтобы изменить тип линии или заменить её на маркеры, м ожно указать
дополнительный аргумент в команде plot строку форматирования. Например,
строка из одного символа дефиса ’-’соответствует поведению по умолчанию 
сплошной линии, ’–’ прерывистой линии, ’:’ пунктиру. При этом маркеры:
кружочки, квадраты, ромбы будут располагаться только в тех местах, где есть
данные.
0 1 2 3 4 5 6 2
4
6
8
10
12
14
0 1 2 3 4 5 6 2
4
6
8
10
12
14
(a) (b)
Рис. 6.1. Простейший график сплошными линиями  (a) и пункти ром и круж-
ками одновременно  (b).
Маркеры и линии можно комбинировать. Изменим предпоследнюю строчку
предыдущей программы следующим образом (результат на рис. 6 .1(b)):
p l o t ( x , ’ : o ’ )
s h o w ( ) В результате, тот же график будет выглядеть немного иначе: н а месте распо-
ложения данных появятся жирные синие кружки, соединённые т онкою пунктир-
ною линией. Чтобы изменить цвет графика, достаточно указат ь дополнительный
именованный параметр color:
p l o t ( x , ’ : o ’ , c o l o r = ’ g r e y ’ )
s h o w ( )

136Глава 6. Графики. Модульmatplotlib
Таблица 6.1. Встроенные типы линий ( linestyle) и маркеров
( markers ).
Строка форматирования Описание
’-’ сплошная линия
’–’ прерывистая линия
’-.’ штрих-пунктир
’:’ пунктирная линия
’.’ маркер точка
’,’ маркер пиксель
’o’ маркер кружочек
’v’ маркер треугольник углом вниз
’ˆ’ маркер треугольник углом вверх
’<’ маркер треугольник углом влево
’>’ маркер треугольник углом вправо
’s’ маркер квадрат
’d’ маркер вытянутый ромб
’D’ маркер квадрат, повёрнутый на 45◦
’p’ маркер пятиугольник
’h’ маркер шестиугольник
’*’ маркер звёздочка
’+’ маркер плюс
’x’ маркер крестик, как знак умножения
×
’|’ маркер вертикальный отрезок
’_’ маркер горизонтальный отрезок
В данном случае было использовано специальное именованное значение
’grey’ , соответствующее серому цвету. Существуют значения ’red’,’black’ ,
’blue’ ,’yellow’ ,’green’ ,’magenta’ ,’cyan’ и некоторые другие. Если желае-
мый цвет не встречается среди именованных значений, можно в оспользоваться
кодировкою в стиле RGB  задать значения компонентов красно го, зелёного и
синего в долях от максимально возможного: 1 соответствует м аксимально воз-
можной интенсивности каждого цвета, 0  его нулевой интенси вности. Все три
интенсивности ставятся в кортеж. Вот как получить темно-фи олетовый цвет:
p l o t ( x , ’ : o ’ , c o l o r = ( 0 . 5 , 0 , 0 . 5 ) )
s h o w ( )
Если вы хотите получить оттенок серого, вместо трёх чисел до статочно ука-
зать только одно, поставленное в кавычки:
p l o t ( x , ’ : o ’ , c o l o r = ’ 0 . 5 ’ )
s h o w ( )

6.1. Простые графики137
даст средне-серый цвет.
Рассмотренный выше пример прост, но недостаточно полон: ча сто оказывает-
ся необходимо отложить по оси абсцисс не номера точек, а каки е-то осознанные
значения. Это можно сделать, передав функции plotдва списка. Рассмотрим
этот случай на примере построения синусоиды:
f rom m a t p l o t l i b . p y p l o t i mport p l o t , s h o w
from m a t h i mport p i , s i n
t = [ ]
x = [ ]
f or i in range ( 4 0 0 ) :
t . a p p e n d ( i * 0 . 0 1 )
x . a p p e n d ( s i n ( 2 * p i * t [ i ] ) )
p l o t ( t , x , c o l o r = ’ g r e y ’ )
s h o w ( )
Команда plotвсегда пытается рассматривать первые аргументы как массив ы
со значениями до тех пор, пока не встретит именованный аргум ент или строку.
В приведённом примере (см. цветную вкладку рис. 1(a)) в каче стве аргументов
выступали 2 списка, первый интерпретируется как абсциссы т очек, второй  как
их ординаты. Можно построить несколько кривых на одном поле одною коман-
дою, например, синус и косинус разом (для этого нужно указыва ть абсциссы и
ординаты попеременно):
f rom m a t p l o t l i b . p y p l o t i mport *
from m a t h i mport *
t = [ ]
x = [ ]
y = [ ]
f or i in range ( 4 0 0 ) :
t . a p p e n d ( i * 0 . 0 1 )
x . a p p e n d ( s i n ( 2 * p i * t [ i ] ) )
y . a p p e n d ( c o s ( 2 * p i * t [ i ] ) )
p l o t ( t , x , t , y )
s h o w ( )
На полученных графиках (см. цветную вкладку рис. 1(b)) сину соида полу-
чится синего цвета, а косинусоида  зелёного; это потому, чт о matplotlib само-
стоятельно чередует цвета, если несколько кривых отобража ются на одном гра-
фике. Последние две строчки в программе можно было бы поменя ть следующим
образом без изменения результата:
p l o t ( t , x )
p l o t ( t , y )
s h o w ( )

138Глава 6. Графики. Модульmatplotlib
Кроме просмотра графиков на экране современные графопостр оители обяза-
ны поддерживать вывод изображения в файл. В matplotlibэто делается очень
просто с помощью команды savefig, единственным обязательным аргументом
которой является имя файла. Изменим последнюю строку предыд ущей програм-
мы так, чтобы она не только выводила график на экран, но и сохр аняла его в
файл ’sincos.png’ :
p l o t ( t , x )
p l o t ( t , y ) s a v e f i g ( ’ s i n c o s . p n g ’ )
s h o w ( )
При необходимости, вывод на экран можно убрать, вывод в файл от этого не
пострадает. Важно только помнить, что функция showне только выводит изоб-
ражение на экран, но и высвобождает буфер так, что он остаётс я пуст. Поэтому
перестановка местами функций savefigиshow не скажется на выводе на экран,
но в файл будет записано пустое полотно.
Модуль matplotlib поддерживает несколько популярных форматов, в част-
ности pngдля растровой графики, epsиpdf  для векторной. Можно сохранить
график несколько раз, в том числе в файлы разных форматов:
p l o t ( t , x )
p l o t ( t , y )s a v e f i g ( ’ s i n c o s . p n g ’ )
s a v e f i g ( ’ s i n c o s . p d f ’ )
s h o w ( )
6.2 Заголовок, подписи, сетка, легенда Если график строится просто для себя, и его не планируется вс тавлять, на-
пример, в научную статью или диплом, представленных выше во зможностей
matplotlib может показаться достаточным. Но чтобы показать его другим лю-
дям, да и самому не забыть, что нарисовано и что по какой оси от ложено, полезно
уметь ставить подписи. Простейшие подписи: заголовок и под писи к осям ставят-
ся командами title,xlabel иylabel , принимающими единственный аргумент
 строку:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
t = a r a n g e ( 0 , 4 , 0 . 0 1 )
x = s i n ( 2 * p i * t )
y = c o s ( 2 * p i * t ) p l o t ( t , x , t , y )t i t l e ( ’ V o l t a g e Ђ o v e r Ђ t i m e ’ )
x l a b e l ( ’ t i m e , Ђ s ’ )

6.2. Заголовок, подписи, сетка, легенда139
y l a b e l ( ’ v o l t a g e , Ђ V ’ )
s h o w ( )
Заметим, что на практике всё же удобнее работать не со списка ми, а с массивами,
что мы продемонстрировали здесь, заменив явный цикл операц иями с массивами
из модуля numpy.
Команды plot,title ,xlabel и др. формируют изображение, поэтому они
должны предшествовать командам вывода типа savefigилиshow ; порядок друг
относительно друга  произвольный. Часто необходимо, чтобы в подписях на осях или легенде содер жались верх-
ние или нижние индексы, греческие буквы, различные значки и прочие матема-
тические символы. Для этого matplotlibимеет режим совместимости с коман-
дами L A
T
EX. Чтобы использовать его, нужно поставить перед строкою сим
вол
’r’ , поскольку и в Python, и в L A
T
E Xсимвол
’\’является специальным и вво-
дит команды. Строка, начинающаяся с ’r’, называется сырою. В такой строке
все символы интепретируются как они есть, в том числе ’\t’и’\n’ не будут
означать табуляцию и конец строки, а просто будут парами сим волов. Внутри
сырой строки нужно поставить символ ’$’, с которого начинается и которым
заканчивается формула L A
T
EX. Внутри пары из
’$’можно использовать многие
специальные обозначения: ’_’для нижнего индекса (см. рис. 6.2(b)), ’ˆ’  для
верхнего. Если в индекс входит несколько символов, следует заключить их в фи-
гурные скобки, служащие в L A
T
EXспециальными символами наряду с
’\’; причём
сами фигурные скобки не отображаются. Кроме того, можно испо льзовать почти
все стандартные команды L A
T
EX, например,
’$\dot{x}$’нарисует’x’с точкою
наверху (будет выглядеть
x  так обозначают производную), а ’$\to$’нарисует
красивую стрелку слева направо ( →, см. рис. 6.2(а)):
x l a b e l ( r ’ $ t $ , Ђ с ’ , f o n t s i z e = 1 8 )
y l a b e l ( r ’ $ E _ { c m } $ , Ђ В , $ i _ { c } $ , мкА ’ , f o n t s i z e = 1 8 )
Если на графике несколько кривых, возникает желание как-то подписать
их. Такая подпись, помещённая на график, как правило называ ется легендой.
Чтобы сделать легенду средствами matplotlibнужно, во-первых, указать при
построении каждой кривой требуемую подпись с помощью парам етра с клю-
чевым словом label, во-вторых, вызвать специальную функцию legend, рису-
ющую легенду. Для того, чтобы можно было использовать в подпи сях нела-
тинские буквы, нужно установить шрифт, их поддерживающий. П о умолча-
нию matplotlib использует шрифты без засечек (в типографии такие шриф-
ты принято обозначать по-французски Sans Serif), список которых содер-
жится в переменной rcParams[’font.sans-serif’] , гдеrcParams  словарь, а
’font.sans-serif’  ключ. Если в вашей системе нужные шрифты не уста-
новлены, либо не имеют необходимых символов, вместо букв пол учатся кряко-
зябры или просто квадратики. В таком случае нужно переопре делить перемен-
ную rcParams[’font.sans-serif’] , записав туда список шрифтов, в которых
нужные символы имеются. Например, в Windows можно использов ать шрифт
’Arial’ , как это показано ниже.

140Глава 6. Графики. Модульmatplotlib
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0
time, s 1.0
0.5
0.0
0.5
1.0
voltage, V
Voltage over time
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0
t , 1.0
0.5
0.0
0.5
1.0
E
cm , ,
i
c ,
Voltage over time
(a)
(b)
Рис. 6.2. Графики с подписями и названием.
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
from m a t p l o t l i b i mport r c P a r a m s
r c P a r a m s [ ’ f o n t . s a n s - s e r i f ’ ] = [ ’ A r i a l ’ ]
t = a r a n g e ( - 1 , 1 , 0 . 0 1 )
x = t * * 2
y = t * * 3
z = t * * 4
p l o t ( t , x , l a b e l = r ’ $ x ^ 2 $ ’ )
p l o t ( t , y , ’ - - ’ , l a b e l = r ’ $ x ^ 3 $ ’ )
p l o t ( t , z , ’ : ’ , l a b e l = r ’ $ x ^ 4 $ ’ )l e g e n d ( )
t i t l e ( ’Степенные одночлены ’ )
s h o w ( )
Получившаяся программа строит легенду, но пока качество её нас не устраи-
вает: во-первых, она налезает на графики, во-вторых, подпи си выглядят не очень
красиво  см. рис. 6.3(a). Чтобы исправить первый недостато к, нужно использо-
вать параметр функции legendс названием loc, отвечающий за расположение.
Параметр locможет принимать числовые значения с нуля по 10, либо соответ -
ствующие им строковые значения типа ’upper right’ верхний правый угол,
или ’lower center’  посредине внизу. Значение 0 соответствует строке ’best’
 Python сам пытается выбрать такое положение легенды, чтоб ы она не засло-
няла график (см. рис. 6.3(b)). Ещё один часто встречающийся э лемент графиков
 сетка. Сетка используется для того, чтобы лучше видеть отн осительное распо-
ложение далеко разнесённых значений. Для получения сетки н ужно всего лишь

6.3. Несколько графиков на одном полотне141
1.0 0.5 0.0 0.5 1.0 1.0
0.5
0.0
0.5
1.0 x
2x3x4
1.0 0.5 0.0 0.5 1.0 1.0
0.5
0.0
0.5
1.0
x
2x3x4
(a)
(b)
Рис. 6.3. Пример использования легенды: (a)  расположение по умолчанию,
(b)  оптимальное расположение с дополнительно наложенною сеткою.
добавить (как обычно, до savefigиshow ) в программу функцию grid. В итоге
добавим в нашу программу ещё две строчки:
l e g e n d ( l o c = ’ b e s t ’ )
g r i d ( T r u e )
У функции gridединственный логический аргумент. Если его значение правд а
 сетка будет, если ложь  нет.
6.3 Несколько графиков на одном полотне
Модуль matplotlib позволяет построить несколько графиков на одном по-
лотне. Для этого существует команда subplot, определяющая, в какой части
полотна расположен выводимый в настоящий момент график, и о существляю-
щая его масштабирование (по умолчанию, если subplotни разу не использован,
вывод осуществляется на всё полотно). Команда subplotимеет три обязатель-
ных аргумента  целых числа. Первое означает, на сколько час тей будет разде-
лено полотно по вертикали, второе  по горизонтали (получае тся своеобразная
сетка), третье  номер элемента в этой сетке, нумерация идёт сначала по гори-
зонтали слева направо, потом по вертикали сверху вниз. Чтоб ы лучше понять
работу subplot , создадим программу, рисующую графики различных одночле-
нов на разных графиках.
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
t = a r a n g e ( 0 , 2 , 0 . 0 1 )
x = s q r t ( t )

142Глава 6. Графики. Модульmatplotlib
y = t
z = s q r t ( t * * 3 )
u = t * * 2
v = s q r t ( t * * 5 )
w = t * * 3
s u b p l o t ( 3 , 2 , 1 )
p l o t ( t , x , l a b e l = ’ x * * ( 1 / 2 ) ’ ) t i t l e ( r ’ $ \ s q r t { x } $ ’ )
y l i m ( [ 0 , 5 ] )
s u b p l o t ( 3 , 2 , 2 )
p l o t ( t , y , l a b e l = ’ x ’ , c o l o r = ’ r e d ’ ) t i t l e ( r ’ $ x $ ’ )
y l i m ( [ 0 , 5 ] )
s u b p l o t ( 3 , 2 , 3 )
p l o t ( t , z , l a b e l = ’ x * * ( 3 / 2 ) ’ )
t i t l e ( r ’ $ \ s q r t { x ^ 3 } $ ’ )
y l i m ( [ 0 , 5 ] )
s u b p l o t ( 3 , 2 , 4 )
p l o t ( t , u , ’ : ’ , l a b e l = ’ x * * 2 ’ )
t i t l e ( r ’ $ x ^ 2 $ ’ )
y l i m ( [ 0 , 5 ] )
s u b p l o t ( 3 , 2 , 5 )
p l o t ( t , v , l a b e l = ’ x * * ( 5 / 2 ) ’ ) t i t l e ( r ’ $ \ s q r t { x ^ 5 } $ ’ )
y l i m ( [ 0 , 5 ] )
s u b p l o t ( 3 , 2 , 6 )
p l o t ( t , w , l a b e l = r ’ $ x ^ 3 $ ’ ) t i t l e ( r ’ $ x ^ 3 $ ’ )
l e g e n d ( l o c = 0 )
g r i d ( T r u e ) t i g h t _ l a y o u t ( )
s h o w ( )
Из приведённого примера видно следующее. Во-первых, все ком анды постро-
ения такие, как plot,xlabel ,title и др., включая рисование сетки gridи ле-
генды legend , относятся только к текущему графику. Во-вторых, для каждо го
графика стиль и цвет линий выставляется независимо (см. цве тную вкладку
рис. 2), поэтому, изменив цвет второго и стиль линий четвёрт ого, мы получили

6.3. Несколько графиков на одном полотне143
цвет и стиль линий по умолчания для всех остальных, идущих как до, так и
после. С помощью команды ylim([0, 5])у всех графиков кроме последнего,
задали фиксированные пределы по оси ординат. Функция tight_layout()обес-
печивает расположение графиков на одном полотне без залеза ния друг на друга
автоматически.
Можно сделать так, чтобы графики на полотне занимали разный размер,
например, сверху два, снизу  один. Дело в том, что функция subplotпро-
сто определяет положение графика на полотне, она не задаёт н икакой реальной
сетки. Поэтому могут одновременно встречаться графики, дл я которых сетка
задана по-разному.
Приведём пример из радиофизики. На выходах микрофона, пере дающей те-
лекамеры и различных датчиков создаются низкочастотные сиг налы с малой
амплитудой. Таким сигналам свойственно большое затухание в пространстве и,
следовательно, они не могут передавать информацию по канал ам связи. Для
эффективной передачи сигналов в произвольной среде необхо димо перенести
спектр данных сигналов из низкочастотной области в область высоких частот.
Такой процесс называется модуляцией.
Модуляция  процесс изменения одного или нескольких параме тров высо-
кочастотного несущего колебания по закону низкочастотног о информационного
сигнала (сообщения). Будем использовать амплитудную моду ляцию  вид мо-
дуляции, при которой изменяемым параметром несущего сигна ла является его
амплитуда. Передаваемая информация заложена в управляющем (модулирую-
щем) сигнале (в данном примере x= cos(2 t)), а роль переносчика информа-
ции выполняет высокочастотное колебание ( y= cos(20 ·2t )), называемое несу-
щим. Модуляция, таким образом, представляет собой процесс посадки инфор-
мационного колебания на заведомо известную несущую. Формул а амплитудно-
модулированного колебания выглядит следующим образом: z= (1 + M·x ) ·y,
где M глубина модуляции.
Вот пример генерации и отображения такого модулированного сигнала на
компьютере:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
r c P a r a m s [ ’ f o n t . s a n s - s e r i f ’ ] = [ ’ A r i a l ’ ]
t = a r a n g e ( 0 , 1 0 , 0 . 0 0 1 )
x = c o s ( 2 * p i * t )
y = c o s ( 2 0 * 2 * p i * t )
z = ( 1 + 0 . 7 * x ) * y s u b p l o t ( 2 , 2 , 1 )
p l o t ( t [ : 2 0 0 0 ] , x [ : 2 0 0 0 ] , c o l o r = ’ b l a c k ’ )
t i t l e ( ’Модулирующий сигнал ’ )x l a b e l ( ’ T i m e , Ђ s ’ )
y l a b e l ( ’ V o l t a g e , Ђ V ’ )
s u b p l o t ( 2 , 2 , 2 )

144Глава 6. Графики. Модульmatplotlib
p l o t ( t [ : 2 0 0 0 ] , y [ : 2 0 0 0 ] , c o l o r = ’ b l a c k ’ )
t i t l e ( ’Несущий сигнал ’ )x l a b e l ( ’ T i m e , Ђ s ’ )
y l a b e l ( ’ V o l t a g e , Ђ V ’ )s u b p l o t ( 2 , 1 , 2 )
p l o t ( t , z , c o l o r = ’ b l a c k ’ )
t i t l e ( ’ A M - сигнал ’ )x l a b e l ( ’ T i m e , Ђ s ’ )
y l a b e l ( ’ V o l t a g e , Ђ V ’ ) t i g h t _ l a y o u t ( )
s h o w ( )
Здесь видно (см. рис. 6.4), что мы как бы обманываем matplotlib: для
графиков yи zмы говорим, что будем размещать графики по схеме 2× 2, а для
графика x по схеме 2× 1. В результате третий график занимает всю нижнюю
половину, как будто он второй из двух, а первые  каждый по чет верти в верхней
половине, как первый и второй из четырёх.
Часто бывает так, что требуется построить не несколько граф иков в одном
окне, а несколько окон с графиками; такая возможность в matplotlibпредусмот-
рена. Например, вам нужно построить несколько разных рисун ков и сохранить
каждый в отдельный файл. Для этого нужно воспользоваться фу нкциейfigure.
Вызов figure подобен вызову subplotв том смысле, что рисование начинается
заново, а все ранее нарисованные объекты: сами графики, под писи к ним, сет-
ка, легенда и проч. остаются на предыдущем полотне (или полот нах). Разница
в том, что subplotразмещает новый график в пределах всё того же полотна, а
figure просто создаёт новое. Вот что будет, если переписать предыд ущий пример
с помощью figure:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
t = a r a n g e ( 0 , 1 , 0 . 0 0 1 )
x = s i n ( 1 0 * p i * t )
y = t
z = s q r t ( t * * 3 ) f i g u r e ( 1 )
p l o t ( t , y )
f i g u r e ( 2 )
p l o t ( t , z )
f i g u r e ( 3 )
p l o t ( t , x )
s h o w ( )
В использованном примере у функции figureтолько один аргумент  номер
создаваемого полотна. Номер этот полезен тем, что в любой мом ент вы можете
вернуться к уже начатому графику и что-то там дорисовать; дл я этого просто

6.3. Несколько графиков на одном полотне145
0.0 0.5 1.0 1.5 2.0
Time, s 1.0
0.5
0.0
0.5
1.0
Voltage, V

0.0 0.5 1.0 1.5 2.0
Time, s 1.0
0.5
0.0
0.5
1.0
Voltage, V

0 2 4 6 8 10
Time, s 2.0
1.5
1.0
0.5
0.0
0.5
1.0
1.5
2.0
Voltage, V
-
Рис. 6.4. Пример нескольких графиков различного размера на одном полотне.
необходимо сменить фигуру на ту, где вы уже рисовали. Так ж е полотну можно
задать нужные размеры. Это делается с помощью именного аргу ментаfigsize
функции figure. Этот аргумент задаётся в виде кортежа из двух чисел  ширина
и высота полотна. Вот пример:
i mport n u m p y a s n p
import m a t p l o t l i b . p y p l o t a s p l t
t = n p . a r a n g e ( - 1 . 0 , 1 . 0 , 0 . 0 0 1 )
x = n p . s i n ( 2 * n p . p i * t )
y = n p . c o s ( 5 * n p . p i * t )
p l t . f i g u r e ( 1 , f i g s i z e = ( 8 , 3 ) )
p l t . p l o t ( t , x )
p l t . f i g u r e ( 2 )
p l t . p l o t ( t , y )
p l t . y l a b e l ( ’ c o s ( t ) ’ )
p l t . f i g u r e ( 1 )
p l t . y l a b e l ( ’ s i n ( t ) ’ )

146Глава 6. Графики. Модульmatplotlib
Рис. 6.5. Пример вызова нескольких полотен ( figure).
p l t . g r i d ( T r u e )
p l t . s h o w ( )
Здесь мы сначала нарисовали первую синусоиду в первом окне, потом вторую
во втором, а затем вернулись к первому окну и доделали подпис и к осям и сетку
(рис. 6.5).
Создание каждого нового полотна потребляет оперативную па мять. Поэтому,
если нет необходимости наблюдать несколько полотен одновр еменно, эффектив-
нее один раз создавать полотно функцией figure, а потом на каждом шаге,
например, цикла перерисовывать на нём новый рисунок, предв арительно стирая
предыдущий функцией clf().
6.4 Гистограммы, диаграммы-столбцы Кроме обычных графиков, отражающих зависимость одной велич ины от дру-
гой, бывает нужно построить графики другого типа, чаще всег о это гистограм-
мы. Гистограммы строят, чтобы следить за распределением не которой величины.
Если величина дискретна  каждому значению сопоставляют его частоту (число
выпадений в данной реализации) или вероятность в процентах или долях едини-
цы. Если величина изменяется непрерывно, её значения делят на диапазоны 
бины, подсчитывая число попаданий в каждый диапазон. Для примера построим гистограммы равномерно на отрезке [0; 6]и нормально
с параметрами µ= 0 , = 3 распределённых случайных величин, сгенерировав по
10000 значений в каждом случае. Воспользуемся стандартным модулемrandom.

6.4. Гистограммы, диаграммы-столбцы147
0 1 2 3 4 5 6 0
200
400
600
800
1000
1200
15 10 50 510 15 0
500
1000
1500
2000
2500
3000
0 1 2 3 4 5 6 0.00
0.05
0.10
0.15
0.20
0.25
15 10 50 510 15 0.00
0.02
0.04
0.06
0.08
0.10
0.12
0.14
(a)(b)
Рис. 6.6. Пример построения гистограмм: (a)  использованы значения парамет-
ров по умолчанию, в результате на обоих графиках наблюдаем по 10 бинов, а
по вертикали отложено число попаданий в каждый из них; (b)  ч исло бинов
выставлено вручную и равно 100, по вертикали отложены значе ния плотности
вероятности.
f rom r a n d o m i mport u n i f o r m , n o r m a l v a r i a t e
from m a t p l o t l i b . p y p l o t i mport *
v = [ ]
f or i in range ( 1 0 0 0 0 ) :
v . a p p e n d ( u n i f o r m ( 0 , 6 ) )
s u b p l o t ( 1 , 2 , 1 )
h i s t ( v )
w = [ ]
f or i in range ( 1 0 0 0 0 ) :
w . a p p e n d ( n o r m a l v a r i a t e ( 0 , 3 ) )
s u b p l o t ( 1 , 2 , 2 )
h i s t ( w )
s h o w ( )
Представленная программа делит весь диапазон от минимальн ого до макси-
мального значения на 10 бинов и рисует частоты  число попада ний в каждый
бин (см. рис. 6.6(a)). Для 10000 значений 10 бинов  маловато , поэтому исполь-
зуем необязательный параметр bins, принимающий целое число, равное желае-
мому количеству бинов. А вместо частот нужно получить плотн ость вероятности
(т. е. площадь под графиком должна равняться единице), для ч его используем
ещё один необязательный параметр normed, принимающий логическое значение.
Изменим программу, указав дополнительные параметры:
f rom r a n d o m i mport u n i f o r m , n o r m a l v a r i a t e

148Глава 6. Графики. Модульmatplotlib
f rom m a t p l o t l i b . p y p l o t i mport *
v = [ ]
f or i in range ( 1 0 0 0 0 ) :
v . a p p e n d ( u n i f o r m ( 0 , 6 ) )
s u b p l o t ( 1 , 2 , 1 )
h i s t ( v , b i n s = 1 0 0 , n o r m e d = T r u e )
w = [ ]
f or i in range ( 1 0 0 0 0 ) :
w . a p p e n d ( n o r m a l v a r i a t e ( 0 , 3 ) )
s u b p l o t ( 1 , 2 , 2 )
h i s t ( w , b i n s = 1 0 0 , n o r m e d = T r u e )
s h o w ( )
Теперь видим (см. рис. 6.6(b)), что по вертикали отложено уж е знание плотно-
сти вероятности, причём график стал более изрезанным, поск ольку увеличилось
число бинов, а число значеинй в каждом бине уменьшилось.
Иногда полезными бывают диаграммы-столбцы. На таких диагра ммах гори-
зонтальный или вертикальный прямоугольник показывает сво ей длиной вклад,
вносимый каждым участником. Главная его задача состоит в ср авнении этих
количественных показателей. Для визуализации используется функция bar(), принимающая две последо-
вательности координат: x, определяющих левый край столбца, и y, определяю-
щих высоту. Ширина прямоугольников по умолчанию равна 0.8 . Но этот и другие
параметры можно менять за счёт необязательных именованных параметров:
f rom n u m p y i mport *
from r a n d o m i mport *
from m a t p l o t l i b . p y p l o t i mport *
d a t a 1 = [ ]
d a t a 2 = [ ]
d a t a 3 = [ ]
f or i in range ( 1 0 ) :
d a t a 1 . a p p e n d ( n o r m a l v a r i a t e ( 5 , 0 . 5 ) )
d a t a 2 . a p p e n d ( n o r m a l v a r i a t e ( 5 , 0 . 5 ) )
d a t a 3 . a p p e n d ( n o r m a l v a r i a t e ( 5 , 0 . 5 ) )
l o c s = a r a n g e ( 1 ,
l en ( d a t a 1 ) + 1 )
w i d t h = 0 . 2
b a r ( l o c s , d a t a 1 , w i d t h = w i d t h , c o l o r = ’ b l u e ’ )
b a r ( l o c s + w i d t h , d a t a 2 , w i d t h = w i d t h , c o l o r = ’ r e d ’ )
b a r ( l o c s + 2 * w i d t h , d a t a 3 , w i d t h = w i d t h , c o l o r = ’ g r e e n ’ ) x t i c k s ( l o c s + w i d t h * 1 . 5 , l o c s )
s h o w ( )
В данном примере widthзадает ширину прямоугольника, colorзадает цвет
прямоугольника. Опционно можно дописать xerr,yerr , которые позволяют уста-
навливать error bars . Далее генерируем последовательности трёх видов данных

6.5. Круговые и контурные диаграммы149
(data ) для пяти точек. Задаем переменную, которая будет определят ь толщину
столбцов. Первый аргумент bar()имеет такой вид для того, чтобы три столбца
стояли вместе, впритык друг к другу. Также здесь применяетс я фокус с функци-
ей xticks , позволяющей изменять засечки на оси абсцисс, и мы смещаемся так,
чтобы аргумент, породивший три своих столбца, стоял посере дине  рис. 3(a).
Часто используют и горизонтальное расположение. Оно описыв ается практиче-
ски также, но вместо функции bar()используется barh(). Более того, такого
рода диаграмм и возможностей существует великое множество , и вы сами може-
те ознакомиться с ними по документации matplotlib.
6.5 Круговые и контурные диаграммы Достаточно распространённым способом графического изобр ажения структу-
ры статистических совокупностей является секторная диагр амма, так как идея
целого очень наглядно выражается кругом, который представ ляет всю совокуп-
ность. Относительная величина каждого значения изображае тся в виде сектора
круга, площадь которого соответствует вкладу этого значен ия в сумму значений.
Этот вид графиков удобно использовать, когда нужно показат ь долю каждой ве-
личины в общем объёме. Секторы могут изображаться как в обще м круге, так и
отдельно, расположенными на небольшом удалении друг от дру га.
Круговая диаграмма сохраняет наглядность только в том случ ае, если ко-
личество частей совокупности диаграммы небольшое. Если ча стей диаграммы
слишком много, её применение неэффективно по причине несущ ественного раз-
личия или малого размера сравниваемых структур. Недостато к круговых диа-
грамм  малая информационная ёмкость, невозможность отраз ить более широ-
кий объём полезной информации.
Нарисуем круговую диаграмму средствами matplotlib’a  рис. 3(b):
f rom m a t p l o t l i b . p y p l o t i mport *
d a t a = [ 1 8 , 1 5 , 1 1 , 9 , 8 , 6 ] l a b e l s = [ ’ J a v a ’ , ’ C ’ , ’ C + + ’ , ’ P H P ’ , ’ P y t h o n ’ , ’ R u b y ’ ]
e x p l o d e = [ 0 , 0 , 0 , 0 , 0 . 2 , 0 ]
a x e s ( a s p e c t = 1 )
p i e ( d a t a , l a b e l s = l a b e l s , e x p l o d e = e x p l o d e , a u t o p c t = ’ % 1 . 1 f % % ’ , s h a d o w = T r u e )
s h o w ( )
Данная программа задаёт набор данных ( data), добавляет на рисунок оси
с соотношением сторон 1:1 ( axes), строит график в виде круговой диаграммы
( pie ). Первым аргументом функция pieпринимает последовательность дан-
ных, затем codeзадаёт имена, по одному на каждый элемент data, далее за-
даётся explode  маска, по которой вырезается кусок пирога, autopctзадаёт
тип форматирования численных значений, shadowдобавляет тень. Как обычно,
цвет чередуется сам собою, порядок по умолчанию для matplotlibэто’blue’ ,
’green’ ,’red’ ,’cyan’ ,’magenta’ ,’yellow’ ,’black’ .

150Глава 6. Графики. Модульmatplotlib
Ещё одним специализированным видом графиков являются контурные диа-
граммы . Проще всего понять, что это такое, если вспомнить физическ ую кар-
ту миры: там высоты и глубины обозначены цветом от тёмно-кор ичневого до
тёмно-синего, а значения разделены на диапазоны, внутри ко торых все значения
красятся единым цветом. Контурная диаграмма  способ предс тавления трёх-
мерной поверхности как бы сверху.
Чтобы построить контурную диаграмму с помощью matplotlib, нужно за-
дать три двумерных массива одинаковой формы: массив значен ий координаты
x для каждого узла сетки, массив координаты yи массив значений функции от
них z= f(x, y ). Если функция fнам известна, нужно определить пределы изме-
нения xиyи задать шаг их изменения по каждой из осей, т. е. сетку. Это мо жно
сделать с помощью функции arange. Далее из одномерных массивов, задающих
сетку, нужно получить двумерные, содержащие координаты xиyв каждом узле
сетки; это можно сделать командою meshgrid, как показано в примере далее.
Сама контурная диаграмма строится с помощью команды contour, которой в
качестве параметров передаются все три массива: x, y и z:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
from m a t p l o t l i b . m l a b i mport *
x = a r a n g e ( - 3 , 3 , 0 . 0 1 )
y = a r a n g e ( - 2 , 2 , 0 . 0 1 )
X , Y = m e s h g r i d ( x , y )
Z = X * * 2 - 4 * Y * * 2 + Y * * 4 c o n t o u r ( X , Y , Z )
s h o w ( )
Представленная программа строит контурную диаграмму функ ции (см. цвет-
ную вкладку рис. 4(a)) с помощью линий уровней. Можно всё зал ить цветом,
как на физической карте мира. Для этого необходимо использо вать функцию
contourf (см. цветную вкладку рис. 4(b)).
Конечно, на практике значения массивов x, y и zбудут, скорее всего, извест-
ны и прибегать к таким ухищрениям не придётся. Тем не менее, п редложенный
пример  хорошая иллюстрация того, как построить график функ ции двух пе-
ременных, не прибегая к изометрической проекции.
6.6 Трёхмерные графики
Вmatplotlib кроме двумерных существует возможность построения трёх-
мерных графиков. Для это используется модуль mplot3d. Для того, чтобы
нарисовать трехмерный график, в первую очередь надо создат ь трехмерные
оси. Они задаются как объект класса mpl_toolkits.mplot3d.Axes3D, кон-
структор которого ожидает как минимум один параметр  экзем пляр класса
matplotlib.figure.Figure . У конструктора классаAxes3Dесть ещё и другие

6.6. Трёхмерные графики151
Рис. 6.7. 3D-оси.
необязательные параметры, но пока мы их использовать не буд ем. Давайте на-
рисуем пустые оси (рис. 6.7):
f rom m a t p l o t l i b . p y p l o t i mport *
from m p l _ t o o l k i t s . m p l o t 3 d i mport A x e s 3 D
f i g = f i g u r e ( ) A x e s 3 D ( f i g )
s h o w ( )
Полученные оси вы можете вращать мышкой в интерактивном реж име.
А теперь нарисуем что-нибудь трёхмерное в полученных осях. Можно рисо-
вать один каркас ( wireframe, см. цветную вкладку рис. 5(a)), а можно  поверх-
ность ( surface , см. цветную вкладку рис. 5(b)):
f rom m a t p l o t l i b . p y p l o t i mport *
import n u m p y a s n p
from m p l _ t o o l k i t s . m p l o t 3 d i mport A x e s 3 D
f i g = f i g u r e ( )
a x = A x e s 3 D ( f i g )
u = n p . l i n s p a c e ( 0 , 2 * n p . p i , 1 0 0 )
v = n p . l i n s p a c e ( 0 , n p . p i , 1 0 0 )
x = 1 0 * n p . o u t e r ( n p . c o s ( u ) , n p . s i n ( v ) )
y = 1 0 * n p . o u t e r ( n p . s i n ( u ) , n p . s i n ( v ) )
z = 1 0 * n p . o u t e r ( n p . o n e s ( n p . s i z e ( u ) ) , n p . c o s ( v ) ) a x . p l o t _ s u r f a c e ( x , y , z , c o l o r = ’ g r e y ’ ) s a v e f i g ( ’ 3 D . p n g ’ )
s h o w ( )

152Глава 6. Графики. Модульmatplotlib
Функцияlinspace как и функция arangeсоздаёт массив значений, каждое
следующее из которых больше предыдущего на одну и ту же величи ну. Напом-
ним, что arange(start, stop, step) принимает три основных аргумента: нача-
ло, конец, шаг; linspace(start, stop, num, endpoint=True) также принима-
ет три обязательных аргумента: начало, конец и число значен ий, расположен-
ных между ними, а кроме того у неё есть ещё необязательный чет вёртый аргу-
мент endpoint , который принимает логические значения. Если endpoint=True
(это значение по умолчанию), то конечное значение stopбудет включено в ге-
нерируемый диапазон и расстояние между соседними значения ми будет равно
(stop-start)/(num-1) , иначе оно не будет включено и расстояние между ними
будет равно (stop-start)/num .
6.7 Учёт ошибок В реальности эксперимент даже при максимальной точности из мерений все-
гда вносит свою погрешность. Например, при снятии вольт-ам перной характе-
ристики (ВАХ) диода в трёх экспериментах получаются немного ра зные значе-
ния тока. С помощью errorbarможно построить среднее значение и отложить
разброс (рис. 6.8). Для того, чтобы учесть это и указать возм ожный разброс во-
круг значения, считаемого истинным, вводят планки погрешн остей ( функция
errorbar ), которые на кривой для полученных точек показывают своеобр азный
доверительный интервал:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
r c P a r a m s [ ’ f o n t . s a n s - s e r i f ’ ] = [ ’ A r i a l ’ ]
x = a r a n g e ( 0 , 2 . 2 , 0 . 2 )
y 1 = [ 0 , 1 0 , 2 4 , 3 9 , 5 5 , 7 3 , 8 7 , 1 3 0 , 1 4 0 , 1 5 0 , 2 0 0 ]
y 2 = [ 0 , 1 1 , 2 5 , 4 1 , 5 8 , 6 6 , 9 4 , 1 3 5 , 1 4 0 , 1 6 0 , 1 7 0 ]
y 3 = [ 0 , 1 0 , 2 4 , 4 0 , 5 7 , 7 0 , 9 0 , 1 3 0 , 1 4 5 , 1 6 0 , 1 8 0 ]
y = c o l u m n _ s t a c k ( [ y 1 , y 2 , y 3 ] ) e r r o r b a r ( x , m e a n ( y , a x i s = 1 ) , y e r r = [ s t d ( y , a x i s = 1 ) , s t d ( y , a x i s = 1 ) ] , m a r k e r = ’ . ’ , c o l o r = ’ b l a c k ’ )
t i t l e ( ’Вольт-амперная характеристика ’ ) x l a b e l ( ’Напряжение, В ’ ) ;
y l a b e l ( ’Ток, мкА ’ )
s h o w ( )
В примере с помощью функции arange()был создан диапазон изменения
напряжения от 0 В до 2 В с шагом 0.2 В. Далее результаты трёх сер ий изме-
рений были представлены в виде трёх списков: y1,y2 ,y3 . С помощью функции
column_stack из нескольких одномерных массивов или списков одинаковой д ли-
ны можно сделать двумерный массив. Далее вызывается функци яerrorbar . В
качестве первого аргумента передаём диапазон изменения на пряжения. В каче-

6.8. Примеры построения графиков153
0.0 0.5 1.0 1.5 2.0
, 0
50
100
150
200
,
-
Рис. 6.8. ВАХ диода, усреднённая по трём экспериментам с отло женными план-
ками погрешностей.
стве второго  среднее ( mean) по трём измерениям значение тока. В качестве
третьего ( yerr)  разброс значений тока ( std).
Рассмотренные в данном примере планки погрешностей симмет ричны относи-
тельно среднего значения, но существует возможность рисов ать и несимметрич-
ные отклонения. Их можно задать в той же функции с помощью спи ска из двух
разных последовательностей: первой для отрицательных отк лонений, второй 
для положительных.
6.8 Примеры построения графиков
Пример задачи 17 (Затухающая синусоида, вариант 1) Постройте гра-
фик затухающей синусоиды e−
x
sin(2 x)на отрезке [0; 10], используя шаг
по абсциссе, равный 0.1.
Решение задачи 17
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
x = a r a n g e ( 0 , 1 0 , 0 . 1 )
f = e x p ( - x ) * s i n ( 2 * p i * x )
p l o t ( x , f )
s h o w ( )

154Глава 6. Графики. Модульmatplotlib
0 2 4 6 8 10 0.6
0.4
0.2
0.0
0.2
0.4
0.6
0.8
0 2 4 6 8 10 0.6
0.4
0.2
0.0
0.2
0.4
0.6
0.8
(a) (b)
Рис. 6.9. Иллюстрация к задачам 17  (a) и 18  (b).
Пример задачи 18 (Затухающая синусоида, вариант 2) Для построен-
ного в предыдущем задании графика измените: цвет линии, тип линии и
маркеров, шаг выборки данных, введите сетку и сохраните пол ученный
график в файл.
Решение задачи 18
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
x = a r a n g e ( 0 , 1 0 , 0 . 0 1 )
f = e x p ( - x ) * s i n ( 2 * p i * x )
p l o t ( x , f , ’ - o ’ , c o l o r = ’ b l a c k ’ )
g r i d ( T r u e )s a v e f i g ( ’ p l o t . p n g ’ )
s h o w ( )
Пример задачи 19 (Семейство затухающих синусоид) Постройте се-
мейство функций e−
x
sin(2 x+
0)
на одном графике различными цветами
при
0 = 0
,
0 =
/ 6и
0 =
/ 3. Сделайте для графика легенду.
Решение задачи 19
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
x = a r a n g e ( 0 , 1 0 , 0 . 0 1 )

6.8. Примеры построения графиков155
f 1 = e x p ( - x ) * s i n ( 2 * p i * x )
f 2 = e x p ( - x ) * s i n ( 2 * p i * x + p i / 6 )
f 3 = e x p ( - x ) * s i n ( 2 * p i * x + p i / 3 )
p l o t ( x , f 1 , l a b e l = r ’ $ \ s i n ( 2 \ p i Ђ x ) $ ’ )
p l o t ( x , f 2 , l a b e l = r ’ $ \ s i n ( 2 \ p i Ђ x Ђ + Ђ \ p i Ђ / 6 ) $ ’ )
p l o t ( x , f 3 , l a b e l = r ’ $ \ s i n ( 2 \ p i Ђ x Ђ + Ђ \ p i Ђ / 3 ) $ ’ )l e g e n d ( l o c = ’ b e s t ’ )
g r i d ( T r u e )
s h o w ( )
Пример задачи 20 (Семейство графиков с затухающими синусоидами)
Перестройте графики так, чтобы каждая кривая располагалас ь на одном
графике с помощью команды subplot, легенду уберите, а её текст пере-
местите в название соответствующего графика. Графики распо ложите
на полотне в один столбец.
Решение задачи 20
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
x = a r a n g e ( 0 , 1 0 , 0 . 0 1 ) f 1 = e x p ( - x ) * s i n ( 2 * p i * x )
f 2 = e x p ( - x ) * s i n ( 2 * p i * x + p i / 6 )
f 3 = e x p ( - x ) * s i n ( 2 * p i * x + p i / 3 )
s u b p l o t ( 3 , 1 , 1 )
p l o t ( x , f 1 ) t i t l e ( r ’ $ \ s i n ( 2 \ p i Ђ x ) $ ’ )
g r i d ( T r u e )
s u b p l o t ( 3 , 1 , 2 )
p l o t ( x , f 2 ) t i t l e ( r ’ $ \ s i n ( 2 \ p i Ђ x Ђ + Ђ \ p i Ђ / 6 ) $ ’ )
g r i d ( T r u e ) s u b p l o t ( 3 , 1 , 3 )
p l o t ( x , f 3 ) t i t l e ( r ’ $ \ s i n ( 2 \ p i Ђ x Ђ + Ђ \ p i Ђ / 3 ) $ ’ )
g r i d ( T r u e )
t i g h t _ l a y o u t ( )
s h o w ( )
Пример задачи 21 Постройте закрашенную контурную диаграмму и
трёхмерный график для функции двух переменных (6.1), опред елённой
в прямоугольной области ( x∈ [− 3; 3] ,y ∈ [− 3; 3] ):

156Глава 6. Графики. Модульmatplotlib
0 2 4 6 8 10 0.6
0.4
0.2
0.0
0.2
0.4
0.6
0.8
1.0 sin(2πx)sin(2 πx+π/ 6)sin(2 πx+π/ 3) 0 2 4 6 8 10 0.60.40.20.00.20.40.60.8 sin(2
πx)
0 2 4 6 8 10 0.60.40.20.00.20.40.60.81.0 sin(2
πx+π/ 6)
0 2 4 6 8 10 0.60.40.20.00.20.40.60.81.0 sin(2
πx+π/ 3)
(a) (b)
Рис. 6.10. Иллюстрация к задачам 19  (a) и 20  (b).
z= 2
xy
x 2
+ y2 (6.1)
Решение задачи 21
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
from m a t p l o t l i b . m l a b i mport *
from m p l _ t o o l k i t s . m p l o t 3 d i mport A x e s 3 D
x = a r a n g e ( - 3 , 3 , 0 . 0 1 )
y = a r a n g e ( - 3 , 3 , 0 . 0 1 )
X , Y = m e s h g r i d ( x , y ) Z = 2 * X * Y / ( X * * 2 + Y * * 2 )
c o n t o u r f ( X , Y , Z )
s a v e f i g ( ’ p l o t . p n g ’ )
f i g = f i g u r e ( )
a x = A x e s 3 D ( f i g )
a x . p l o t _ s u r f a c e ( X , Y , Z ) s a v e f i g ( ’ 3 D . p n g ’ )
s h o w ( )
6.9 Задания на построение графиков Для каждого из заданий данного раздела следует выполнить 1 в ариант с
номером (n − 1)% m+ 1 , где n номер в списке группы, а m число заданий.
Задание 18 Постройте графики следующих функций, используя шаг вы-
борки данных по абсциссе из задания 17:

6.9. Задания на построение графиков157
1.x2
на отрезке x∈ [− 2; 2] ;
2. x3
на отрезке x∈ [− 2; 2] ;
3. x4
на отрезке x∈ [− 2; 2] ;
4. cos(2 t)на отрезке t∈ [− 10; 10] ;
5. 1
t
cos(2
t)на отрезке t∈ [1; 10] ;
6. e−
t
cos(2 t)на отрезке t∈ [− 10; 10] ;
7. 4 sin( t+/ 8) −1на отрезке t∈ [− 10; 10] ;
8. 2 cos( t− 2) + sin(2 ∗t− 4) на отрезке t∈ [− 20 ; 10 ];
9. ln(x+ 1) на отрезке x∈ [0; e− 1];
10. log
2(
|x |) на отрезке x∈ [− 4; 4] за исключением точки x= 0 ;
11. 2x
на отрезке x∈ [− 2; 2] ;
12. ex
на отрезке x∈ [− 2; 2] ;
13. 2−
x
на отрезке x∈ [− 2; 2] ;
14. 3

x
на отрезке x∈ [1; 125] ;
15. 5

x
на отрезке x∈ [1; 32] .
Задание 19 Для построенного в рамках задания 18 графика измените:
• цвет линии;
• тип линии и маркеров;
• шаг выборки данных.
Далее введите сетку. Сохраните полученный график в файл, оп робуйте
сохранять файл в разных форматах: png,pdf ,jpg ,eps .
Задание 20 Постройте семейство функций на одном графике различны-
ми цветами:
1. степенные многочлены с целыми степенями от 1 до 6 на отрезк е[− 1; 1] ;
2. синусоиды y= sin( t)с частотами = 2 , = 3 , . . . , = 8 на отрезке
t ∈ [− 1; 1] ;
3. синусоиды y= sin(2 t+
0)
с начальными фазами
0 = 0
,
0 =
/6, . . . ,
0 = 5
/6на отрезке t∈ [− 1; 1] ;

158Глава 6. Графики. Модульmatplotlib
4. логарифмические функции log
2(
x ), ln( x) и log
10(
x ) на отрезке x∈ [1; 10] ;
5. гиперболические функции sh(x), ch( x) и th( x) на отрезке x∈ [− 10; 10] , для
их вычисления воспользуйтесь их выражением через экспонен ту.
Задание 21 Для построенного в задании 20 графика сделайте сетку и ле-
генду. Перестройте графики так, чтобы каждая кривая распол агалась на
одном графике с помощью команды subplot, легенду уберите, а её текст
переместите в название соответствующего графика. Графики р асполо-
жите на полотне:
•в одни столбец;
• в два столбца;
• в 3 столбца;
• в одну строку.
Перестройте графики из задания каждый в своём окне. Сделайт е так,
чтобы эти графики автоматически сохранялись каждый в свой ф айл.
Задание 22 Постройте круговую диаграмму, которая показывала бы до-
ли от общего числа студентов вашей группы, сдавших сессию на :
1. одни пятёрки,
2. пятёрки и четвёрки,
3. с тройками, но без задолжностей,
4. с задолжностями, сумевших в итоге пересдать,
5. несдавших и отчисленных (если такие имеются).
Задание 23 Постройте закрашенную контурную диаграмму и трёхмер-
ный график для следующих функций двух переменных, определён ных в
прямоугольной области x∈ [− 3; 3] ,y ∈ [− 3; 3] :
1. z= x2
+ y2
,
2. z= x2
− y2
,
3. z= x3
+ y3
,
4. z= x3
− y3
,
5. z= x2
− y2
+ x,
6. z= x2
− y2
+ y,

6.9. Задания на построение графиков159
7.z= x2
+ y2
+ x,
8. z= x2
+ y2
+ y,
9. z= sin( xy),
10. z= cos( xy),
11. z= tg( xy),
12. z= xy ,
13. z= x− sin( xy),
14. z= x+ cos( xy),
15. z= p
x
2
+ y2
.
Построенные графики сохраните в файлы с расширением png.

Глава 7
Библиотеки, встроенные вnumpy
Исторически numpyимеет в своём составе 3 библиотеки численных мето-
дов: linalg для задач линейной алгебры, fftдля выполнения быстрого Фурье-
преобразования и randomдля генерации случайных чисел. Хотя основным мо-
дулем для научных и инженерных вычислений стал scipy, построенный на базе
numpy , поддержка этих трёх библиотек сохраняется из соображений обратной
совместимости со старыми программами. Освоение возможнос тей этих библио-
тек позволяет писать много полезных прикладных программ.
7.1 Элементы линейной алгебры
Библиотека linalgдаёт возможность вычислять определители матриц, ре-
шать системы линейных уравнений и задачу наименьших квадра тов, произво-
дить QR и SVD разложения. Вот пример простой программы, решающ ей систему
линейных уравнений с помощью функции solveи вычисляющей определитель
матрицы с помощью функции detизlinalg :
f rom n u m p y i mport *
A = a r r a y ( [ [ 2 , 3 ] , [ - 1 , 5 ] ] )
b = a r r a y ( [ - 7 , - 1 6 ] )
x = l i n a l g . s o l v e ( A , b )
p rint ( x )
D = l i n a l g . d e t ( A )
p rint ( D )
Результаты её работы легко проверить вручную и получить иск омые решения:
[ 1. -3.]
13.0
Синтаксис функций solveиdet простой и очевидный для тех, кто привычен
к записи систем уравнений в матричной форме вида ˆ
A x = b. Функция solveтре-
бует 2 параметра: матрицу коэффициентов ˆ
A и вектор свободных членов (правая

7.1. Элементы линейной алгебры161
часть системы уравнений)b. Результат выполнения функции  вектор искомых
значений x. Функция detтребует один параметр  матрицу, определитель кото-
рой следует отыскать.
Кроме определителя для матриц можно вычислить собственные значения и
собственные векторы матрицы ( linalg.eig(a)), а также норму вектора или опе-
ратора ( linalg.norm(x[, ord, axis]) ). Уже реализованы все основные методы
разложения матриц:
•inalg.cholesky(a)  разложение Холецкого; linalg.qr(a[, mode]) QR
разложение; linalg.svd(a[, full_matrices, compute_uv])  сингуляр-
ное разложение; linalg.lstsq(a, b)  метод наименьших квадратов.
Используя возможности встроенной в модуль numpyбиблиотеки linalg, по-
пробуем решить популярную задачу аппроксимации сток-затв орной характери-
стики полевого транзистора полиномиальной (параболой) и к усочно-линейной
функцией. В данном случае, под аппроксимацией будем понима ть замену изме-
ренных пар значений (напряжение, ток)некоторою функцией ток(напряжение).
Предположим, что у нас есть результаты измерения тока стока i
c (список
y)
при изменении напряжения на затворе U
ЗИ (массив
x). Данная вольт-амперная
характеристика (ВАХ) показана на рис. 7.1. Программа для её от ображения бу-
дет иметь следующий вид:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
from m a t p l o t l i b i mport r c P a r a m s
r c P a r a m s [ ’ f o n t . s a n s - s e r i f ’ ] = ’ L i b e r a t i o n Ђ S a n s ’
x = a r a n g e ( 0 , - 4 . 5 , - 0 . 5 )
y = [ 5 0 , 3 5 , 2 2 , 1 1 , 4 , 0 , 0 , 0 , 0 ] p l o t ( x , y , ’ o ’ , c o l o r = ’ g r e y ’ )t i t l e ( ’Сток-затворная характеристика ’ )x l a b e l ( r ’ $ U _ { ЗИ } , В $ ’ , f o n t s i z e = 1 8 )
y l a b e l ( r ’ $ i _ { с } , мкA $ ’ , f o n t s i z e = 1 8 )
x l i m ( - 5 , 0 . 5 )
y l i m ( - 1 0 , 6 0 )
s h o w ( )
Кусочно-линейная аппроксимация заменяет ВАХ транзистора д вумя отрез-
ками:
iс = 
0 +

1U
ЗИ при
U
ЗИ > U
отс
0 при U
ЗИ < U
отс (7.1)
Используя метод наименьших квадратов ( lstsq) и функцию матричного
умножения ( dot), произведём аппроксимацию этих двух участков ВАХ прямыми
линиями (рис. 7.2(а)). Разделим все измерения на два отрезк а от 0 В до−1.5 В
( b = 0 ;e = 4 ) и от −2.5 В до −4 В ( b= 5 ;e = 9 ). Выведем значения ко-
эффициентов аппроксимации, для чего добавим следующий код п еред выводом
изображения на экран функцей show():

162Глава 7. Библиотеки, встроенные вnumpy
5 4 3 2 1 0
U ; 10
0
10
20
30
40
50
60
i ; A
-
Рис. 7.1. Сток-затворная характеристика полевого транзис тора (ВАХ)  резуль-
таты эксперимента.
b = 0 ; e = 4 ; r = e - b
a = o n e s ( ( r , 2 ) )
a [ : , 1 ] = x [ 1 : r + 1 ] r e s u l t = l i n a l g . l s t s q ( a , y [ b : e ] )
y a 1 = d o t ( a , r e s u l t [ 0 ] ) p l o t ( x [ b : e ] , y a 1 , c o l o r = ’ b l a c k ’ )
p rint ( r e s u l t [ 0 ] )
b = 5 ; e = 9 ; r = e - b
a = o n e s ( ( r , 2 ) )
a [ : , 1 ] = x [ 1 : r + 1 ] r e s u l t = l i n a l g . l s t s q ( a , y [ b : e ] )
y a 1 = d o t ( a , r e s u l t [ 0 ] ) p l o t ( x [ b : e ] , y a 1 , c o l o r = ’ b l a c k ’ )
p rint ( r e s u l t [ 0 ] )
Результаты:
[ 62. 26.]
[ 0. 0.]
Функция lstsqвозвращает кортеж, нулевой элемент которого  коэффициен-
ты модели, первый элемент  сумма квадратов ошибок аппрокси мации (разниц
между реальными и аппроксимированными значениями). Тепер ь, используя те
же функции из модуля numpy, произведём аппроксимацию полиномом второго
порядка (7.2) для участка от 0 В до −3 В ( b=0; e=7 ) (рис. 7.2(b)).
i с =

0 +

1U
ЗИ +

2U 2
ЗИ (7.2)
Для получения параболической аппроксимации (см. рис. 7.2( b)) нужно заме-
нить код из предыдущего листинга на следующий:

7.2. Быстрое преобразование Фурье163
5 4 3 2 1 0
U ; 10
0
10
20
30
40
50
60
i ; A
-
5 4 3 2 1 0
U ; 10
0
10
20
30
40
50
60
i ; A
-
(a) (b)
Рис. 7.2. Различные подходы к аппроксимации вольт-амперно й характеристики
полевого транзистора: (a)  кусочно-линейная, (b)  парабо лическая.
b = 0 ; e = 7 ; r = e - b
a = o n e s ( ( r , 3 ) )
a [ : , 1 ] = x [ 1 : r + 1 ]
a [ : , 2 ] = x [ 1 : r + 1 ] * * 2 r e s u l t = l i n a l g . l s t s q ( a , y [ b : e ] )
y a 1 = d o t ( a , r e s u l t [ 0 ] ) p l o t ( x [ b : e ] , y a 1 , c o l o r = ’ b l a c k ’ )
p rint ( r e s u l t [ 0 ] )
Результат:
[ 69.71428571 41.38095238 6.0952381 ]
7.2 Быстрое преобразование Фурье
Библиотека fftпозволяет быстро и легко делать все возможные варианты
преобразования Фурье над массивами. Многие реализации пре образования Фу-
рье до сих пор поддерживают только массивы длиною в 2N
значений, где N
целое число, иначе массив либо обрезается до ближайшей степ ени двойки, либо
удлиняется нулями или периодически. Функции библиотеки fftподдерживают
длины массивов, являющиеся степенями 2, 3, 5 и 7 или произволь ными их про-
изведениями. Самые востребованные методы библиотеки fftrttf иirfft
позволяют произвести прямое Фурье-преобразование над дейс твительнозначны-
ми данными и обратное Фурье-преобразование над комплексны ми данными, для
которых половина значений является комплексно-сопряжённ ыми, причём сопря-
жённые значения не включаются в обрабатываемый массив. Далее приведём при-
мер расчёта Фурье-преобразования синусоиды:

164Глава 7. Библиотеки, встроенные вnumpy
f rom n u m p y i mport *
t = a r a n g e ( 0 , 1 , 0 . 1 )
x = s i n ( 2 * p i * t )
f x = f f t . r f f t ( x )
p rint ( f x )
Как и положено нормальной синусоиде, Фурье-образ которой р ассчитан на це-
лом числе периодов, наша имеет только одну существенно отли чную от нуля
компоненту:
[ -3.33066907e-16 +0.00000000e+00j -1.72084569e-15
-5.00000000e+00j 7.35173425e-16 +4.55540506e-16j
-6.24151122e-16 -1.76490554e-15j 1.83186799e-15
+4.44089210e-16j -1.11022302e-16 +0.00000000e+00j]
Все остальные значения порядка 10−
15
или ещё меньше следует признать нулями
с точностью вычислений. Часто требуется построить спектр мощности или амплитудный спектр сиг-
нала. С помощью numpyэта задача легко решается. Проще всего построить так
называемую периодограмму  неусреднённую оценку спектра по одной реализа-
ции. Для получения периодограммы мощности достаточно взят ь квадрат модуля
Фурье-образа. Чтобы мощность соответствовала коэффициен там при гармони-
ках в исходном сигнале, нужно учесть нормировку. Дело в том, что большинство
библиотечных функций Фурье-преобразования производят не обходимое для ал-
горитма суммирование, но не нормируют результат, поскольку в ряде случа-
ев (например, при реализации преобразования Гильберта, дл я фильтрации, для
расчёта функции когерентности) это излишне, а вычислитель ные ресурсы эко-
номятся. Поэтому нормировку необходимо произвести вручну ю. Для реализации
Фурье-преобразования в numpyнеобходимая нормировка  половина длины ис-
ходного ряда. Для начала можно построить амплитудный спект р моногармони-
ческого сигнала (рис. 7.3(a)):
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
r c P a r a m s [ ’ f o n t . s a n s - s e r i f ’ ] = [ ’ L i b e r a t i o n Ђ S a n s ’ ]
d t = 0 . 1
t = a r a n g e ( 0 , 1 0 0 , d t )
x = 2 . 5 * s i n ( 2 * p i * t ) f x = f f t . r f f t ( x ) / (
l en ( x ) / 2 )#нормировка на половину длины ряда
f n = 1 / ( 2 * d t ) #частота Найквиста
f r e q = l i n s p a c e ( 0 , f n ,
l en ( f x ) )#массив частот
p l o t ( f r e q ,
a bs ( f x ) , c o l o r = ’ b l a c k ’ )
t i t l e ( ’Амплитудный спектр ’ ) x l a b e l ( ’Частота, Гц ’ ) ;
y l a b e l ( ’Напряжение, В ’ )
y l i m ( [ 0 , 3 ] )

7.2. Быстрое преобразование Фурье165
0 1 2 3 4 5
, 0.0
0.5
1.0
1.5
2.0
2.5
3.0
,

0 1 2 3 4 5
, 0
2
4
6
8
10
, 2

(a)
(b)
Рис. 7.3. Амплитудный спектр моногармонического сигнала  ( a) и спектр мощ-
ности бигармонического сигнала  (b).
s a v e f i g ( ’ F F T . p n g ’ )
s h o w ( )
Здесь частота Найквиста  максимально разрешимая частота в спектре, равная
половине частоты выборки. Чтобы построить спектр, нужно ра ссчитать массив
частот, для которых с помощью преобразования Фурье получен ы значения ам-
плитуд гармоник. Это несложно сделать с помощью функции linspaceизnumpy ,
если учесть, что минимальная частота равна 0, максимальная  частота Найк-
виста, а число частот равно числу амплитуд. Если умножить Фурье образ синусоиды на ei
, а затем сделать обратное пре-
образование, получится сигнал, сдвинутый по фазе относите льно исходного на
. Чаще всего оказывается нужно сдвинуть сигнал на /2или −/ 2. По пра-
вилу Эйлера e−
i/ 2
= cos( −/ 2) + isin( −/ 2) = −i, то есть мы сдвинули фазу
синусоиды на и получили вместо синуса минус косинус:
f y = f x * - 1 j
y = f f t . i r f f t ( f y )
p rint ( y )
Вывод:
[-1. -0.80901699 -0.30901699 0.30901699
0.80901699 1. 0.80901699 0.30901699 -0.30901699 -0.80901 699]
Одинокая синусоида единичной амплитуды  не очень интересн ый пример.
Рассчитаем и построим график бигармонического сигнала, со стоящего из двух
синусоид разных амплитуд (рис. 7.3(b)):
f rom n u m p y i mport *

166Глава 7. Библиотеки, встроенные вnumpy
t = a r a n g e ( 0 , 2 , 0 . 1 )
x = 2 * s i n ( 2 * p i * t ) + 3 * c o s ( p i * t )
P x =
a bs ( f f t . r f f t ( x ) / ( 0 . 5 * len ( t ) ) ) * * 2
p rint ( P x )
Получаем коэффициент 9 при 2 члене, что соответствует квадр ату амплитуды
косинуса, и 4 при третьем  квадрат амплитуды синуса, осталь ные коэффици-
енты  нули:
[1.97215226e-33 9.00000000e+00 4.00000000e+00 7.296963 37e-31
2.30741815e-31 1.28189897e-31 1.04524070e-31 3.8259753 9e-31
3.86541844e-31 1.28189897e-31 1.97215226e-33]
Строим спектр мощности, увеличив длину ряда:
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
r c P a r a m s [ ’ f o n t . s a n s - s e r i f ’ ] = [ ’ L i b e r a t i o n Ђ S a n s ’ ]
d t = 0 . 1
t = a r a n g e ( 0 , 1 0 0 , d t )
x = 2 * s i n ( 2 * p i * t ) + 3 * c o s ( p i * t ) P x =
a bs ( f f t . r f f t ( x ) / ( 0 . 5 * len ( t ) ) ) * * 2
f n = 1 / ( 2 * d t ) p l o t ( l i n s p a c e ( 0 , f n ,
l en ( P x ) ) , P x , c o l o r = ’ b l a c k ’ )
t i t l e ( ’Спектр мощности ’ ) x l a b e l ( ’Частота, Гц ’ ) ;
y l a b e l ( r ’Мощность сигнала, В $ ^ 2 $ ’ )
y l i m ( [ 0 , 1 0 ] )
s h o w ( )
7.3 Генерация случайных чисел Кроме стандартного модуля randomесть библиотека randomиз модуля numpy,
которая позволяет генерировать псевдослучайные числа с са мыми различными
распределениями. Самыми распространёнными являются равно мерное, которо-
му соответствует функция uniform, и нормальное  функция normal. Обе эти
функции имеют одинаковый синтаксис: сначала идут параметры распределения,
потом  число значений, которое нужно сгенерировать. Если э то число не ука-
зать, получится не массив, а одно случайное число. Для равно мерного распреде-
ления на отрезке [a ;b] параметрами являются величины aи b, для нормального
со средним µи дисперсией 2
 величины µи.
f rom n u m p y i mport *
x = r a n d o m . u n i f o r m ( - 2 , 1 , 1 0 )
p rint ( x )
y = r a n d o m . n o r m a l ( 5 , 0 . 5 , 1 0 )

7.4. Примеры решения заданий167
p rint ( y )
Вывод программы:
[-0.41038517 0.33622363 -0.24998561 0.58409914 0.969823 31
-1.11356063 -0.43092171 -0.92418957 -0.49456604 -0.6147 4565]
[ 4.89630265 3.68213872 4.97692322 4.4682948 5.19711419
4.87308781 5.51078962 5.68588492 4.65777752 5.66324449]
Кроме генерации непрерывно распределённых чисел библиоте каrandom под-
держивает также множество дискретных распределений. Само е простое  равно-
мерное дискретное, когда вероятности всех событий равны, з адаётся с помощью
функции randint:
f rom n u m p y i mport *
x = r a n d o m . r a n d i n t ( - 1 0 , 1 0 , 1 0 )
p rint ( x )
y = r a n d o m . p e r m u t a t i o n ( x )
p rint ( y )
Синтаксис randintполностью повторяет таковой у uniform. В приведён-
ном примере использована ещё одна весьма полезная на практи ке функция
permutation . Она случайно тасует элементы массива, но не меняет оригина ль-
ный массив, как это видно из сравнения первой и второй строк в ывода приве-
дённой программы, а вместо этого создаёт новый:
[-9 -1 -7 2 8 -8 -4 5 -9 5]
[-9 -9 2 -4 5 -7 -1 5 8 -8]
В заключение раздела хотелось бы сказать, что numpyобладает гораздо бо-
лее мощными и гибкими возможностями, чем это можно проиллюст рировать в
рамках приведённого краткого ознакомительного курса. Но к расотаnumpyи его
удобство становятся очевидными только по мере использован ия.
7.4 Примеры решения заданий
Пример задачи 22 (Определитель матрицы) Найдите определитель ма-
трицы. Матрицу возьмите из текстового файла, созданного при выпол-
нении задания №15.
Решение задачи 22
f rom n u m p y i mport *
M = l o a d t x t ( ’ M a t r i x . t x t ’ )
p rint ( l i n a l g . d e t ( M ) )

168Глава 7. Библиотеки, встроенные вnumpy
Пример задачи 23 (Cистема линейных уравнений) Решите систему ли-
нейных уравнений, матрицу коэффициентов и столбец свободн ых членов
прочитайте из текстовых файлов, созданных в задании №15. За пишите
в новый текстовый файл полученные корни.
Решение задачи 23
f rom n u m p y i mport *
M = l o a d t x t ( ’ M a t r i x . t x t ’ )
V = l o a d t x t ( ’ V e c t o r . t x t ’ )
p rint ( l i n a l g . s o l v e ( M , V ) )
Пример задачи 24 (Аппроксимация параболою) Сгенерируйте парабо-
лу y= x2
− x− 6на отрезке [− 6; 6] . Прибавьте к ней белый шум с па-
раметрами (0; 2). Аппроксимируйте её полиномом второй степени. Оце-
ните ошибку аппроксимации. Постройте график (рис. 7(a)).
Решение задачи 24
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
x = a r a n g e ( - 6 , 6 , 0 . 1 ) #диапазон
y = x * * 2 - x - 6 #парабола
r = r a n d o m . n o r m a l ( 0 , 2 ,
l en ( x ) )#белый шум
z = y + r
a = o n e s ( (
l en ( x ) , 3 ) )
a [ : , 1 ] = x
a [ : , 2 ] = x * * 2 r e s u l t = l i n a l g . l s t s q ( a , z )
z a = d o t ( a , r e s u l t [ 0 ] ) #аппроксимирующая кривая
p l o t ( x , z , ’ o ’ , c o l o r = ’ r e d ’ )
p l o t ( x , z a , c o l o r = ’ b l u e ’ )
p rint ( r e s u l t [ 1 ] / len ( x ) )#ошибка аппроксимации
s h o w ( )
Значение ошибки аппроксимации должно быть порядка квадрат а стандарт-
ного отклонения шума.
Пример задачи 25 (Погрешности аппроксимации) Сгенерируйте 3 ря-
да y, как это описано в предыдущем задании, пусть ряды отличаются
реализациями шума. Для каждого x таким образом будет доступ но по 3

7.4. Примеры решения заданий169
значенияy. По этим значениям рассчитайте для каждого xсреднее зна-
чение ¯
y и среднеквадратичное отклонение от среднего
x. С использова-
нием полученных рядов и постройте график погрешностей резу льтатов
( errorbar ) (рис. 7(b)).
Решение задачи 25
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
x = a r a n g e ( - 6 , 6 , 0 . 1 )
y = x * * 2 - x - 6
r = r a n d o m . n o r m a l ( 0 , 2 ,
l en ( x ) )
y 1 = y + r
r = r a n d o m . n o r m a l ( 0 , 2 ,
l en ( x ) )
y 2 = y + r
r = r a n d o m . n o r m a l ( 0 , 2 ,
l en ( x ) )
y 3 = y + r
y = c o l u m n _ s t a c k ( [ y 1 , y 2 , y 3 ] ) e r r o r b a r ( x , m e a n ( y , a x i s = 1 ) , y e r r = [ s t d ( y , a x i s = 1 ) ,
s t d ( y , a x i s = 1 ) ] , m a r k e r = ’ . ’ , c o l o r = ’ g r e e n ’ , e c o l o r = ’ b l u e ’ )
s a v e f i g ( ’ p l o t . p n g ’ )
s h o w ( )
Пример задачи 26 (Генерация массивов случайных чисел) Сгенерируйте
случайные векторы из nдействительных значений с равномерным и нор-
мальным распределением, а также из nцелых чисел.
Решение задачи 26
n =
i nt (i nput ( ’Введите количество значений : ’ ) )
a =
i nput ( ’Введите диапазон равномерного распределения : ’ ) . s p l i t( )
x = r a n d o m . u n i f o r m (
f loat ( a [ 0 ] ) , float ( a [ 1 ] ) , n )
print ( x )
b =
i nput ( ’Введите параметры нормального распределения : ’ ) . s p l i t( )
y = r a n d o m . n o r m a l (
f loat ( b [ 0 ] ) , float ( b [ 1 ] ) * * 0 . 5 , n )
print ( y )
c =
i nput ( ’Введите диапазон для дискретного распределения : ’ ) . s p li t ( )
z = r a n d o m . r a n d i n t (
i nt ( c [ 0 ] ) , int ( c [ 1 ] ) , n )
p rint ( z )
Возможный вывод программы (при каждом запуске будут различ ные случайные
числа):

170Глава 7. Библиотеки, встроенные вnumpy
Введите количество значений: 8
Введите диапазон равномерного распределения: 1 10
[ 4.59727241 5.25897018 7.05872105 6.53497311
2.79842143 6.9183058 5.47890825 8.6876828 ]
Введите параметры нормального распределения: 3 9
[ 9.2115671 2.97903395 2.91634906 3.67303643
0.29596935 6.45306148 3.50505498 3.44637582]
Введите диапазон дискретного распределения: -10 10
[ 7 2 -2 -2 6 -8 3 1]
Чтобы вводить сразу несколько значений с клавиатуры, в данн ом примере был
использован метод split, разделяющий строку на подстроки. При выполне-
нии задания можно просто каждый необходимый параметр считы вать новым
input() .
Пример задачи 27 (Случайные перестановки) Сгенерируйте массив-ле-
сенку длины n. Cлучайно перемешайте его. На экран выведите изначаль-
ный и перемешанный массивы.
Решение задачи 27
f rom n u m p y i mport *
n =
i nt (i nput ( ’Размер массива : ’ ) )
x = a r a n g e ( n , 0 , - 1 )
p rint ( x )
y = r a n d o m . p e r m u t a t i o n ( x )
p rint ( y )
Возможный вывод программы (третья строка будет меняться от запуска к за-
пуску):
Размер массива: 10
[10 9 8 7 6 5 4 3 2 1]
[ 7 5 6 1 2 8 10 4 3 9]
Пример задачи 28 (Периодограмма синуса) Рассчитайте и постройте
периодограмму для функции sin(x) на отрезке x∈ [ ; ].
Решение задачи 28 Результат можно увидеть на рис. 8(a). Грубость графика
обусловлена малым объёмом данных.
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
t = a r a n g e ( - p i , p i , p i / 1 2 )
x = s i n ( 2 * p i * t )

7.5. Задания на использование встроенных библиотекnumpy171
P x = a bs ( f f t . r f f t ( x ) / ( 0 . 5 * len ( t ) ) ) * * 2
f n = 1 / ( 2 * p i / 1 2 ) f r e q = l i n s p a c e ( 0 , f n ,
l en ( P x ) )
g r i d ( T r u e ) ; p l o t ( f r e q , P x , c o l o r = ’ r e d ’ )
s h o w ( )
Пример задачи 29 (Сложный шум) Сгенерируйте случайный процесс,
представляющий собою сумму равномерно распределённых на от резке
[ − 10; 10] случайных величин и нормально распределённых случайных ве -
личин с параметрами (0; 1), длиною в 10000 значений. Постройте гисто-
грамму его распределения.
Решение задачи 29 Возможный результат можно увидеть на рис. 8(b). От за-
пуска к запуску картинка будет несколько варьировать.
f rom n u m p y i mport *
from m a t p l o t l i b . p y p l o t i mport *
n = 1 0 0 0 0
x = r a n d o m . u n i f o r m ( - 1 0 , 1 0 , n )
y = r a n d o m . n o r m a l ( 0 , 1 , n )
z = x + y
h i s t ( z , b i n s = 1 0 0 , n o r m e d = T r u e , c o l o r = ’ g r e e n ’ )
s h o w ( )
7.5 Задания на использование встроенных библиотек numpy
Для заданий, содержащих большое число вариантов (от 4 и боле е) следует
выполнить 1 вариант с номером (n − 1)% m+ 1 , где n номер в списке группы,
а m  число заданий.
Задание 24 Найдите определитель матрицы. Матрицу возьмите из
текстового файла, созданного ранее, либо у преподавателя.
Задание 25 Решите систему линейных уравнений. Матрицу коэффици-
ентов и столбец свободных членов прочитайте из текстовых фа йлов,
созданных ранее. Запишите в новый текстовый файл полученны е корни.
Задание 26 Сгенерируйте набор значений заданной функции с шумом.
Аппроксимируйте его полиномом второй степени. Оцените оши бку ап-
проксимации. Постройте график. Функции:
1. парабола y= x2 − x− 6на отрезке [− 4; 4] с белым шумом, распределённым
по нормальному закону с параметрами (0; 1);

172Глава 7. Библиотеки, встроенные вnumpy
2. параболаy= x2 − x− 6на отрезке [− 4; 4] с белым шумом, распределённым
по равномерному закону на отрезке [− 10; 10] ;
3. парабола y= x2 − x− 6на отрезке [− 4; 4] с белым шумом, распределённым
по закону 2
(random.chisquare ) с параметрами(6;n), где 6  количество
степеней свободы шума, а n длина ряда y;
4. парабола y= 5 x2
− 4x +1 на отрезке [− 6; 6] с белым шумом, распределённым
по нормальному закону с параметрами (0; 3);
5. парабола y= 5 x2
− 4x +1 на отрезке [− 6; 6] с белым шумом, распределённым
по равномерному закону на отрезке [− 1; 1] ;
6. парабола y= 5 x2
− 4x +1 на отрезке [− 6; 6] с белым шумом, распределённым
по закону 2
(random.chisquare ) с параметрами(6;n), где 6  количество
степеней свободы шума, а n длина ряда y;
7. парабола y= x2
+ 5 на отрезке [− 10; 10] с белым шумом, распределённым
по нормальному закону с параметрами (0; 1);
8. парабола y= x2
+ 5 на отрезке [− 10; 10] с белым шумом, распределённым
по равномерному закону на отрезке [− 10; 10] .
Задание 27 Сгенерируйте 5 рядов y, как это описано в предыдущем зада-
нии, пусть ряды отличаются реализациями шума. Для каждого xтаким
образом будет доступно по 5 значений y. По этим значениям рассчитай-
те для каждого xсоответствующее ему среднее значение ¯
y и средне-
квадратичное отклонение от среднего
y. С использованием полученных
рядов ¯
y (x ) и
y(
x ) постройте график средних с планками погрешностей
( errorbar ).
Задание 28 Сгенерируйте случайные векторы из 10, 30 и 200 значений:
1. с равномерным распределением на отрезке [− 0.5; 0 .5] ;
2. с нормальным распределением с параметрами µ= 1 , = 0 .5 ;
3. из целых чисел в диапазоне [0; 10].
Задание 29 Сгенерируйте и случайно перемешайте:
1. массив-диапазон, покрывающий полуинтервал [0; 10)с шагом 0.5;
2. массив-диапазон из целых чисел от 0 до 19;
3. массив из 10 чисел, первые 5 из которых нули, вторые 5  един ицы;
4. массив длины 10, в котором изначально в начале и в конце был о по
2 тройки. А середине  пятёрки;

7.5. Задания на использование встроенных библиотекnumpy173
5. массив из 4 нулей, 4 единиц и 4 двоек;
6. массив из 15 нулей и 1 единицы;
7. массив-пирамиду длины 11 из целых чисел, где среднее числ о  самое
большое, стоящие рядом с ним на 1 меньше, следующие по очереди
от середины ещё на 1 меньше и т. д., значение среднего числа за -
дайте сами;
8. массив, полученный в результате табулирования синусоид ы.
Выведите на экран сначала неизменённый массив, потом  пере мешан-
ный.
Задание 30 Рассчитайте и постройте периодограмму  оценку спектра
мощности:
1. сигнала y(x ), полученного по формуле 4 sin(x+/ 8) −1на отрезке
[ − 10; 10] с шагом 0.05;
2. сигнала y(x ), полученного по формуле 2 cos(x− 2) + sin(2 x− 4), на от-
резке [− 20 ; 10 ] с шагом /20;
3. нормального шума, параметры выберите сами;
4. равномерного шума, параметры выберите сами.
Задание 31 Сгенерируйте случайный процесс длиною в 10000 значений и
постройте гистограмму его распределения для следующих рядо в:
1. равномерный шум с параметрами (0,1) ;
2. равномерный шум с параметрами (− 4,10) ;
3. равномерный шум с параметрами (0.5 ,0 .6) ;
4. равномерный шум с параметрами (− a, a ), где a случайное равномерно
распределённое число из диапазона [0; 1];
5. равномерный шум с параметрами (− a, 2a ), где a случайное равномерно
распределённое число из диапазона [1; 10];
6. нормальный (гауссов) шум со стандартными параметрами: (0,1) ;
7. нормальный шум с параметрами (− 2,0 .25) ;
8. нормальный шум с параметрами (1,2 .5) ;
9. нормальный шум с нулевым средним и среднеквадратичным от клонением
, где  число, равномерно распределённое в диапазоне [0; 1];

174Глава 7. Библиотеки, встроенные вnumpy
10. нормальный шум с параметрами µ, , где µесть нормально распределён-
ное число со стандартными параметрами (0,1) , а  число, равномерно
распределённое в диапазоне [1,10] ;
11. процесс, представляющий собою сумму двух независимых ве личин, распре-
делённых равномерно на интервале [− 1; 1] ;
12. процесс, представляющий собою сумму 3 независимых велич ин, равномерно
распределённых на интервале [− 1; 1] ;
13. процесс, представляющий собою сумму двух нормально расп ределённых
случайных величин с единичною дисперсией, первое из которы х имеет сред-
нее −e, а второе имеет среднее e;
14. процесс, представляющий собою сумму большого числа (нап ример, 30) рав-
номерно распределённых на отрезке [− 0.1; 0 .1] случайных величин;
15. процесс, представляющий собою сумму большого числа (нап ример, 30) нор-
мально распределённых случайных величин с параметрами µ= 0 , = 0 .1 .

Учебное издание
Серия Библиотека ALT
Сысоева Марина Вячеславовна Сысоев Илья Вячеславович
Программирование для нормальных с нуля на языке Python В двух частях
Часть 1
Ответственный редактор: В. Л. Черный
Оформление обложки: А. С. Осмоловская Вёрстка: В. Л. Черный
Издание доступно в РИНЦ по адресу: https://elibrary.ru
ООО Базальт СПО
Адрес для переписки: 127015, Москва, а/я 21
Телефон: (495) 123-47-99. E-mail: sales@basealt.ru
http://basealt.ru
Подписано в печать 02.03.18. Формат 70x100/16.
Гарнитура Computer Modern. Печать офсетная. Бумага офсетн ая.
Усл. печ. л. 14.3[+0.33]. Уч.-изд. л. 11.77 Тираж 999 экз. Изд . номер. 044
Издательство ООО МАКС Пресс Лицензия ИД N 00510 от 01.12.99 г.
119992, ГСП-2, Москва, Ленинские горы, МГУ имени М. В. Ломон осова,
2-й учебный корпус, 527 к.
Тел. 8(495)939-3890/91. Тел./Факс 8(495)939-3891.

По вопросам приобретения обращаться: ООО Базальт СПО(495)123-47-99 E-mail: sales@basealt.ru http://basealt.ru

0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 1.0
0.5
0.0
0.5
1.0
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 1.0
0.5
0.0
0.5
1.0
(a)(b)
Рис. 1. График синусоиды серыми линиями  (a) и синусоиды (си ними) и коси-
нусоиды (зелёными) линиями  (b).
0.0 0.5 1.0 1.5 2.0 0
1
2
3
4
5 x
0.0 0.5 1.0 1.5 2.0 0
1
2
3
4
5
x
0.0 0.5 1.0 1.5 2.0 0
1
2
3
4
5 x
3
0.0 0.5 1.0 1.5 2.0 0
1
2
3
4
5 x
2
0.0 0.5 1.0 1.5 2.0 0
1
2
3
4
5 x
5
0.0 0.5 1.0 1.5 2.0 012345678 x
3
x3
Рис. 2. Пример построения нескольких графиков на одном поло
тне.

1 2 3 4 5 6 7 8 9 10 0
1
2
3
4
5
6
Java
26.9%
C
22.4%
C++ 16.4%
PHP13.4%
Python
11.9%
Ruby
9.0%
(a)
(b)
Рис. 3. Пример столбцовой (a) и круговой (b) диаграмм.
3 2 1 0 1 2 2.0
1.5
1.0
0.5
0.0
0.5
1.0
1.5
3 2 1 0 1 2 2.0
1.5
1.0
0.5
0.0
0.5
1.0
1.5
(a) (b)
Рис. 4. Пример построения контурных диаграмм: (a)  использ ованы линии, (b)
 использована заливка.

− −  − − −
−



− −  − − −
−



(a)(b)
Рис. 5. 3D-каркас (a) и 3D-поверхность (b).
3 2 1 0 1 2 3
2
1
0
1
2
(a) (b)
Рис. 6. Иллюстрация к задаче 21.

− − −    −





− − −    −





(a)(b)
Рис. 7. Иллюстрации к задачам 24  (а) и 25  (b). На рис. (а) пред ставлена за-
висимость y
i =
x2 i

x
i−
6 +
i (серые точки), где

i  нормально распределённые
случайные числа (шум) с нулевым средним и среднеквадратичн ым отклонени-
ем 2, и её аппроксимирующая функция (чёрная кривая), рассчит анная методом
наименьших квадратов. На рис. (b)  зависимость hy
k (
x )i
k =1 ,2 ,3 с разбросом
ошибок, построенная по 3 экспериментам ( k номер эксперимента), исходная
зависимость сгенерирована по формуле y
i =
x2i

x
i−
6 +
i, причём для каждого
эксперимента реализация шума своя.
0.0 0.5 1.0 1.5 2.0 0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
− − −     







(a) (b)
Рис. 8. Спектр мощности синусоиды, построенный по 1 периоду при шаге вы-
борки /12  (a) и гистограмма сложного (суммы равномерного и нормальн ого)
распределения  (b).

Сообщить о нарушении / Abuse

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