Условные операторы

Содержание лекции:

1. Условные операторы

2. Циклы

3. Функции

Запись третьего занятия вы можете посмотреть по этой ссылке.


1. Условные операторы

Оператор if

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

Условный оператор if ("если") является основным оператором проверки выполнения условия. Для того, чтобы выполнить простую вложенную инструкцию, необходимо проверить условие на соответствие, использовав оператор if и прописав после него соответствующее условие:

 # объявляем переменную

var = 5

# выполняем проверку условия

if var < 10:

# если условие выполняется, то выполняется вложенная инструкция

    print("var less than 10")


В данном случае мы объявляем переменную var и присваиваем ей значение равное 5, далее выполняем проверку условия - если переменная меньше 10, то вывести соответствующее сообщение.

Оператор if производит проверку истинности выражения, т.е. является ли результат выражения логической истиной (True) или же ложью (False). Далее выполняется вложенная инструкция, если результат выражения является True. Если результат выражения является False, тогда вложенная инструкция игнорируется. В предыдущем разделе приводились примеры того, что выводит Python в качестве результата выражения с оператором сравнения.

Оператор else

Оператор if позволяет выполнить вложенную инструкцию, если результат выражения True, а что, если нам необходимо, чтобы программа могла выполнять действия и в случае False результата? Для этого мы можем использовать оператор else. Условный оператор else ("иначе") является продолжением основной инструкции. 

# объявляем переменные

var_1 = 10

var_2 = 9

# выполняем проверку условия

if var_1 == var_2:

# если True

    print("var_1 equal var_2")

# иначе

else:

# выполняется другая вложенная инструкция

    print("var_1 not equal var_2")

Как показано в примере выше, мы задаем переменной var_1 значение равное 10, а переменной var_2 значение 9, затем производим сравнение наших переменных на равенство, если var_1 равно var_2, тогда следует вывести сообщение, что они равны, иначе, вывести сообщение, что переменные не равны. Таким образом, оператор else позволяет выполнить инструкцию print("var_1 not equal var_2") в случаях, когда результат проверки на равенство является False.

Оператор elif

В предыдущем примере мы рассматривали ситуацию, когда нас интересовало всего 2 возможные ситуации - равно, не равно. А что, если для решения определенной задачи нас интересует более двух возможных ситуации? Для этого предусмотрен оператор elif (сокращение от конструкции else if), который позволяет добавить дополнительные условия в логику выполнения программы:

# объявляем переменные

var_1 = 10

var_2 = -10

# выполняем проверку условия

if var_1 == var_2:

# если True

    print("var_1 equal var_2")

# иначе если выполняется другое условие

elif var_1 < var_2:

# если True для elif

    print("var_1 less than var_2")

# если False для всех

else:

    print("var_1 more than var_2")

Здесь мы объявляем переменные var_1 и var_2 и присваиваем значения 10 и -10 соответственно, после этого выполняем проверку первого условия, равны ли эти переменные, если они равны, то выводим соответствующее сообщение. Если они не равны, то пытаемся понять, какая из этих переменных больше. Выполняется проверка второго условия (elif), если var_1 меньше var_2, тогда выводим соответствующее сообщение, и наконец, остается последний вариант, который и выводит сообщение о том, что var_1 больше чем var_2.

Главное, на что стоит обратить внимание - после использования конструкций if и elif всегда необходимо записывать условие проверки (в нашем случае var_1 == var_2 и var_1 < var_2 соответственно), а else всегда используется без условий, потому что означает выполнение инструкции при любых других вариантах, которые не были рассмотрены операторами if и elif.

Количество конструкций elif может быть множество, тогда, как if и else используются по 1 разу в рамках одной инструкции:

if (условие):

    (выполнение условия)

elif (другое условие):

    (выполнение другого условия)

elif (третье условие):

    (выполнение третьего условия)

elif (четвертое условие):

...

...

...

else:

    (выполнение при всех других не рассмотренных ранее случаях)

Стоит обратить внимание, что в случае, когда вы используете оператор if несколько раз на одном уровне вложенности инструкций, то они работают независимо друг от друга и не образуют одну общую инструкцию:

var = 10

if var == 10:

    print("var equal 10")

if var < 10:

    print("var less than 10")

else:

    print("var more than 10")

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

var equal 10

var more than 10

Оператор if всегда задает начало новой инструкции. В примере выше переменная var попадает на проверку в несколько инструкций, сперва мы получаем результат True в выражении var == 10, после чего выводится первое сообщение. Далее var опять проверяется следующей инструкцией, получается результат False и программа выводит второе сообщение, после оператора else. Давайте для наглядности построим блок-схему данной программы:

