#2. Булева алгебра. Управляющие конструкции

Булева алгебра. Управляющие конструкции.

enter image description here

План

  1. Тип bool
  2. Операторы
    1. Логические операторы
    2. Операторы сравнения
    3. Цепочки сравнений
    4. Операторы членства
    5. Операторы тождественности
    6. Условная конструкция if
  3. Приоритет операций

Тип bool

В программировании очень часто приходится сравнивать различные данные, и, в зависимости от результатов сравнения, определять несколько алгоритмов.
Результатом данных сравнений являются два значение: Истина или Ложь.

Специально для такого формата в Python есть логическтий тип данных bool, который содержит только два значения: True или False.

Название типа bool (в других языках тип часто называется как Boolean) получило в честь английского математика и логика Джорджа Буля, занимавшегося вопросами математической логики в середине XIX века.

enter image description here
Джордж Буль (англ. George Boole; 1815-1864) — английский математик, логик и философ. Профессор математики Королевского колледжа Корка (ныне Университетский колледж Корк). Один из основателей математической логики.

Операторы

Логические операторы

Для создания составных условных выражений применяются логические операции. В Python имеются следующие логические операторы:

and - И (логическое умножение)
and возвращает True, если оба выражения равны True

A B A and B
True True True
True False False
False True False
False False False
age = 22
weight = 58
result = age > 21 and weight == 58
print(result)  # True

В данном случае оператор and сравнивает результаты двух выражений: age > 21 и weight == 58. И если оба этих выражений возвращают True, то оператор and также возвращает True. Причем в качестве одно из выражений необязательно выступает операция сравнения: это может быть другая логическая операция или просто переменная типа bool, которая хранит True или False.

age = 22
weight = 58
isMarried = False
result = age > 21 and weight == 58 and isMarried
print(result)  # False, так как isMarried = False

or - ИЛИ (логическое сложение)

Возвращает True, если хотя бы одно из выражений равно True

A B A or B
True True True
True False True
False True True
False False False
age = 22
isMarried = False
result = age > 21 or isMarried
print(result)  # True, так как выражение age > 21 равно True

not - НЕ (логическое отрицание)

A not A
True False
False True

Возвращает True, если выражение равно False

age = 22
isMarried = False
print(not age > 21)  # False
print(not isMarried)  # True

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

Аналогично если один из операндов оператора or возвращает True, то второй операнд не оценивается, так как оператор в любом случае возвратит True.

Операторы сравнения

enter image description here

Для сравнения данных используют операторы сравнения. Результатом сравнений является ответ типа bool - True или False.

ОператорОписаниеПримеры
== Проверяет равны ли оба операнда. Если да, то условие становится истинным. 5 == 5 в результате будет True
True == False в результате будет False
'hello' == 'hello' в результате будет True
!= Проверяет равны ли оба операнда. Если нет, то условие становится истинным. 12 != 5 в результате будет True
False != False в результате будет False
'hi' != 'Hi' в результате будет True
> Проверяет больше ли значение левого операнда, чем значение правого. Если да, то условие становится истинным. 5 > 2 в результате будет True.
True > False в результате будет True.
'A' > 'B' в результате будет False.
< Проверяет меньше ли значение левого операнда, чем значение правого. Если да, то условие становится истинным. 3 < 5 в результате будет True.
True < False в результате будет False.
'A' < 'B' в результате будет True.
>= Проверяет больше или равно значение левого операнда, чем значение правого. Если да, то условие становится истинным. 1 >= 1 в результате будет True.
23 >= 3.2 в результате будет True.
'C' >= 'D' в результате будет False.
<= Проверяет меньше или равно значение левого операнда, чем значение правого. Если да, то условие становится истинным. 4 <= 5 в результате будет True.
0 <= 0.0 в результате будет True.
-0.001 <= -36 в результате будет False.

Цепочки сравнений

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

x < y <= z
# эквивалентно 
x < y and y <= z

