В логическом (булевом) типе данных имеется 2 значения: True («правда») и False («ложь»). Детальное описание этого типа дано в стандарте PEP-285.
Класс bool – это подкласс типа int (т.е. целых чисел). True и False – синглтон-объекты, которые по ходу выполнения программы никогда не меняют место расположения в памяти.
К логическим объектам можно применять математические операции. Есть 3 типа логических операторов: not («не»), or («или»), and («и»).
Операции с логическим типом данных обладают свойствами: коммутативность, дистрибутивность, ассоциативность; к ним применимо правило де Моргана.
Задача 1. Базовый уровень
Условие
Напишите функцию dislike_6(a), которая всегда возвращает True, если только не передается число 6 типа int или типа float (в данном случае она вернет «Только не 6!»).
Вначале проверяем, является ли аргумент целым или вещественным числом. Если это так и он равен 6 или 6.0, то вернем «Только не 6!» Во всех остальных случаях результат представлен в виде True.Решение – IDE
def dislike_6(a):
if (type(a) is float or type(a) is int) and a == 6.0:
return 'Только не 6!'
return True
# Тесты
print(dislike_6(6.0))
print(dislike_6(6))
print(dislike_6('6'))
print(dislike_6('Хорошо'))
print(dislike_6([6, 6]))
Результат выполнения
Только не 6!
Только не 6!
True
True
True
Задача 2. Базовый уровень
Условие
Изучающий язык Python студент постоянно путается в свойствах логических операций (ассоциативность, дистрибутивность, коммутативность, правило де Моргана).
Он решил написать функцию-подсказку help_bool(letter), которая принимает одну из 4 букв: к, а, д, м (соответствующую каждому свойству).
Результат выполнения: определенное правило работы в виде строки.
Если будет передано что-то иное, то вернется подсказка-строка с пояснением по каждому возможному аргументу.
Охарактеризуем каждое правило:
– Коммутативность (к)
A or B = B or A
A and B = B and A
– Дистрибутивность (д)
A and (B or C) == (A and B) or (A and C)
A or (B and C) == (A or B) and (A or C)
– Ассоциативность (а)
A or (B or C) == (A or B) or C == A or B or C
A and (B and C) == (A and B) and C == A and B and C
– Теорема Де Моргана (м)
not (A or B) == not A and not B
not (A and B) == not A or not B
not (A < B) == A >= B
not (not (A)) = A
Если пользователь забудет нужный аргумент, то дадим ему подсказку:
Возможные аргументы: к – Коммутативность, д – Дистрибутивность, а – Ассоциативность, м – Теорема Де Моргана. Можем даже принудительно задать параметр по умолчанию, который без верного аргумента будет возвращать подсказку.
Решение — IDE
def help_bool(letter=None):
if letter == 'к':
return 'A or B = B or A\nA and B = B and A'
elif letter == 'а':
return 'A or (B or C) == (A or B) or C == A or B or C\n' \
'A and (B and C) == (A and B) and C == A and B and C'
elif letter == 'д':
return 'A and (B or C) == (A and B) or (A and C) \nA or (B and C) == (A or B) and (A or C)'
elif letter == 'м':
return 'not(A or B) == not A and not B \nnot(A and B) == not A or not B\n'\
'not(A < B) == A >= B\nnot(not(A)) = A'
else:
return 'Возможные аргументы: к – Коммутативность, д – Дистрибутивность, а – Ассоциативность, ' \
'м – Теорема Де Моргана'
# Тесты
print(help_bool())
print(help_bool([2, 6]))
print(help_bool('к'))
Результат выполнения
Возможные аргументы: к – Коммутативность, д – Дистрибутивность, а – Ассоциативность, м – Теорема Де Моргана
Возможные аргументы: к – Коммутативность, д – Дистрибутивность, а – Ассоциативность, м – Теорема Де Моргана
A or B = B or A
A and B = B and A
Задача 3. *Продвинутый уровень
Условие
Дано 2 скрипта. В первом – возникает ошибка, во втором – ошибки нет.
Поясните почему.
Скрипт 1.
a = None
if len(a) > 0 and a is not None:
print('OK')
Скрипт 2.
a = None
if a is not None and len(a) > 0:
print('OK')
Применение оператора and к выражениям останавливается тогда, когда обнаруживается первое ложное значение. None – ложное значение, поэтому оно сразу возвращается, без вычисления второй половины выражения во втором скрипте.
В первом же примере мы пытаемся найти длину None, а такого свойства у значения нет. Поэтому возникает ошибка.
Решение – IDE
a = None
if a is not None and len(a) > 0:
print('OK')
a = 'Нет ошибок'
if a is not None and len(a) > 0:
print('OK')
Результат выполнения
– первое выражение будет проигнорировано
– второе выражение напечатает 'OK'.
Решение – IDE
a = None
if len(a) > 0 and a is not None:
print('OK')
Результат выполнения
TypeError (ошибка типа).
Задача 4. *Продвинутый уровень
Условие
После изучения темы «Логический тип в Python» перед учеником стала задача написать функцию divider(a, b), принимающую любые 2 числовых параметра.
Задача функции: разделить a на b.
Если в знаменателе введут ноль, то результат будет следующим: «Нули в знаменателе не приветствуются».
В противном случае выводится итог деления чисел, возведенный в куб.
Решите задание без использования условия if, применяя свойства логических операторов.
Для решения задачи необходимо вспомнить о свойствах операторов and, or.
Если решать задание «в лоб», то оно очень простое.
Решение – IDE
def divider(a, b):
if b == 0:
return 'Нули в знаменателе не приветствуются'
return (a / b) ** 3
Однако требуется не использовать условия.Решение – IDE
def divider(a, b):
return b and (a / b) ** 3 or 'Нули в знаменателе не приветствуются'
# Тесты
print(divider(10, 4))
print(divider(10, 0))
print(divider(-12.2, 2))
print(divider(-6.4, 0))
Результат выполнения
15.625
Нули в знаменателе не приветствуются
-226.98099999999997
Нули в знаменателе не приветствуются