В данном случае будет корректно заменить второй if на elif, тогда мы получим единую инструкцию, которая выведет только одно верное сообщение:

var = 10

if var == 10:

    print("var equal 10")

elif var < 10:

    print("var less than 10")

else:

    print("var more than 10")

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

Конструкции if-elif-else можно использовать на разных уровнях вложенности для более сложных программ:

if (условие):

    if (дополнительное условие):

        (выполнение дополнительного условия)

    elif (другое дополнительное условие):

         (выполнение другого дополнительного условия)

    elif ...

         ... 

    ...

    else: 

         ...

elif (другое условие):

    (выполнение другого условия)

elif ... 

     ...

else: 

     ...

2. Циклы

Циклы это специальные выражения, которые позволяют выполнять часть кода несколько раз, если оно того требует. Циклы очень полезны в программировании, поскольку это позволяет не прописывать вручную одну и ту же операцию несколько раз. Допустим нам надо вывести на экран 13 чисел от 1 до 13, как бы это выглядело без циклов:

print(1)

print(2)

print(3)

print(4)

print(5)

print(6)

print(7)

print(8)

print(9)

print(10)

print(11)

print(12)

print(13)

Несколько утомительно. Давайте посмотрим далее что можно с этим сделать, применив циклы. В языке Python есть несколько видов циклических выражений.

Цикл while

Самый простой вид циклов, выполняет инструкцию в блоке до тех пор, пока условие не станет ложным.

# создаем переменную, равную 1

var = 1

# прописываем цикл с условием - выполнять до тех пор, пока переменная

# меньше или равна 13

while var <= 13:

# выводим значение переменной

    print(var)

# увеличиваем переменную на 1

    var += 1


Памятка
Необходимо всегда помнить, что при использовании цикла while, нужно следить за тем, чтобы было прописано условие выхода из цикла. Если бы в примере выше мы не увеличивали переменную var на 1, тогда цикл бы стал бесконечным, и программа бы выполнялось до тех пор, пока не закончится память компьютера.

Давайте представим цикл while в виде блок схемы для наглядности: 

В нашем случае мы реализуем цикл while с помощью комбинации условие + действие. Действие будет повторяться до тех пор, пока не выполнится условие. Из схемы видно, что если мы уберем блок действия var=var+1 , то наше условие не будет выполнено никогда и цикл будет бесконечным.

Цикл for

Цикл for менее универсальный, но работает быстрее, чем цикл while. Он способен проходить по любому итерируемому объекту, будь то списки, словари, кортежи, строки и не требует ручного увеличения счетчика итераций:

for i in [1, 2, 3, 4, 5 ,6 ,7 ,8 ,9 , 10, 11, 12, 13]:

    print(i)

В примере выше написана программа с использованием цикла for. Мы указываем, что наша вложенная инструкция print(i) должна выполняться для каждого элемента из массива [1, 2, 3, 4, 5 ,6 ,7 ,8 ,9 , 10, 11, 12, 13]. То есть данный цикл описывает конструкцию:

i =1 

print(i)

i =2 

print(i)

i =3 

print(i)

...

i = 13

print(i)

В нашем примере все равно отсутствует элегантность, присущая языку Python. Давайте попробуем что-нибудь сделать с массивом из 13 чисел. Что если нам понадобится выводить 100 или 100000 чисел? Для этих целей применим функцию range(), которая поможет нам автоматически сгенерировать последовательность чисел.

>>> var = range(1, 14)

>>> print(var)

range(1, 14)

>>> print(var[0])

1

>>> print(var[1])

2

>>> print(var[12])

13

>>> print(var[14])

Traceback (most recent call last):

  File "<pyshell#77>", line 1, in <module>

    print(var[14])

IndexError: range object index out of range

Мы присвоили переменной значение выражения range(1,14), после того, как мы решили вывести содержимое переменной var, обнаружилось, что в ней заложено это выражение - range(1, 14). Как говорилось ранее, range это особый тип, который содержит в себе последовательность данных. Чтобы это показать, выполним команду print(var[0]), которая выводит содержимое переменной, стоящей в 0 ячейке памяти. Ячейки памяти берут отсчет с 0, поэтому на 12 позиции будет храниться число 13, как видно из примера. Тем самым мы видим, что переменная var содержит в себе последовательность чисел от 1 до 13. Но как быть с 14 позицией, ведь в команде range() второй параметр у нас равен 14? Особенность range() состоит в том, что последнее число последовательности не включается в нее, то есть мы говорим, что нам надо сформировать последовательность чисел от 1 до 14, не включая 14. Функция range() работает так, потому что чаще всего используется для работы с  индексами, отсчет которых начинается с 0.