В примере выше y вычисляется только один раз. Если x < y оказывается ложным, то в обоих случаях, приведенных выше z не оценивается вообще.

Еще пример:

a < b <= c < d
# эквивалентно 
a < b and b <= c and c < d

В такой форме сравнения легче читаются, и каждое подвыражение вычисляется по крайней мере один раз.

Операторы членства

В добавок к перечисленным операторам, в Python присутствуют, так называмые, операторы членства, предназначенные для проверки на наличие элемента в составных типах данных, таких, как строки, списки, кортежи или словари (о них поговорим на следующих занятиях):

ОператорОписаниеПримеры
in Возвращает истину, если элемент присутствует в последовательности, иначе возвращает ложь. 'cad' in 'cadillac' вернет True.
1 in [2,3,1,6] вернет True.
'hi' in {'hi':2,'bye':1} вернет True.
 2 in {'hi':2,'bye':1} вернет False (в словарях проверяется наличие в ключах, а не в значениях).
not in Возвращает истину если элемента нет в последовательности. Результаты противоположны результатам оператора in.

Операторы тождественности

Операторы тождественности сравнивают размещение двух объектов в памяти компьютера.

ОператорОписаниеПримеры
is Возвращает истину, если оба операнда указывают на один объект. x is y вернет истину, если id(x) будет равно id(y).
is not Возврашает ложь если оба операнда указывают на один объект. x is not y, вернет истину если id(x) не равно id(y).

Условная конструкция if

Условные конструкции используют условные выражения и в зависимости от их значения направляют выполнение программы по одному из путей. В Python это конструкция if. Она имеет следующее формальное определение:

if логическое_выражение:
    инструкции
[elif логическое выражение:
    инструкции]
[else: 
    инструкции]

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

language = 'english'
if language == 'english':
    print('Hello')
print('End')

Поскольку в данном случае значение переменной language равно ‘english’, то будет выполняться блок if, который содержит только одну инструкцию - print('Hello'). В итоге консоль выведет следующие строки:

Hello
End

Обратите внимание в коде на последнюю строку, которая выводит сообщение End. Она не имеет отступов от начала строки, поэтому она не принадлежит к блоку if и будет выполняться в любом случае, даже если выражение в конструкции if возвратит False.

Но если бы мы поставили бы отступы, то она также принадлежала бы к конструкции if:

language = 'english'
if language == 'english':
    print('Hello')
    print('End')

Блок else

Если вдруг нам надо определить альтернативное решение на тот случай, если выражение в if возвратит False, то мы можем использовать блок else:

language = 'russian'
if language == 'english':
    print('Hello')
else:
    print('Привет')
print('End')

Блок elif

enter image description here
Если необходимо ввести несколько альтернативных условий, то можно использовать дополнительные блоки elif, после которого идет блок инструкций.

language = 'german'
if language == 'english':
    print('Hello')
    print('World')
elif language == 'german':
    print('Hallo')
    print('Welt')
else:
    print('Привет')
    print('мир')

Сначала Python проверяет выражение if. Если оно равно True, то выполнениются инструкции из блока if. Если это условие возвращает False, то Python проверяет выражение из elif.

Если выражение после elif равно True, то выполняются инструкции из блока elif. Но если оно равно False то выполняются инструкции из блока else

При необходимости можно определить несколько блоков elif для разных условий. Например:

language = 'german'
if language == 'english':
    print('Hello')
elif language == 'german':
    print('Hallo')
elif language == 'french':
    print('Salut')
else:
    print('Привет')

Вложенные конструкции if

Конструкция if в свою очередь сама может иметь вложенные конструкции if:

language = 'russian'
daytime = 'morning'
if language == 'english':
    if daytime == 'morning':
        print('Good morning')
    else:
        print('Good evening')
else:
    if daytime == 'morning':
        print('Доброе утро')
    else:
        print('Добрый вечер'))

Альтернативный синтаксис if, замена тернарному оператору

