Операция
Обозначение Пример использования
Отрицание 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