Ветвление. Условный оператор
Ход выполнения программы может быть линейным, то есть таким, когда выражения выполняются друг за другом, начиная с первого и заканчивая последним. Ни одна строка кода программы не пропускается.
Однако чаще в программах бывает не так. При выполнении кода, в зависимости от тех или иных условий, некоторые его участки могут быть опущены, в то время как другие – выполнены. Иными словами, в программе может присутствовать ветвление, которое реализуется условным оператором – особой конструкцией языка программирования.
Проведем аналогию с реальностью. Человек живет по расписанию. Можно сказать, расписание – это алгоритм для человека, его программный код, подлежащий выполнению. В расписании на 18.00 стоит поход в бассейн. Однако экземпляр биоробота класса Homo sapiens через свои рецепторы-сенсоры получает информацию, что воду из бассейна слили. Разумно было бы отменить занятие по плаванию, то есть изменить ход выполнения программы-расписания. Одним из условий посещения бассейна должно быть его функционирование, иначе должны выполняться другие действия.
Подобная нелинейность действий может быть реализована в компьютерной программе. Например, часть кода будет выполняться лишь при определенном значении конкретной переменной. В языках программирования используется приблизительно такая конструкция условного оператора:
Перевести на человеческий язык можно так: если логическое выражение возвращает истину, то выполняются выражения внутри фигурных скобок; если логическое выражение возвращает ложь, то код внутри фигурных скобок не выполняется. С английского «if» переводится как «если».
Конструкция if логическое_выражение называется заголовком условного оператора. Выражения внутри фигурных скобок – телом условного оператора. Тело может содержать как множество выражений, так и всего одно.
Пример использования условного оператора в языке программирования Python:
В Питоне вместо фигурных скобок используется двоеточие. Обособление вложенного кода, то есть тела оператора, достигается за счет отступов. В программировании принято делать отступ равным четырем пробелам. Можно использовать клавишу табуляции ( Tab ) на клавиатуре.
Большинство сред программирования автоматически создают отступ, как только вы поставите двоеточие и перейдете на новую строку. Однако при работе в интерактивном режиме отступы надо добавлять вручную.
Нахождение в теле условного оператора здесь обозначается тремя точками. При создании файла со скриптом таких точек быть не должно, как и приглашения >>> .
Python считается языком с ясным синтаксисом и легко читаемым кодом. Это достигается сведением к минимуму таких вспомогательных элементов как различные скобки и точка с запятой. Для разделения выражений используется переход на новую строку, а для обозначения вложенных выражений – отступы от начала строки. В других языках данный стиль программирования также используется, но лишь для удобочитаемости кода человеком. В Питоне же такой стиль возведен в ранг синтаксического правила.
Данный пример вырван из контекста и сам по-себе не является рабочим. Полная версия программы могла бы выглядеть так:
a = 50 b = 10 n = 98 if n 100: a = a + b print(a)
Последняя строчка кода print(a) уже не относится к условному оператору, что обозначено отсутствием перед ней отступа. Она не является вложенной в условный оператор, значит, не принадлежит ему.
Поскольку переменная n равна 98, а это меньше 100, то a станет равной 60. Это значение будет выведено на экран. Если переменная n изначально была бы связана, например, со значением 101, то на экран было бы выведено 50. Потому что при n , равной 101, логическое выражение в заголовке условного оператора вернуло бы ложь. Значит, тело не было бы выполнено, и переменная a не изменилась бы.
Структуру программы можно изобразить следующим образом:
Основная ветка программы выполняется всегда, а вложенный код лишь тогда, когда в темно-зеленой строчке, обозначающей заголовок условного оператора, случается истина.
Для небольших программ иногда чертят так называемые блок-схемы, отражающие алгоритм выполнения. В языке блок-схем различные части кода обозначаются своими фигурами. Так блоку последовательно выполняемых действий соответствует прямоугольник, ветвлению – ромб. Для кода выше блок-схема может выглядеть так:
Условный оператор может включать не одну ветку, а две, реализуя тем самым полноценное ветвление.
В случае возврата логическим выражением False поток выполнения программы не возвращается сразу в основную ветку. На случай False существует другой вложенный код, отличный от случая True . Другими словами, встретившись с расширенной версией условного оператора, поток выполнения программы не вернется в основную ветку, не выполнив хоть какой-нибудь вложенный код.
В языках программирования разделение на две ветви достигается с помощью добавления блока else, получается так называемое if–else (если-иначе). Синтаксис выглядит примерно так:
if логическое_выражение < выражение 1; выражение 2; … >else
Если условие при инструкции if оказывается ложным, то выполняется блок кода при инструкции else . Ситуация, при которой бы выполнились обе ветви, невозможна. Либо код, принадлежащий if , либо код, принадлежащий еlse . Никак иначе. В заголовке else никогда не бывает логического выражения.
Пример программы с веткой else на языке Python:
tovar1 = 50 tovar2 = 32 if tovar1 + tovar2 > 99: print("99 рублей недостаточно") else: print("Чек оплачен")
Следует иметь в виду, что логическое выражение при if может выглядеть нестандартно, то есть не так просто, как a > b и тому подобное. Там может стоять просто одна переменная, число, слово True или False , а также сложное логическое выражение, когда два простых соединяются через логически and или or .
Если вместо знака вопроса будет стоять 0, то с логической точки зрения это False , значит выражение в if не будет выполнено. Если a будет связано с любым другим числом, то оно будет расцениваться как True , и тело условного оператора выполнится. Другой пример:
Здесь a уже связана с булевым значением. В данном случае это True . Отметим, что в выражении a = 5 > 0 присваивание выполняется после оператора сравнения, так что подвыражение 5 > 0 выполнится первым, после чего его результат будет присвоен переменной a . На будущее, если вы сомневаетесь в последовательности выполнения операторов, используйте скобки, например так: a = (5 > 0) .
if a > 0 and a b: print(b - a)
Тут, чтобы вложенный код выполнился, a должно быть больше нуля и одновременно меньше b . Также в Питоне, в отличие от других языков программирования, позволительна такая сокращенная запись сложного логического выражения:
Практическая работа
- Напишите программу, которая просит пользователя что-нибудь ввести с клавиатуры. Если он вводит какие-нибудь данные, то на экране должно выводиться сообщение «ОК». Если он не вводит данные, а просто нажимает Enter , то программа ничего не выводит на экран.
- Напишите программу, которая запрашивает у пользователя число. Если оно больше нуля, то в ответ на экран выводится число 1. Если введенное число не является положительным, то на экран должно выводиться -1.
Примеры решения и дополнительные уроки в pdf-версии курса
Python. Введение в программирование
Осваиваем Python. Унция 2. Ветвления, циклы + практика.
Простые конструкции в языке Python: ветвления и циклы имеют свои особенности по сравнению с другими языками. Поэтому я всё же решил потратить на это время и рассказать. Материал совсем простой!
Так же по просьбам читающих добавил в конец статьи разбор простой программки для наглядной демонстрации пройденного материала.
Условная инструкция if
if условие1: блок1 elif условие2: блок2 else: блок3
Существует так же краткая форма записи (аналог тернарного оператора в Си):
Заменяет собой конструкцию вида:
if условие: X = A else: X = B
Перехват исключений
try: блок 1 # интерпретатор пытается выполнить блок1 except (name1,name2): блок 2 # выполняется, если в блоке try возникло исключение name1 или name2 except name3: блок 3 # выполняется, если в блоке try возникло исключение name3 except: блок 4 # выполняется для всех остальных возникших исключений else: блок 5 # выполняется, если в блоке try не возникло исключения finally: блок 6 # выполнится всегда
Конструкция else была добавлена к инструкции обработки исключений для того, чтобы мы могли разделить ситуации, не прибегая к использованию флагов, когда выполнение программы продолжилось из-за того, что исключений в блоке try не возникло, или же они были перехвачены и обработаны.
Конструкция else в языке Python так же добавлена и в циклы
Цикл while
while условие: блок1 else: # необязательная часть else блок2 # выполняется, если выход из цикла был произведён не инструкцией break
break — осуществляет выход за пределы цикла
continue — осуществляет переход в начало цикла (к строке заголовка)
Цикл for
for in : блок1 if условие: continue else: break блок2 # не выполнится никогда, учитывая инструкцию if else: блок3 # выполнится, если выход из цикла не осуществлялся инструкцией break
>>> L = [(5,5),(6,6)] >>> for (x,y) in L: # присваивание кортежа в цикле for . print x,y, # вывод без добавления символа конца строки . 5 5 6 6
Рассмотрим типичную задачу поиска общих элементов двух списков. Её можно решить абсолютно разными путями, например, с помощью множеств, но в данном случае нас интересует решение с помощью вложенных циклов for.
for elem1 in list1: for elem2 in list2: if elem1 == elem2: print elem1, u'элемент найден' break else: print elem1, u'не был найден'
Однако, эту задачу можно решить с помощью только одного цикла for, благодаря использованию оператора in:
for elem in list1: print (elem,'found') if elem in list2 else (elem,'not found')
В данном случае оператор in сам осуществляет обход списка и поиск элемента. Этот вариант решения будет работать быстрее, чем первый. Поэтому во всех случаях, когда это возможно — лучше стараться пользоваться уже описанными конструкциями языка.
Близкая тема к циклам в языке Python — это понятие итератора. И очень кстати, что эта тема была описана сегодняшним же числом на хабре. Некоторые описанные в ней моменты я использовал при написании практического примера, специально для это статьи. Например функцию enumerate() Вообще тенденция единовременного появления большого количества русскоязычного материала по Питону — очень позитивная!
Практика
Условие задачи: построить график изменения курса заданных валют за заданный период времени от текущей даты.
- словарь, ключами которого являются названия валют, а значениями — идентификаторы валют определённые ЦБ.
- количество интересующих нас месяцев
- ширина картинки
- высота картинки
Реализация:
Результат работы:
Описание:
- список, содержащий значения курса валют по дням
- минимальное значение в списке
- максимальное значение в списке
Так же внутри функции используется конструкция try/except. В том случае, если получить документ с сервера ЦБ не удалось, или на вход функции были переданы неверные значения — функция parse() выбросит исключение и после этого логика программы перейдёт к обработчику исключений except, где наша функция возвратит объект None.
Цикл for j,key in enumerate(currency.keys()): в теле функции drawCurrency() осуществляет обход словаря валют. Для каждой из них вызывает функцию getData(), генерируется случайным образом цвет отображения курса валюты на графике, а так же определяется минимальное и максимальное значение курса среди всех переданных на вход валют.
После этого осуществляется последовательная отрисовка графиков каждой из валют.
Если требуется пояснение каких-то моментов — я отвечу в комментариях. В следующей статье cleg планировал углублённо раскрыть тему функций, однако, учитывая параллельное появление статей — не могу пока знать станет ли он это делать. Становится всё интереснее и интереснее ))