Файл: Учебник по информатике. Программирование на Python. Основы 1 Программирование на Python. Основы.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.12.2023
Просмотров: 103
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Открытый учебник по информатике. Программирование на Python. Основы
12
Функции целочисленного деления и нахождения остатка от деления работают по следующему правилу: если число a не делится нацело на b, то знак остатка должен совпадать со знаком делителя. Или соблюдается одно из следующих условий.
[
0 ≤ ???? < ????
???? < ???? ≤ 0
, где b – делитель, r – остаток.
Результат целочисленного деления в таком случае можно представить, как
????//???? = ⌊
????
????
⌋, где ⌊????⌋ − округление вниз (до меньшего или равного целого).
Соответственно, ????%???? = ???? − (????//????) ∙ ????
Поэтому
−12//7 = ⌊
−12 7
⌋ = ⌊−1 5
7
⌋ = −2
−12%7 = −12 − (−12//7) ∙ 7 = −12 − (−2) ∙ 7 = −12 + 2 ∙ 7 = 2
Или
13//(−6) = ⌊
13
−6
⌋ = ⌊−2 1
6
⌋ = −3 13%(−6) = 13 − 13%(−6) ∙ 7 = 13 − (−3) ∙ (−6) = 13 − 18 = −5
Также данные операции могут быть применены к вещественным числам.
Логика вычисления остается такая же – результат целочисленного деления является вещественным числом с нулевой дробной частью, результат для остатка от деления вычисляется по приведенной выше формуле.
Существует и другой подход к работе с остатками, когда остаток не может быть отрицательным. Например, остаток от деления 13 на -6 будет равен 1, а сам результат целочисленного деления равен 2.
При этом формула
???? = ???? ∙ ???? + ???? где b – делитель, r – результат целочисленного деления, q – остаток, справедлива для обоих случаев (Python и данного определения).
Открытый учебник по информатике. Программирование на Python. Основы
13
Знаки сравнения
Для числовых данных.
Операция
Обозначение Пример использования
Равно
==
4+2 == 3+3 # True
False == True # False
Не равно
!=
3+1 != 2+2 # False
Больше
>
2 > 2 – 3 # True
Больше или равно
>=
2 >= 1+1 # True
Меньше
<
3 < 10 # True
Меньше или равно
<=
5 <= 1 # False
True <= False # False
При использовании операторов присваивания с логическими значениями, последние сначала преобразуются в числовое представление – True в 1, False в 0.
Посмотрим, какие значения получаются в таком случае.
A
B
== != >
>= <
<=
False
False
1 0
0 1
0 1
False
True
0 1
0 0
1 1
True
False
0 1
1 1
0 0
True
True
1 0
0 1
0 1
Также в Python есть механизм цепочек сравнения (chaining comparison
operators) с помощью которого, в числе прочего, удобно обозначать диапазоны значений числовых переменных.
Пример.
Число х в диапазоне [10; 110].
10 <= x <= 110
Про сравнение объектов других типов будет рассказано в следующих главах.
Открытый учебник по информатике. Программирование на Python. Основы
14
Логические операции
Логические операции применяются для связки логических выражений.
Операция
Обозначение Пример использования
Отрицание not not True # False
Дизъюнкция or
False or True # True
Конъюнкция and
True and True # True
В языке Python всего три логические операции. В качестве альтернативы можно использовать, например, оператор <= для операции импликации и оператор == для эквивалентности. Однако стоит помнить о порядке выполнения операций в записываемом выражении.
Примеры.
Число х одновременно четно и больше 10. x % 2 == 0 and x > 10
Число оканчивается на 5 или принадлежит промежутку (-∞;0)U(100;+∞) x % 10 == 5 or 0 >= x <= 100
Любое выражение в Python вычисляется слева направо, поэтому при вычислении значения логического выражения выражение может быть вычислено досрочно. Выражение считается вычисленным, если результат левого операнда дизъюнкции равен True или результат левого операнда конъюнкции равен False. Так как нет смысла вычислять значение выражения
1 or expr или 0 and expr, потому что результат первого всегда будет истинным, второго – ложным.
Пример вычисления с «досрочным» результатом: a = 10 b = 15 c = 20
# True or ... == True if a < b or c > a + b: c = 10
На этом принципе построены некоторые алгоритмы проверок значений.
Например, при работе с конъюнкцией правильнее писать в качестве левой части выражения самое редко встречающееся условие, тогда записанные правее условия будут проверяться только при истинности самого редко срабатывающего условия.
Открытый учебник по информатике. Программирование на Python. Основы
15
Побитовые операции
Применяются для обработки целых чисел в двоичном представлении.
Операция
Обозначение Пример использования
Побитовое отрицания
a
5 # -6
Побитовое умножение a & b
13 & 10 # 8
Побитовое сложение a | b
13 | 6 # 15
Побитовое исключающее или a ^ b
13 ^ 6 # 11
Побитовое отрицание производит инвертирование бит, в том числе бита, отвечающего за знак [3]. Поэтому в результате получается значение –(a+1).
Сокращенная запись
Для действий, направленных на изменение значения переменной относительно текущего значения могут применяться сокращенные операторы.
Операция
Обозначение Эквивалент
Сложение a += e a = a + e
Вычитание a -= e a = a - e
Умножение a *= e a = a * e
Деление a /= e a = a / e
Целочисленное деление a //= e a = a // e
Остаток от деления a %= e a = a % e
Побитовое умножение a &= e a = a & e
Побитовое сложение a |= e a = a | e
Побитовое исключающее или a ^= e a = a ^ e
Сокращенные операторы выполняются всегда в самом конце, после вычисления выражения справа от оператора.
Открытый учебник по информатике. Программирование на Python. Основы
16
Приоритет выполнения операций
В любом выражении можно задавать порядок выполнения операций с помощью скобок. В остальных случаях нужно знать, в каком порядке выполняются операции в выражении.
Приоритет выполнения операций следующий
Операция
**
*, /, //, %
+, -
&
|
^
==, !=, <, <=, >, >= not and or
Говоря иначе, чем выше операция в таблице, тем раньше она выполняется.
Если несколько операций записаны в одной строке, то они имеют одинаковый приоритет. При наличии их в одном выражении, выполняются они слева направо, то есть в первую очередь выполняется самая левая одноприоритетная операция.
Пример (рис.4-5)
Рисунок 5. Порядок выполнения операций в выражении
Рисунок 6. Расстановка приоритета операций с помощью скобок
Стоит заметить, что почти все операции являются лево ассоциативными, то есть при совпадении приоритета у соседних операций сначала выполняется операция, которая левее, затем правая.
Единственное исключение – операция возведения в степень, являющаяся право ассоциативной.
Например, запись a**b**c будет вычисляться, как ????
????
????
, а не как (????
????
)
с
Открытый учебник по информатике. Программирование на Python. Основы
17
Ввод и вывод данных
Для коммуникации с программным кодом при запуске программы, в программу вставляют специализированные функции – ввода и вывода.
Чтобы программа обработала какое-либо значение, его необходимо ввести.
Сделать это можно по-разному – считать из файла, запросить у сервиса в интернете или просто ввести через терминал.
Разберем самый простой случай.
Ввод значения через терминал.
Для этого в Python есть функция input().
Функция input() возвращает поступившее через терминал сообщение до переноса строки.
ВАЖНО: результатом работы функции input() является строковое значение.
Поэтому если нужно ввести число, то считанное строковое значение необходимо преобразовать с помощью соответствующей функции преобразования – int() или float().
Пример – ввод целого числа из терминала.
# ввод строки из терминала inp = input()
# преобразование введенной строки в целевое значение x = int(inp)
Также данную операцию можно выполнить в одну строку, передав результат выполнения функции input() на вход функции для преобразования. x = int(input())
Для интерактивности можно в качестве аргумента функции input привести приветственную строку. Например, «Input x: ». x = int(input('Input x:'))
Открытый учебник по информатике. Программирование на Python. Основы
18
Вывод значений на экран
Для вывода сообщений на экран используется функция print().
Функция принимает на вход значения или имена переменных через запятую, которые необходимо вывести. Строго говоря, данная функция имеет ряд настроек, которые нужны для корректировки формата вывода. Однако на данном этапе для нас хватит и уже описанного функционала.
Пример – вывод через пробел значений переменных a и b. print(a, b)
Пример простой программы для нахождения корня линейного уравнения
kx+b = 0.
# ввод коэффициента k k = float(input('Input k:'))
# ввод коэффициента b b = float(input('Input b:'))
# вычисление корня x = -b / k
# вывод корня на экран print('x =', x)
Условный оператор
Условный оператор – конструкция, управляющая цепочкой вычислений, которая позволяет выбрать ОДИН ИЗ n вариантов дальнейшего выполнения алгоритма.
Говоря на языке примеров, у нас есть n возможных вариантов вычислений, чтобы для каждого из них реализовать различные алгоритмы мы применяем конструкцию «если вариант1, то делаем1, иначе если вариант2, делаем2, …, иначе если вариантN то делаемN, во всех не перечисленных случаях
делаем(N+1)».
Условный оператор является первым из рассматриваемых в этом учебнике составным оператором. Составным он называется, потому что состоит из нескольких частей – ключевых слов (if, elif else) и блоков команд, выполняемых при истинности одного из условия (про блоки команд подробнее ниже).
Подробную документацию по этому и другим операторам можно найти в официальной документации [4] или в неофициальном русском переводе [5].
Открытый учебник по информатике. Программирование на Python. Основы
19
Условный оператор можно представить, как условный_оператор ::= "if" условие ":" блок команд
("elif" условие ":" блок команд)*
["else" ":" блок команд]
В представленной нотации запись (…)* означает, что на этом месте может быть 0 или больше выражений, описанных в скобках, […] – может быть 0 или
1 выражение описанного в скобках формата.
Говоря иначе, допустимы, например, такие использования условный_оператор ::= "if" условие1 ":" блок команд 1
Или
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"elif" условие3 ":" блок команд 3
Или
условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"else" ":" блок команд 3
Или
условный_оператор ::= "if" условие1 ":" блок команд "else" ":" блок команд 2
Самая важная особенность – условный оператор выбирает не более одного блока команд, который будет выполнен. В случае, если ни одно условие не выполняется и не задана секция else, условный оператор не перейдет ни к какому блоку команд и передаст управление команде, следующей сразу после последнего блока команд, описанного в условном операторе.
ВАЖНО. Условия проверяются в той последовательности, в которой они указаны в последовательности блоков elif.
Например, следующие обобщенные алгоритмы не являются эквивалентными:
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"elif" условие3 ":" блок команд 3
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие3 ":" блок команд 3
"elif" условие2 ":" блок команд 2
Открытый учебник по информатике. Программирование на Python. Основы
20
Если мы нумеруем условия в порядке их указания в составном условном операторе, то логика проверки условий и, соответственно, выбора блока команд будет следующая:
Если выполняется условие1, то выполняем блок команд 1 и завершаем работу условного оператора, иначе, если выполняется условие 2, то выполняем блок команд 2 и завершаем работу условного оператора, …, если не выполняется ни одно условия, выполняем блок команд, указанный после else (если блок указан) либо завершаем работу условного оператора (если блок команд для else не указан).
Данный процесс можно представить в виде блок схемы (рис.7).
Рисунок 7. Схематическое изображение работы условного оператора
В случае отсутствия секции блока else программа не выполнит ничего во время работы условного оператора, когда ни одно из условий не будет истинным
(блок команд N+1 будет отсутствовать). Если в условном операторе не будет блоков elif, то условный оператор выполнит блок команд 1, если условие выполняется, и блок команд N+1, если не выполняется. Когда же нет ни блоков
elif, ни блока else, алгоритм выполнит блок команд 1, если условие истинно, и не выполнит ничего, если условие ложно.
Открытый учебник по информатике. Программирование на Python. Основы
21
Блоки команд
В языке Python доступно два варианта оформления блоков команд в составных операторах, в том числе и условном операторе.
1) На той же строке, что и ключевые слова – if, elif и else для условного оператора – через точку с запятой.
Пример: if x % 2 == 0: y = y +x; z = 10 else: y = 0; z = 13 2) Каждая команда с новой строки и уровнем отступа на 1 больше, чем у ключевых слов if, elif и else
Тот же пример: if x % 2 == 0: y = y +x z = 10 else: y = 0 z = 13
Второй способ считается общепринятым и соответствует официальным рекомендациям по оформлению кода PEP-8 [1].
В чем же заключается идея такого формата.
Все блоки команд в составном операторе являются вложенными. Чтобы показать уровень вложенности для блока команд в таком операторе увеличивают отступ относительно ключевого слова. Также очень важно, чтобы все дальнейшие составные команды использовали аналогичное количество пробелов в качестве отступа.
Чтобы не считать каждый раз пробелы принято устанавливать отступы с помощью знака табуляции (кнопка Tab на клавиатуре, обычно, над Caps Lock).
Команды одного уровня вложенности в рамках одного составного оператора должны иметь одинаковый отступ от начала строки.
Строго говоря, Python не запрещает делать разные отступы для обособленных составных операторов. Однако, такой подход противоречит рекомендациям
PEP-8 и усложняет поддержку написанного кода.
Открытый учебник по информатике. Программирование на Python. Основы
22
Для иллюстрации приведем два примера – с разными отступами и с одинаковыми. Данные примеры наглядно показывают удобство применения рекомендации PEP-8 для оформления блоков команд.
Пример 1 (разные отступы) if x % 2 == 0: y = y + x if y > 5: y = 6 if x // 3 == 4: y = 0 if x > 10: z = 22
Пример 2 (одинаковые отступы) if x % 2 == 0: y = y + x if y > 5: y = 6 if x // 3 == 4: y = 0 if x > 10: z = 22
Тернарная условная операция
Для удобства в некоторых случаях используют тернарную условную операцию. Обычно, она используется, когда в зависимости от условия устанавливает значение конкретной переменной.
Пример (в формате обычного условного оператора): if y > 10: x = 5 else: x = y + 3
Пример (с помощью тернарной условной операции): x = 5 if y > 10 else y + 3
Тернарную условную операцию удобно применять, когда условие небольшое и выражение, которое присваивается, в обоих случаях получается по простому алгоритму. Иначе анализ тернарной условной операции становится гораздо сложнее и увеличивает сложность поддержки кода. В качестве маркера
«понятного» выражения можно использовать, например, рекомендации Дзен
Python [6] и не делать строки длиной более 79 символов.
Открытый учебник по информатике. Программирование на Python. Основы
23
Запуск и трассировка программы
Мы подходим к практике. Точнее пока что больше к попыткам запустить написанную программу и исследовать, как она работает. Для этого нам нужен, собственно, сам интерпретатор и самый простой инструмент для написания кода – IDLE [7].
После скачивания установочного файла по ссылке и его установки у нас появляется доступ к IDLE (обычно это ярлык в меню «Пуск»). Открываем его и компьютер готов к экспериментам.
После запуска появляется окно Python Shell, здесь ты можешь покомандно вводить программу и смотреть, что получается. В рамках данного параграфа нас интересует возможность запускать написанные программы (скрипты).
Для этого нужно наш код оформить в виде файла.
Алгоритм действий:
1) File -> New file (или Ctrl+N)
2) Пишем код, который хотим запустить
3) Сохраняем написанный код в файл (важно делать перед каждым запуском)
4) Запускаем (Run -> Run module или F5)
Теперь мы умеем создать файл с программой и запустить его. После запуска мы можем проанализировать вывод нашей программы. Например, результат может быть как на рис.8.
Рисунок 8. Запуск простой программы и результат
Открытый учебник по информатике. Программирование на Python. Основы
24
Инструмент Debug
Однако при разработке нашего алгоритма мы можем допустить логические ошибки в коде, в связи с чем наш код будет делать не то, что мы хотим.
Отследить поведение программы с помощью вывода промежуточных вычислений с помощью функции print, конечно, можно. Но такой метод может оказаться весьма неудобным, если мы имеем дело, например, с многострочной программой или циклом с большим количеством повторов.
Неудобный он в первую очередь из-за возможно длинного вывода и неудобства анализировать таковой.
Поэтому для пошагового анализа работы программы используют специализированные средства отладки – отладчики, также именуемые дебагерами (от de – отрицание действия, bug – программная ошибка [8]).
Для запуска Debug-режима в IDLE необходимо выбрать в меню
Debug -> Debugger. Теперь при запуске скрипта код будет выполняться по одной инструкции при нажатии на кнопку Step, и по одной строке при нажатии на кнопку Over.
Режим Step выполняет все инструкции внутри вызываемых методов, поэтому анализ хода выполнения программы получается существенно длиннее. Over же работает построчно и позволяет в ускоренном режиме проанализировать работу написанного кода.
В нижней области окна отладчика можно контролировать значения переменных на текущем этапе
Рисунок 9. Окно дебагера IDLE
Область 1 – панель управление ходом выполнения программы.
Открытый учебник по информатике. Программирование на Python. Основы
25
Go – продолжить выполнение до конца,
Step – выполнить следующую команду,
Over – выполнить текущую строку,
Out – выполнить текущую функцию до конца (предполагает, что сейчас отладчик находится внутри функции),
Quit – закончить работу отладчика.
Про функции мы поговорим в одной из следующих глав. На текущем этапе для нас наиболее полезные кнопки – Go и Over.
Область 2 – стек вызовов [9].
Область 3 – состояние памяти.
Здесь отображаются значения служебных переменных и тех, которые мы используем в ходе выполнения программы.
Для удобства анализа полезно поставить галочку на пункте Source, тогда в соседнем окне будет подсвечиваться текущая выполняемая строка (рис.10).
Рисунок 10. Пример отображения окна отладчика и исходного кода
Открытый учебник по информатике. Программирование на Python. Основы
26
Про объекты в памяти
Если начать писать программу в оболочке REPL для Python (REPL – read, eval,
print, loop), можно заметить одну особенность. Значения в диапазоне [-5; 256] будут иметь всегда один и тот же адрес для разных переменных, другие значения при их именовании будут иметь разные адреса для разных имен в случае совпадения значений.
Так, при попытке выполнить следующую последовательность команд,
1. >>> a = 100 2. >>> b = 55 + 45 имена a и b будут ссылаться на один и тот же объект.
В то время, как при следующей последовательности вычислений
1. >>> a = 1000 2. >>> b = 550 + 450 имена a и b будут ссылаться на разные объекты.
REPL
Скрипт
>>> a = 100
>>> b = 55 + 45
>>> id(a), id(b)
(1342269254224, 1342269254224)
>>> a = 1000
>>> b = 550 + 450
>>> id(a), id(b)
(1342341491280, 1342341490800) a = 100 b = 55 + 45 print(id(a), id(b)) a = 1000 b = 550 + 450 print(id(a), id(b))
2037007603152 2037007603152 2037013785168 2037013785168
Функция print выводит переданные ей значения на экран через пробел.
Это объясняется тем, что при запуске интерпретатора CPython создаются объекты для значений в диапазоне [-5; 256], так как считается, что это наиболее часто используемые значения. Такой подход позволяет не тратить время на выделение памяти для них. Аналогично кэшируются при первом использовании строковые значения, состоящие из букв, цифр и символов подчеркивания длиной до 20 символов.
При запуске же скрипта целиком происходит кеширование всех используемых неизменяемых объектов. Эта процедура относится к оптимизации использования памяти и в данном разделе не рассматривается. Данный факт можно проверить с помощью функции id(var_name), которая возвращает адрес объекта, на который ссылается переменная var_name.
Открытый учебник по информатике. Программирование на Python. Основы
27
1 2 3 4 5 6 7 8
Операция
Обозначение Пример использования
Отрицание not not True # False
Дизъюнкция or
False or True # True
Конъюнкция and
True and True # True
В языке Python всего три логические операции. В качестве альтернативы можно использовать, например, оператор <= для операции импликации и оператор == для эквивалентности. Однако стоит помнить о порядке выполнения операций в записываемом выражении.
Примеры.
Число х одновременно четно и больше 10. x % 2 == 0 and x > 10
Число оканчивается на 5 или принадлежит промежутку (-∞;0)U(100;+∞) x % 10 == 5 or 0 >= x <= 100
Любое выражение в Python вычисляется слева направо, поэтому при вычислении значения логического выражения выражение может быть вычислено досрочно. Выражение считается вычисленным, если результат левого операнда дизъюнкции равен True или результат левого операнда конъюнкции равен False. Так как нет смысла вычислять значение выражения
1 or expr или 0 and expr, потому что результат первого всегда будет истинным, второго – ложным.
Пример вычисления с «досрочным» результатом: a = 10 b = 15 c = 20
# True or ... == True if a < b or c > a + b: c = 10
На этом принципе построены некоторые алгоритмы проверок значений.
Например, при работе с конъюнкцией правильнее писать в качестве левой части выражения самое редко встречающееся условие, тогда записанные правее условия будут проверяться только при истинности самого редко срабатывающего условия.
Открытый учебник по информатике. Программирование на Python. Основы
15
Побитовые операции
Применяются для обработки целых чисел в двоичном представлении.
Операция
Обозначение Пример использования
Побитовое отрицания
a
5 # -6
Побитовое умножение a & b
13 & 10 # 8
Побитовое сложение a | b
13 | 6 # 15
Побитовое исключающее или a ^ b
13 ^ 6 # 11
Побитовое отрицание производит инвертирование бит, в том числе бита, отвечающего за знак [3]. Поэтому в результате получается значение –(a+1).
Сокращенная запись
Для действий, направленных на изменение значения переменной относительно текущего значения могут применяться сокращенные операторы.
Операция
Обозначение Эквивалент
Сложение a += e a = a + e
Вычитание a -= e a = a - e
Умножение a *= e a = a * e
Деление a /= e a = a / e
Целочисленное деление a //= e a = a // e
Остаток от деления a %= e a = a % e
Побитовое умножение a &= e a = a & e
Побитовое сложение a |= e a = a | e
Побитовое исключающее или a ^= e a = a ^ e
Сокращенные операторы выполняются всегда в самом конце, после вычисления выражения справа от оператора.
Открытый учебник по информатике. Программирование на Python. Основы
16
Приоритет выполнения операций
В любом выражении можно задавать порядок выполнения операций с помощью скобок. В остальных случаях нужно знать, в каком порядке выполняются операции в выражении.
Приоритет выполнения операций следующий
Операция
**
*, /, //, %
+, -
&
|
^
==, !=, <, <=, >, >= not and or
Говоря иначе, чем выше операция в таблице, тем раньше она выполняется.
Если несколько операций записаны в одной строке, то они имеют одинаковый приоритет. При наличии их в одном выражении, выполняются они слева направо, то есть в первую очередь выполняется самая левая одноприоритетная операция.
Пример (рис.4-5)
Рисунок 5. Порядок выполнения операций в выражении
Рисунок 6. Расстановка приоритета операций с помощью скобок
Стоит заметить, что почти все операции являются лево ассоциативными, то есть при совпадении приоритета у соседних операций сначала выполняется операция, которая левее, затем правая.
Единственное исключение – операция возведения в степень, являющаяся право ассоциативной.
Например, запись a**b**c будет вычисляться, как ????
????
????
, а не как (????
????
)
с
Открытый учебник по информатике. Программирование на Python. Основы
17
Ввод и вывод данных
Для коммуникации с программным кодом при запуске программы, в программу вставляют специализированные функции – ввода и вывода.
Чтобы программа обработала какое-либо значение, его необходимо ввести.
Сделать это можно по-разному – считать из файла, запросить у сервиса в интернете или просто ввести через терминал.
Разберем самый простой случай.
Ввод значения через терминал.
Для этого в Python есть функция input().
Функция input() возвращает поступившее через терминал сообщение до переноса строки.
ВАЖНО: результатом работы функции input() является строковое значение.
Поэтому если нужно ввести число, то считанное строковое значение необходимо преобразовать с помощью соответствующей функции преобразования – int() или float().
Пример – ввод целого числа из терминала.
# ввод строки из терминала inp = input()
# преобразование введенной строки в целевое значение x = int(inp)
Также данную операцию можно выполнить в одну строку, передав результат выполнения функции input() на вход функции для преобразования. x = int(input())
Для интерактивности можно в качестве аргумента функции input привести приветственную строку. Например, «Input x: ». x = int(input('Input x:'))
Открытый учебник по информатике. Программирование на Python. Основы
18
Вывод значений на экран
Для вывода сообщений на экран используется функция print().
Функция принимает на вход значения или имена переменных через запятую, которые необходимо вывести. Строго говоря, данная функция имеет ряд настроек, которые нужны для корректировки формата вывода. Однако на данном этапе для нас хватит и уже описанного функционала.
Пример – вывод через пробел значений переменных a и b. print(a, b)
Пример простой программы для нахождения корня линейного уравнения
kx+b = 0.
# ввод коэффициента k k = float(input('Input k:'))
# ввод коэффициента b b = float(input('Input b:'))
# вычисление корня x = -b / k
# вывод корня на экран print('x =', x)
Условный оператор
Условный оператор – конструкция, управляющая цепочкой вычислений, которая позволяет выбрать ОДИН ИЗ n вариантов дальнейшего выполнения алгоритма.
Говоря на языке примеров, у нас есть n возможных вариантов вычислений, чтобы для каждого из них реализовать различные алгоритмы мы применяем конструкцию «если вариант1, то делаем1, иначе если вариант2, делаем2, …, иначе если вариантN то делаемN, во всех не перечисленных случаях
делаем(N+1)».
Условный оператор является первым из рассматриваемых в этом учебнике составным оператором. Составным он называется, потому что состоит из нескольких частей – ключевых слов (if, elif else) и блоков команд, выполняемых при истинности одного из условия (про блоки команд подробнее ниже).
Подробную документацию по этому и другим операторам можно найти в официальной документации [4] или в неофициальном русском переводе [5].
Открытый учебник по информатике. Программирование на Python. Основы
19
Условный оператор можно представить, как условный_оператор ::= "if" условие ":" блок команд
("elif" условие ":" блок команд)*
["else" ":" блок команд]
В представленной нотации запись (…)* означает, что на этом месте может быть 0 или больше выражений, описанных в скобках, […] – может быть 0 или
1 выражение описанного в скобках формата.
Говоря иначе, допустимы, например, такие использования условный_оператор ::= "if" условие1 ":" блок команд 1
Или
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"elif" условие3 ":" блок команд 3
Или
условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"else" ":" блок команд 3
Или
условный_оператор ::= "if" условие1 ":" блок команд "else" ":" блок команд 2
Самая важная особенность – условный оператор выбирает не более одного блока команд, который будет выполнен. В случае, если ни одно условие не выполняется и не задана секция else, условный оператор не перейдет ни к какому блоку команд и передаст управление команде, следующей сразу после последнего блока команд, описанного в условном операторе.
ВАЖНО. Условия проверяются в той последовательности, в которой они указаны в последовательности блоков elif.
Например, следующие обобщенные алгоритмы не являются эквивалентными:
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"elif" условие3 ":" блок команд 3
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие3 ":" блок команд 3
"elif" условие2 ":" блок команд 2
Открытый учебник по информатике. Программирование на Python. Основы
20
Если мы нумеруем условия в порядке их указания в составном условном операторе, то логика проверки условий и, соответственно, выбора блока команд будет следующая:
Если выполняется условие1, то выполняем блок команд 1 и завершаем работу условного оператора, иначе, если выполняется условие 2, то выполняем блок команд 2 и завершаем работу условного оператора, …, если не выполняется ни одно условия, выполняем блок команд, указанный после else (если блок указан) либо завершаем работу условного оператора (если блок команд для else не указан).
Данный процесс можно представить в виде блок схемы (рис.7).
Рисунок 7. Схематическое изображение работы условного оператора
В случае отсутствия секции блока else программа не выполнит ничего во время работы условного оператора, когда ни одно из условий не будет истинным
(блок команд N+1 будет отсутствовать). Если в условном операторе не будет блоков elif, то условный оператор выполнит блок команд 1, если условие выполняется, и блок команд N+1, если не выполняется. Когда же нет ни блоков
elif, ни блока else, алгоритм выполнит блок команд 1, если условие истинно, и не выполнит ничего, если условие ложно.
Открытый учебник по информатике. Программирование на Python. Основы
21
Блоки команд
В языке Python доступно два варианта оформления блоков команд в составных операторах, в том числе и условном операторе.
1) На той же строке, что и ключевые слова – if, elif и else для условного оператора – через точку с запятой.
Пример: if x % 2 == 0: y = y +x; z = 10 else: y = 0; z = 13 2) Каждая команда с новой строки и уровнем отступа на 1 больше, чем у ключевых слов if, elif и else
Тот же пример: if x % 2 == 0: y = y +x z = 10 else: y = 0 z = 13
Второй способ считается общепринятым и соответствует официальным рекомендациям по оформлению кода PEP-8 [1].
В чем же заключается идея такого формата.
Все блоки команд в составном операторе являются вложенными. Чтобы показать уровень вложенности для блока команд в таком операторе увеличивают отступ относительно ключевого слова. Также очень важно, чтобы все дальнейшие составные команды использовали аналогичное количество пробелов в качестве отступа.
Чтобы не считать каждый раз пробелы принято устанавливать отступы с помощью знака табуляции (кнопка Tab на клавиатуре, обычно, над Caps Lock).
Команды одного уровня вложенности в рамках одного составного оператора должны иметь одинаковый отступ от начала строки.
Строго говоря, Python не запрещает делать разные отступы для обособленных составных операторов. Однако, такой подход противоречит рекомендациям
PEP-8 и усложняет поддержку написанного кода.
Открытый учебник по информатике. Программирование на Python. Основы
22
Для иллюстрации приведем два примера – с разными отступами и с одинаковыми. Данные примеры наглядно показывают удобство применения рекомендации PEP-8 для оформления блоков команд.
Пример 1 (разные отступы) if x % 2 == 0: y = y + x if y > 5: y = 6 if x // 3 == 4: y = 0 if x > 10: z = 22
Пример 2 (одинаковые отступы) if x % 2 == 0: y = y + x if y > 5: y = 6 if x // 3 == 4: y = 0 if x > 10: z = 22
Тернарная условная операция
Для удобства в некоторых случаях используют тернарную условную операцию. Обычно, она используется, когда в зависимости от условия устанавливает значение конкретной переменной.
Пример (в формате обычного условного оператора): if y > 10: x = 5 else: x = y + 3
Пример (с помощью тернарной условной операции): x = 5 if y > 10 else y + 3
Тернарную условную операцию удобно применять, когда условие небольшое и выражение, которое присваивается, в обоих случаях получается по простому алгоритму. Иначе анализ тернарной условной операции становится гораздо сложнее и увеличивает сложность поддержки кода. В качестве маркера
«понятного» выражения можно использовать, например, рекомендации Дзен
Python [6] и не делать строки длиной более 79 символов.
Открытый учебник по информатике. Программирование на Python. Основы
23
Запуск и трассировка программы
Мы подходим к практике. Точнее пока что больше к попыткам запустить написанную программу и исследовать, как она работает. Для этого нам нужен, собственно, сам интерпретатор и самый простой инструмент для написания кода – IDLE [7].
После скачивания установочного файла по ссылке и его установки у нас появляется доступ к IDLE (обычно это ярлык в меню «Пуск»). Открываем его и компьютер готов к экспериментам.
После запуска появляется окно Python Shell, здесь ты можешь покомандно вводить программу и смотреть, что получается. В рамках данного параграфа нас интересует возможность запускать написанные программы (скрипты).
Для этого нужно наш код оформить в виде файла.
Алгоритм действий:
1) File -> New file (или Ctrl+N)
2) Пишем код, который хотим запустить
3) Сохраняем написанный код в файл (важно делать перед каждым запуском)
4) Запускаем (Run -> Run module или F5)
Теперь мы умеем создать файл с программой и запустить его. После запуска мы можем проанализировать вывод нашей программы. Например, результат может быть как на рис.8.
Рисунок 8. Запуск простой программы и результат
Открытый учебник по информатике. Программирование на Python. Основы
24
Инструмент Debug
Однако при разработке нашего алгоритма мы можем допустить логические ошибки в коде, в связи с чем наш код будет делать не то, что мы хотим.
Отследить поведение программы с помощью вывода промежуточных вычислений с помощью функции print, конечно, можно. Но такой метод может оказаться весьма неудобным, если мы имеем дело, например, с многострочной программой или циклом с большим количеством повторов.
Неудобный он в первую очередь из-за возможно длинного вывода и неудобства анализировать таковой.
Поэтому для пошагового анализа работы программы используют специализированные средства отладки – отладчики, также именуемые дебагерами (от de – отрицание действия, bug – программная ошибка [8]).
Для запуска Debug-режима в IDLE необходимо выбрать в меню
Debug -> Debugger. Теперь при запуске скрипта код будет выполняться по одной инструкции при нажатии на кнопку Step, и по одной строке при нажатии на кнопку Over.
Режим Step выполняет все инструкции внутри вызываемых методов, поэтому анализ хода выполнения программы получается существенно длиннее. Over же работает построчно и позволяет в ускоренном режиме проанализировать работу написанного кода.
В нижней области окна отладчика можно контролировать значения переменных на текущем этапе
Рисунок 9. Окно дебагера IDLE
Область 1 – панель управление ходом выполнения программы.
Открытый учебник по информатике. Программирование на Python. Основы
25
Go – продолжить выполнение до конца,
Step – выполнить следующую команду,
Over – выполнить текущую строку,
Out – выполнить текущую функцию до конца (предполагает, что сейчас отладчик находится внутри функции),
Quit – закончить работу отладчика.
Про функции мы поговорим в одной из следующих глав. На текущем этапе для нас наиболее полезные кнопки – Go и Over.
Область 2 – стек вызовов [9].
Область 3 – состояние памяти.
Здесь отображаются значения служебных переменных и тех, которые мы используем в ходе выполнения программы.
Для удобства анализа полезно поставить галочку на пункте Source, тогда в соседнем окне будет подсвечиваться текущая выполняемая строка (рис.10).
Рисунок 10. Пример отображения окна отладчика и исходного кода
Открытый учебник по информатике. Программирование на Python. Основы
26
Про объекты в памяти
Если начать писать программу в оболочке REPL для Python (REPL – read, eval,
print, loop), можно заметить одну особенность. Значения в диапазоне [-5; 256] будут иметь всегда один и тот же адрес для разных переменных, другие значения при их именовании будут иметь разные адреса для разных имен в случае совпадения значений.
Так, при попытке выполнить следующую последовательность команд,
1. >>> a = 100 2. >>> b = 55 + 45 имена a и b будут ссылаться на один и тот же объект.
В то время, как при следующей последовательности вычислений
1. >>> a = 1000 2. >>> b = 550 + 450 имена a и b будут ссылаться на разные объекты.
REPL
Скрипт
>>> a = 100
>>> b = 55 + 45
>>> id(a), id(b)
(1342269254224, 1342269254224)
>>> a = 1000
>>> b = 550 + 450
>>> id(a), id(b)
(1342341491280, 1342341490800) a = 100 b = 55 + 45 print(id(a), id(b)) a = 1000 b = 550 + 450 print(id(a), id(b))
2037007603152 2037007603152 2037013785168 2037013785168
Функция print выводит переданные ей значения на экран через пробел.
Это объясняется тем, что при запуске интерпретатора CPython создаются объекты для значений в диапазоне [-5; 256], так как считается, что это наиболее часто используемые значения. Такой подход позволяет не тратить время на выделение памяти для них. Аналогично кэшируются при первом использовании строковые значения, состоящие из букв, цифр и символов подчеркивания длиной до 20 символов.
При запуске же скрипта целиком происходит кеширование всех используемых неизменяемых объектов. Эта процедура относится к оптимизации использования памяти и в данном разделе не рассматривается. Данный факт можно проверить с помощью функции id(var_name), которая возвращает адрес объекта, на который ссылается переменная var_name.
Открытый учебник по информатике. Программирование на Python. Основы
27
1 2 3 4 5 6 7 8
Открытый учебник по информатике. Программирование на Python. Основы
15
Побитовые операции
Применяются для обработки целых чисел в двоичном представлении.
Операция
Обозначение Пример использования
Побитовое отрицания
a
5 # -6
Побитовое умножение a & b
13 & 10 # 8
Побитовое сложение a | b
13 | 6 # 15
Побитовое исключающее или a ^ b
13 ^ 6 # 11
Побитовое отрицание производит инвертирование бит, в том числе бита, отвечающего за знак [3]. Поэтому в результате получается значение –(a+1).
Сокращенная запись
Для действий, направленных на изменение значения переменной относительно текущего значения могут применяться сокращенные операторы.
Операция
Обозначение Эквивалент
Сложение a += e a = a + e
Вычитание a -= e a = a - e
Умножение a *= e a = a * e
Деление a /= e a = a / e
Целочисленное деление a //= e a = a // e
Остаток от деления a %= e a = a % e
Побитовое умножение a &= e a = a & e
Побитовое сложение a |= e a = a | e
Побитовое исключающее или a ^= e a = a ^ e
Сокращенные операторы выполняются всегда в самом конце, после вычисления выражения справа от оператора.
Открытый учебник по информатике. Программирование на Python. Основы
16
Приоритет выполнения операций
В любом выражении можно задавать порядок выполнения операций с помощью скобок. В остальных случаях нужно знать, в каком порядке выполняются операции в выражении.
Приоритет выполнения операций следующий
Операция
**
*, /, //, %
+, -
&
|
^
==, !=, <, <=, >, >= not and or
Говоря иначе, чем выше операция в таблице, тем раньше она выполняется.
Если несколько операций записаны в одной строке, то они имеют одинаковый приоритет. При наличии их в одном выражении, выполняются они слева направо, то есть в первую очередь выполняется самая левая одноприоритетная операция.
Пример (рис.4-5)
Рисунок 5. Порядок выполнения операций в выражении
Рисунок 6. Расстановка приоритета операций с помощью скобок
Стоит заметить, что почти все операции являются лево ассоциативными, то есть при совпадении приоритета у соседних операций сначала выполняется операция, которая левее, затем правая.
Единственное исключение – операция возведения в степень, являющаяся право ассоциативной.
Например, запись a**b**c будет вычисляться, как ????
????
????
, а не как (????
????
)
с
Открытый учебник по информатике. Программирование на Python. Основы
17
Ввод и вывод данных
Для коммуникации с программным кодом при запуске программы, в программу вставляют специализированные функции – ввода и вывода.
Чтобы программа обработала какое-либо значение, его необходимо ввести.
Сделать это можно по-разному – считать из файла, запросить у сервиса в интернете или просто ввести через терминал.
Разберем самый простой случай.
Ввод значения через терминал.
Для этого в Python есть функция input().
Функция input() возвращает поступившее через терминал сообщение до переноса строки.
ВАЖНО: результатом работы функции input() является строковое значение.
Поэтому если нужно ввести число, то считанное строковое значение необходимо преобразовать с помощью соответствующей функции преобразования – int() или float().
Пример – ввод целого числа из терминала.
# ввод строки из терминала inp = input()
# преобразование введенной строки в целевое значение x = int(inp)
Также данную операцию можно выполнить в одну строку, передав результат выполнения функции input() на вход функции для преобразования. x = int(input())
Для интерактивности можно в качестве аргумента функции input привести приветственную строку. Например, «Input x: ». x = int(input('Input x:'))
Открытый учебник по информатике. Программирование на Python. Основы
18
Вывод значений на экран
Для вывода сообщений на экран используется функция print().
Функция принимает на вход значения или имена переменных через запятую, которые необходимо вывести. Строго говоря, данная функция имеет ряд настроек, которые нужны для корректировки формата вывода. Однако на данном этапе для нас хватит и уже описанного функционала.
Пример – вывод через пробел значений переменных a и b. print(a, b)
Пример простой программы для нахождения корня линейного уравнения
kx+b = 0.
# ввод коэффициента k k = float(input('Input k:'))
# ввод коэффициента b b = float(input('Input b:'))
# вычисление корня x = -b / k
# вывод корня на экран print('x =', x)
Условный оператор
Условный оператор – конструкция, управляющая цепочкой вычислений, которая позволяет выбрать ОДИН ИЗ n вариантов дальнейшего выполнения алгоритма.
Говоря на языке примеров, у нас есть n возможных вариантов вычислений, чтобы для каждого из них реализовать различные алгоритмы мы применяем конструкцию «если вариант1, то делаем1, иначе если вариант2, делаем2, …, иначе если вариантN то делаемN, во всех не перечисленных случаях
делаем(N+1)».
Условный оператор является первым из рассматриваемых в этом учебнике составным оператором. Составным он называется, потому что состоит из нескольких частей – ключевых слов (if, elif else) и блоков команд, выполняемых при истинности одного из условия (про блоки команд подробнее ниже).
Подробную документацию по этому и другим операторам можно найти в официальной документации [4] или в неофициальном русском переводе [5].
Открытый учебник по информатике. Программирование на Python. Основы
19
Условный оператор можно представить, как условный_оператор ::= "if" условие ":" блок команд
("elif" условие ":" блок команд)*
["else" ":" блок команд]
В представленной нотации запись (…)* означает, что на этом месте может быть 0 или больше выражений, описанных в скобках, […] – может быть 0 или
1 выражение описанного в скобках формата.
Говоря иначе, допустимы, например, такие использования условный_оператор ::= "if" условие1 ":" блок команд 1
Или
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"elif" условие3 ":" блок команд 3
Или
условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"else" ":" блок команд 3
Или
условный_оператор ::= "if" условие1 ":" блок команд "else" ":" блок команд 2
Самая важная особенность – условный оператор выбирает не более одного блока команд, который будет выполнен. В случае, если ни одно условие не выполняется и не задана секция else, условный оператор не перейдет ни к какому блоку команд и передаст управление команде, следующей сразу после последнего блока команд, описанного в условном операторе.
ВАЖНО. Условия проверяются в той последовательности, в которой они указаны в последовательности блоков elif.
Например, следующие обобщенные алгоритмы не являются эквивалентными:
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие2 ":" блок команд 2
"elif" условие3 ":" блок команд 3
Условный_оператор ::= "if" условие1 ":" блок команд 1
"elif" условие3 ":" блок команд 3
"elif" условие2 ":" блок команд 2
Открытый учебник по информатике. Программирование на Python. Основы
20
Если мы нумеруем условия в порядке их указания в составном условном операторе, то логика проверки условий и, соответственно, выбора блока команд будет следующая:
Если выполняется условие1, то выполняем блок команд 1 и завершаем работу условного оператора, иначе, если выполняется условие 2, то выполняем блок команд 2 и завершаем работу условного оператора, …, если не выполняется ни одно условия, выполняем блок команд, указанный после else (если блок указан) либо завершаем работу условного оператора (если блок команд для else не указан).
Данный процесс можно представить в виде блок схемы (рис.7).
Рисунок 7. Схематическое изображение работы условного оператора
В случае отсутствия секции блока else программа не выполнит ничего во время работы условного оператора, когда ни одно из условий не будет истинным
(блок команд N+1 будет отсутствовать). Если в условном операторе не будет блоков elif, то условный оператор выполнит блок команд 1, если условие выполняется, и блок команд N+1, если не выполняется. Когда же нет ни блоков
elif, ни блока else, алгоритм выполнит блок команд 1, если условие истинно, и не выполнит ничего, если условие ложно.
Открытый учебник по информатике. Программирование на Python. Основы
21
Блоки команд
В языке Python доступно два варианта оформления блоков команд в составных операторах, в том числе и условном операторе.
1) На той же строке, что и ключевые слова – if, elif и else для условного оператора – через точку с запятой.
Пример: if x % 2 == 0: y = y +x; z = 10 else: y = 0; z = 13 2) Каждая команда с новой строки и уровнем отступа на 1 больше, чем у ключевых слов if, elif и else
Тот же пример: if x % 2 == 0: y = y +x z = 10 else: y = 0 z = 13
Второй способ считается общепринятым и соответствует официальным рекомендациям по оформлению кода PEP-8 [1].
В чем же заключается идея такого формата.
Все блоки команд в составном операторе являются вложенными. Чтобы показать уровень вложенности для блока команд в таком операторе увеличивают отступ относительно ключевого слова. Также очень важно, чтобы все дальнейшие составные команды использовали аналогичное количество пробелов в качестве отступа.
Чтобы не считать каждый раз пробелы принято устанавливать отступы с помощью знака табуляции (кнопка Tab на клавиатуре, обычно, над Caps Lock).
Команды одного уровня вложенности в рамках одного составного оператора должны иметь одинаковый отступ от начала строки.
Строго говоря, Python не запрещает делать разные отступы для обособленных составных операторов. Однако, такой подход противоречит рекомендациям
PEP-8 и усложняет поддержку написанного кода.
Открытый учебник по информатике. Программирование на Python. Основы
22
Для иллюстрации приведем два примера – с разными отступами и с одинаковыми. Данные примеры наглядно показывают удобство применения рекомендации PEP-8 для оформления блоков команд.
Пример 1 (разные отступы) if x % 2 == 0: y = y + x if y > 5: y = 6 if x // 3 == 4: y = 0 if x > 10: z = 22
Пример 2 (одинаковые отступы) if x % 2 == 0: y = y + x if y > 5: y = 6 if x // 3 == 4: y = 0 if x > 10: z = 22
Тернарная условная операция
Для удобства в некоторых случаях используют тернарную условную операцию. Обычно, она используется, когда в зависимости от условия устанавливает значение конкретной переменной.
Пример (в формате обычного условного оператора): if y > 10: x = 5 else: x = y + 3
Пример (с помощью тернарной условной операции): x = 5 if y > 10 else y + 3
Тернарную условную операцию удобно применять, когда условие небольшое и выражение, которое присваивается, в обоих случаях получается по простому алгоритму. Иначе анализ тернарной условной операции становится гораздо сложнее и увеличивает сложность поддержки кода. В качестве маркера
«понятного» выражения можно использовать, например, рекомендации Дзен
Python [6] и не делать строки длиной более 79 символов.
Открытый учебник по информатике. Программирование на Python. Основы
23
Запуск и трассировка программы
Мы подходим к практике. Точнее пока что больше к попыткам запустить написанную программу и исследовать, как она работает. Для этого нам нужен, собственно, сам интерпретатор и самый простой инструмент для написания кода – IDLE [7].
После скачивания установочного файла по ссылке и его установки у нас появляется доступ к IDLE (обычно это ярлык в меню «Пуск»). Открываем его и компьютер готов к экспериментам.
После запуска появляется окно Python Shell, здесь ты можешь покомандно вводить программу и смотреть, что получается. В рамках данного параграфа нас интересует возможность запускать написанные программы (скрипты).
Для этого нужно наш код оформить в виде файла.
Алгоритм действий:
1) File -> New file (или Ctrl+N)
2) Пишем код, который хотим запустить
3) Сохраняем написанный код в файл (важно делать перед каждым запуском)
4) Запускаем (Run -> Run module или F5)
Теперь мы умеем создать файл с программой и запустить его. После запуска мы можем проанализировать вывод нашей программы. Например, результат может быть как на рис.8.
Рисунок 8. Запуск простой программы и результат
Открытый учебник по информатике. Программирование на Python. Основы
24
Инструмент Debug
Однако при разработке нашего алгоритма мы можем допустить логические ошибки в коде, в связи с чем наш код будет делать не то, что мы хотим.
Отследить поведение программы с помощью вывода промежуточных вычислений с помощью функции print, конечно, можно. Но такой метод может оказаться весьма неудобным, если мы имеем дело, например, с многострочной программой или циклом с большим количеством повторов.
Неудобный он в первую очередь из-за возможно длинного вывода и неудобства анализировать таковой.
Поэтому для пошагового анализа работы программы используют специализированные средства отладки – отладчики, также именуемые дебагерами (от de – отрицание действия, bug – программная ошибка [8]).
Для запуска Debug-режима в IDLE необходимо выбрать в меню
Debug -> Debugger. Теперь при запуске скрипта код будет выполняться по одной инструкции при нажатии на кнопку Step, и по одной строке при нажатии на кнопку Over.
Режим Step выполняет все инструкции внутри вызываемых методов, поэтому анализ хода выполнения программы получается существенно длиннее. Over же работает построчно и позволяет в ускоренном режиме проанализировать работу написанного кода.
В нижней области окна отладчика можно контролировать значения переменных на текущем этапе
Рисунок 9. Окно дебагера IDLE
Область 1 – панель управление ходом выполнения программы.
Открытый учебник по информатике. Программирование на Python. Основы
25
Go – продолжить выполнение до конца,
Step – выполнить следующую команду,
Over – выполнить текущую строку,
Out – выполнить текущую функцию до конца (предполагает, что сейчас отладчик находится внутри функции),
Quit – закончить работу отладчика.
Про функции мы поговорим в одной из следующих глав. На текущем этапе для нас наиболее полезные кнопки – Go и Over.
Область 2 – стек вызовов [9].
Область 3 – состояние памяти.
Здесь отображаются значения служебных переменных и тех, которые мы используем в ходе выполнения программы.
Для удобства анализа полезно поставить галочку на пункте Source, тогда в соседнем окне будет подсвечиваться текущая выполняемая строка (рис.10).
Рисунок 10. Пример отображения окна отладчика и исходного кода
Открытый учебник по информатике. Программирование на Python. Основы
26
Про объекты в памяти
Если начать писать программу в оболочке REPL для Python (REPL – read, eval,
print, loop), можно заметить одну особенность. Значения в диапазоне [-5; 256] будут иметь всегда один и тот же адрес для разных переменных, другие значения при их именовании будут иметь разные адреса для разных имен в случае совпадения значений.
Так, при попытке выполнить следующую последовательность команд,
1. >>> a = 100 2. >>> b = 55 + 45 имена a и b будут ссылаться на один и тот же объект.
В то время, как при следующей последовательности вычислений
1. >>> a = 1000 2. >>> b = 550 + 450 имена a и b будут ссылаться на разные объекты.
REPL
Скрипт
>>> a = 100
>>> b = 55 + 45
>>> id(a), id(b)
(1342269254224, 1342269254224)
>>> a = 1000
>>> b = 550 + 450
>>> id(a), id(b)
(1342341491280, 1342341490800) a = 100 b = 55 + 45 print(id(a), id(b)) a = 1000 b = 550 + 450 print(id(a), id(b))
2037007603152 2037007603152 2037013785168 2037013785168
Функция print выводит переданные ей значения на экран через пробел.
Это объясняется тем, что при запуске интерпретатора CPython создаются объекты для значений в диапазоне [-5; 256], так как считается, что это наиболее часто используемые значения. Такой подход позволяет не тратить время на выделение памяти для них. Аналогично кэшируются при первом использовании строковые значения, состоящие из букв, цифр и символов подчеркивания длиной до 20 символов.
При запуске же скрипта целиком происходит кеширование всех используемых неизменяемых объектов. Эта процедура относится к оптимизации использования памяти и в данном разделе не рассматривается. Данный факт можно проверить с помощью функции id(var_name), которая возвращает адрес объекта, на который ссылается переменная var_name.
Открытый учебник по информатике. Программирование на Python. Основы
27
1 2 3 4 5 6 7 8
Последовательности и итераторы
Последовательности
В Python есть так называемые типы-последовательности (Sequences).
Последовательность – общий термин, который предполагает упорядоченный набор данных. Говоря иначе, элементы в объекте-последовательности будут расположены в том же порядке, в котором будут добавлены, либо объявлены
(в зависимости от того, изменяемая последовательность или нет).
К последовательностям относят типы: str, list, tuple, bytes, bytesarray и range.
Обращение к элементам объекта последовательности происходит путем указания номера (индекса) элемента в последовательности. При этом элементы последовательности нумеруются от первого к последнему, начиная с нуля, или от последнего к первому в обратном порядке, начиная с -1.
Так, если последовательность S содержит 5 элементов, то обращение к S
3
эквивалентно обращению к S-
2
(рис.1).
Рисунок 1. Прямая и обратная нумерация в Python
Для обращения к элементу последовательности по индексу используется синтаксическая конструкция s[index], где s – последовательность, к элементу которой необходимо обратиться, index – индекс элемента в прямой или обратной нумерации.
При попытке выхода за границы последовательности (указание несуществующего индекса), интерпретатор вернет ошибку «IndexError:
выходит за допустимый диапазон».
ВАЖНО: допустимые индексы элементов последовательности всегда находятся в диапазоне [-len(seq); len(seq)-1], где len(seq) – количество элементов последовательности
Методы работы с каждым из перечисленных выше типов мы разберем подробнее чуть ниже. Сейчас же нам важно понимать, как обозначаются
(инициализируются) значения для данных типов.
Открытый учебник по информатике. Программирование на Python. Основы
28
Тип
Пример
Описание
Строка (str) s = '12345abcde'
Строка из 10 символов. s[0] – '1', s[1] – '2', …, s[9] – 'e'.
Кортеж (tuple) s = (1, 2, '123', 5) Неизменяемая последовательность из 4 объектов s[0] – 1, s[1] – 2, s[2] – '123', s[3] – 5.
Список (list) s = [5, 10, 'asd']
Изменяемая последовательность из 3 объектов s[0] – 5, s[1] – 10, s[2] – 'asd'.
Стоит заметить, что для создания пустой последовательности необходимо оставить незаполненным пространство между границами последовательности:
• s = '' для строки,
• t = () для кортежа,
• l = [] для списка.
Также надо помнить, что кортеж из одного элемента определяется несколько неочевидным образом. Так как при отсутствии нескольких значений в круглых скобках, записанное значение интерпретируется, как отдельный объект – результат выполнения операций в скобках.
Например, при записи x = (3) получим объект типа int со значением 3. То есть такие скобки считаются скобочными группами в выражении, так же как в выражении x = (25 – y) * 5. Ведь если бы это было не так, то подвыражение (25 – y) воспринималось бы как кортеж, что привело бы к неправильному результату при вычислении данного выражения.
Поэтому для формирования кортежа из одного элемента кортеж записывают как одноэлементный кортеж (singleton tuple) с помощью запятой, после которой не указывается следующий элемент. t = (1,) t = 1,
Строго говоря, также мы можем не указывать последний элемент и при инициализации списка. Однако, обычно в этом нет необходимости.
Открытый учебник по информатике. Программирование на Python. Основы
29
Общие функции, операторы и методы для последовательностей
Последовательности поддерживают ряд общих методов и операторов [10].
Метод
Обращение
Пример
Количество элементов len(seq) len('1234') #4 len([1,4,8]) #3
Конкатенация
(сложение) seq1 + seq2
'asd'+'123' #'asd123'
[5]+[1,3] #[5,1,3]
Повторение N раз seq*N
N*seq
'a'*4 # 'aaaa'
2*[4, 2]#[4, 2, 4, 2]
Проверка вхождения value value in seq
'4' in '123234'#True
'0' in '123' #False
Проверка
НЕвхождения value value not in seq
'1' not in '22'#True
'2' not in '22'#False
Количество вхождений value seq.count(value)
'12311'.count('1') #3
Индекс первого
(левого) элемента
value seq.index(value)
'12511'.index('5') #2
Максимальный элемент max(seq) max([5,2,10,2]) #10 max('12345asdfw')#'w'
Минимальный элемент min(seq) min([5,2,10,2]) #2 min('12345asdfw')#'1'
Сортировка элементов sorted(seq, reverse=True/False) sorted('bac')
# ['a', 'b', 'c']
Функция sorted всегда возвращает список элементов последовательности, поданной в качестве аргумента.
Важно, что при операциях поиска (count, index, in, not in) тип элемента value был совместим с объектом последовательности. Например, если мы производим поиск в строке, то нельзя в качестве искомого значения использовать любые значения, кроме строк.
При вызове методы index, если элемент отсутствует в последовательности, интерпретатор вернет ошибку «ValueError:
«Ошибка значения: значение отсутствует в последовательности».
Методы count, index и операторы in, not in для строки позволяют искать не только единичные символы, но и подстроки.
Открытый учебник по информатике. Программирование на Python. Основы
30
Примеры '15243'.index('2') # 2
'15243'.index('43') # 3
'12112'.count('1') # 3
'12112'.count('12') # 2
[1, 2, 3].index(2) # 1
[1, 2, 3].index([2, 3]) # ValueError
[1, 2, 3].count(3) # 1
[1, 2, 3].count([2, 3]) # 0
В примере
[1, 2, 3].index([2, 3]) получаем ValueError так как в списке нет ЭЛЕМЕНТА, содержащего список [2, 3]. В отличии от следующей записи
[1, 2, [3, 4]].index([3, 4]) # 2
Сравнение последовательностей
В общем случае последовательности сравниваются поэлементно. Сравнение допустимо только между последовательностями одного типа. При сравнении на равенство между различными типами последовательностей результатом будет ложь. При попытке сравнения порядка – ошибка несовместимости типов.
>>>a, b, c = ['1', '2'], ('1', '2'), '12'
>>>a == b
False
>>>b == c
False
>>>a > b
TypeError: '>' not supported between instances of 'list' and
'tuple'
Признак равенства – все элементы S соответствуют элементам F или s
i
= f
i
и
f
j
= s
j
для всех допустимых i и j. Говоря иначе последовательности F и S должны быть одинаковой длины и элемент, стоящий на позиции i в F, должен быть равен элементу на i-той позиции S.
Последовательности сравниваются лексикографически – слева направо. То есть операция сравнения применяется последовательно к элементам последовательности, начиная с самого левого (нулевого) элемента. И происходит до тех пор, пока либо не дойдет до конца обоих последовательностей (в случае равных последовательностей), либо не найдет отличия в одном из элементов. Если одна из последовательностей является началом другой, то последовательность большей длины считается последовательностью с бóльшим значением.
Пример.