Вернемся к циклу for. Теперь мы можем написать нашу программу максимально компактно:

for i in range(1,14):

    print(i)

В принципе, цикл for можно также изображать на блок-схемах, как и цикл while. Важно помнить, что увеличение счетчика и его начальное значение заложено внутри оператора for и его не надо прописывать отдельно.

Оператор continue

Оператор continue позволяет начать следующий проход цикла, минуя оставшиеся инструкции:

for var in 'Python':

    if var == 'h':

        continue

    print(var)

На примере выше мы перебираем последовательность символов и когда наша переменная хранит в себе символ 'h', мы используем оператор continue, чтобы пропустить дальнейшую инструкцию print(var).

На блок-схеме выше представлена ситуация, когда используется оператор continue. В текстовой сноске примерно описан вариант реализации цикла for. Основное, на что стоит обратить внимание, это красная линия, которая переводит на блок for без каких-либо действий.

Оператор break

Оператор break досрочно прерывает цикл. Повторите пример ниже и посмотрите, что получится.

for var in 'Python':

    if var == 'h':

        break

    print(var)


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

Оператор else

Оператор else проверяет цикл на экстренный выход (break). Если экстренного выхода не было, т.е. оператор break не был выполнен, блок инструкций вложенный в оператор else - выполняется.

for var in 'Python':

    if var == 'a':

        break 

else:

    print('Символа a нет в слове Python')

Операторы continue, break и else работают с циклами for и while.

3. Функции

Функции в Python это объекты, принимающие аргументы и возвращающие значение. Функции определяются с помощью инструкции def:

 def sum(x, y):

    return x + y

Функции позволяют упаковывать часть кода для его последующего повторного вызова. В примере выше определена функция с именем sum, которая принимает два параметра x и y, и возвращает результат их суммы. Обратившись к этой функции по имени и задав параметры, мы можем получить результат:

>>> sum(34, 12)

46

>>> sum('abc', 'def')

'abcdef'

Инструкция return позволяет вернуть значение, которое нам необходимо. Это необходимо для того, чтобы получить определенный результат и затем дальше использовать его в программе.

Функция может быть любой сложности, внутри конструкции def -> return, мы можем написать любой код. Смысл в функциях заключается в том, чтобы не писать один и тот же код повторно, а просто, в нужный момент, вызывать заранее написанную функцию. Так же функция может быть без параметров или может не возвращать какое-то конкретное значение или не заканчиваться инструкцией return вовсе:

def fun():

    var = 'Python'

    if len(var) >= 6:

        print(var)

return                       # В этом случае функция вернет значение None

Код под инструкцией def будет относиться к функции до тех пор, пока он вложен в эту инструкцию, то есть отступает от def.

Функции бывают разных типов:

  • Глобальные функции - такие функции доступны из любой части кода файла, в котором они написаны. Глобальные функции доступны из других модулей, но об этом мы расскажем в разделе "Подключение модулей".

# Объявляем функцию

def solve(s):

   

    c = []

    for i in range(len(s)-1):

        if i == 0 or i%2 == 0:

            c.append(s[i])

    return c

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

print(solve([1, 2, 3, 4, 5, 6, 7, 8]))

  • Локальные функции - функции, объявленные внутри других функций. Вызвать их можно только внутри функции, в которой они объявлены. Их удобно использовать, если необходима небольшая вспомогательная функция, которая больше нигде не используется.
  • Лямбда-функции - особые, анонимные функции, имеющие ряд ограничений, по сравнению с обычными функциями. Они локально решают единственную задачу. Применение такой функции выглядит, как выражение, давайте посмотрим на примере:

# Обычная функция

def search_len(arg_1):

    return len(arg_1)


# Лямбда-функция

result = lambda x: len(x)

Обычно, лямбда-функции применяют при вызове функций, которые в качестве аргументов содержат функции. Проблема использования лямбда-функций состоит в том, что иногда усложняется читаемость кода.

 >>> func = lambda x, y: x + y

>>> func(1, 2)

3

>>> func('a', 'b')

'ab'

>>> (lambda x, y: x + y)(1, 2)

3

>>> (lambda x, y: x + y)('a', 'b')

'ab'