Во многих языках программирования (С++, Java, PHP…) существуют тернарный оператор, т.е. специальный оператор условия, который возвращает один из двух результатов, в зависимости от того, выполняется его условие или нет. Выглядит он так:

print ($input == 1) ? 'One!' : 'Not One!';

Тернарные операторы часто применяются, когда варианта всего два, так как такая запись короче аналогичного действия с if. Однако, к сожалению, можно встретить связку if-ов и тернарных операторов, которую совершенно невозможно прочесть. Другими словами, это не необходимая вещь в языке и она может стать причиной нечитаемого текста.

В Python нет тернарного оператора, но есть возможность его имитировать при помощи if:

test = True
result = 'Test is True' if test else 'Test is False'
# result = 'Test is True'

Это можно использовать с любыми функциями, как и с печатью:

test = True
print ('ttt' if test else 'fff') # выведет ttt

Особенности сравнения объектов

В языке Python все является объектом. Когда мы говорим о числе, строке, функции. классе, списке и т.д. - мы говорим об объекте.

Python считает, что если объект не пуст, он True, а не False. False - это собственно сам False, 0 и пустая строка ''. Таким образом если нам необходимо сравнить строку с пустой строкой, или число с нулем, а так же узнать, является ли пустым тот или иной объект, вместо того, чтобы писать условия в стиле старых языков:

if s !='':
    pass
    
if 8 % 2 != 0:
    pass

можно слегка их сократить:

if s:
    pass
    
if 8 % 2:
    pass

Это значительно сокращает и упрощает код.

Еще одна альтернатива тернарному оператору

Применение and к нескольким выражениям не просто возвращает True или False. Оно возвращает первое False-выражение, либо последнее из выражений, если все они True.

Аналогично, операция or возвращает первое True-значение, либо последнее, если ни одно из них не True.

Используя вышеописанную особенность Python, можно реализовать тернарный оператор еще более оригинальным образом:

test = True
result = test and 'Test is True' or 'Test is False'

В нашем случае test == True, т.е. and его пропускает и возвращает нам последнее из истинных значений, с которым работал, т.е. выражение Test is True or Test is Falseor возвращает первое встреченное True выражение, ему больше ничего не интересно. Если заменить строки приблизительным смыслом и использовать псевдокод, получим что-то вида:

result = true1 and true2 or true3
result = true2 or true3
result = true2

Что касается приоритета операций, not приоритетнее and, and приоритетнее or. Т.е. сначала выполняется not, потом and, потом or.

Приоритет операций

ОперацияОписание
( )Скобки – высший приоритет – первые
**Экспонента (возведение в степень)
+x, -x, ~xУнарные плюс, минус и битовое отрицание
*, /, //, %Умножение, деления, взятие остатка
+, -Сложение и вычитание
<<, >>Битовые сдвиги
&Битовое И
^Битовое исключающее ИЛИ (XOR)
|Битовое ИЛИ
==, !=, >, >=, <, <=,
is, is not,
in, not in
Сравнение, проверка идентичности,
проверка вхождения
notЛогическое НЕ
andЛогическое И
orЛогическое ИЛИ
if – elseКонструкция if – else
=Присвоение – низший приоритет – последние

Практика

  1. Проверить, является ли введеное число четным.
    int(input())
  2. Проверить, является ли введеное число нечетным, делится ли на 3 и на 5 без остатка одновременно, но так, чтобы не делилось на 10 .

Полезные ссылки

  1. 📖 Операторы в Python
  2. 📖 Приоритеты операций в Python

Домашнее задание

  1. Завершить практики, начатые на уроке.
  2. Проверить, является ли введеное число високосным годом или нет
  3. Написать программу для проверки надежности введеного пароля.
    • Пароль должен иметь длину len(str) не менее 6 символов
    • Содержать такие буквы: F, K, и D или С
    • Не должен содержать цифры 1 и 6
    • Если в пароле есть #, то должна быть буква а