Лямбда-функции не имеют имени, поэтому могут возникать проблемы с отловом ошибки. В рамках данного курса мы не будем более подробно останавливаться на данном виде функций и рекомендуем использовать стандартный, более явный тип.

  • Методы - функции, работающие в связке с тем типом данных, который ассоциирован с данной функцией. В прошлых разделах приводились примеры методов для каждого типа. Более подробный разбор методов является частью объектно-ориентированного программирования и не входит в рамки данного курса.

Функции могут принимать произвольное количество аргументов, для этого необходимо поставить символ * перед именем аргумента функции:

>>> def func(*args):

      return args

>>> func(1, 2, 3, 'abc')

(1, 2, 3, 'abc')

Как мы видим в таком случае образуется кортеж из этих аргументов. Также можно принимать аргументы в виде словаря, для этого необходимо использовать символ **:

>>> def func(**kwargs):

         return kwargs

>>> func(a=1, b=2, c=3)

{'a': 1, 'c': 3, 'b': 2}

Очень важно документировать описание к любой функции, чтобы каждый раз не разбирать написанное заново. Для этого используют строки, заключенные в тройные кавычки. Поскольку описание функции зачастую состоит более, чем из 1 строки, использование строк с тройными кавычками очень удобно. Обычно под документирование выделяют место между определением функции и началом основного кода:

def solve(s):

    ''' Функция solve(s) принимает список

        создает пустой список   

        находит элементы с четным индексом (включая 0)

        заносит их в созданный список и возвращает его

    '''

    c = []

    for i in range(len(s)-1):

        if i == 0 or i%2 == 0:

            c.append(s[i])

    return c

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

var_1 = [1,2,3]

  

def func(a):

    var_1 = []

    for i in a:

        var_1.append(i*2)

    return var_1

print(func(var_1))

print(var_1)

Зеленым цветом обозначена глобальная переменная, красным - локальная. Глобальная переменная var_1 в данном случае остается неизменной, т.к. она используется только в качестве параметра для функции и нигде не происходит манипуляций над ней. Внутри этой функции изменения происходят с локальной переменной var_1. Результат выполнения такой программы будет следующий:

[2, 4, 6]

[1, 2, 3]

Теперь приведем пример плохого кода, в котором происходят манипуляции с глобальной переменной:

var_1 = [1,2,3]

  

def func(a):

    var_2 = []

    for i in a:

        var_2.append(i*2)

    return var_2

var_3 = var_1

var_3.append(12)

print(func(var_1))

print(var_1)

За счет того, что var_3 связывается с тем же объектом, что и var_1, то изменения над глобальной переменной var_3 приведет к изменению другой глобальной переменной  var_1. В итоге эта цепочка меняет результат выполнения функции, поскольку на вход подаются уже другие данные. Вот пример неосторожного обращения с глобальными переменными. А теперь представьте, что у вас сотни строк кода и десяток функций, можете представить сколько времени понадобится на поиск подобной ошибки?

Практические задания:

Задание 1:
Дано натуральное число. Требуется определить, является ли год с данным номером високосным. Если год является високосным, то выведите YES, иначе выведите NO. Напомним, что в соответствии с григорианским календарем, год является високосным, если его номер кратен 4, но не кратен 100, а также если он кратен 400.
Задание 2:
Факториалом числа n называется произведение 1 × 2 × ... × n. Обозначение: n!.
По данному натуральному n вычислите значение n!. Пользоваться математической библиотекой math в этой задаче запрещено.
Задание 3:
Определите среднее значение всех элементов последовательности, завершающейся числом 0.
Задание 4:
Даны четыре действительных числа: x1, y1, x2, y2. Напишите функцию distance(x1, y1, x2, y2), вычисляющая расстояние между точкой (x1,y1) и (x2,y2). Считайте четыре действительных числа и выведите результат работы этой функции.

Домашнее задание 3:
Задание 3.1
Написать код, который бы решал заданное квадратное уравнение в виде: ax2 + bx + c = 0. На вход: a, b, c. На выходе - корни уравнения

Примеры уравнений:

3x2 - 14x - 5 = 0

9x2 - 6x + 1 = 0

4x2 + 8 = 0

x2 - 3,2x + 1,12 = 0

* алгоритм решения уравнения можно сделать в виде функции

Задание 3.2
По данному натуральном n вычислите сумму 1!+2!+3!+...+n!. Пользоваться математической библиотекой math в этой задаче запрещено.

Завершить и продолжить  
Обсуждение

0 Комментарии