Бесплатный курс по python. Зарегистрируйтесь для отслеживания прогресса →

Python: Комбинирование операций и функций

Логические операции — это выражения. Значит, логические операции можно комбинировать с другими выражениями.

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

  • если остаток 0, то число было чётным;
  • если остаток не 0, то число было нечётным.

Остаток от деления — простая, но очень важная концепция в арифметике, алгебре, и даже в теории чисел и криптографии. Идея проста: нужно разделить число на несколько равных групп, и если в конце что-то останется — это и есть остаток от деления.

Делим конфеты поровну между людьми:

  • 7 конфет, 2 человека: 2 x 3 + остаток 1. Значит, 7 не кратно 2.
  • 21 конфету, 3 человека: 3 x 7 + остаток 0. Значит, 21 кратно 3.
  • 19 конфет, 5 человек: 5 x 3 + остаток 4. Значит, 19 не кратно 5.

Оператор % вычисляет остаток от деления (не путайте с делением):

  • 7 % 21
  • 21 % 30
  • 19 % 54

С помощью него напишем функцию проверки чётности:

def is_even(number):
    return number % 2 == 0

print(is_even(10))  # => True
print(is_even(3))   # => False

В одном выражении мы скомбинировали логический оператор == (проверка равенства) и арифметический оператор %.

Приоритет арифметических операций выше логических. Значит, сначала вычисляется арифметическое выражение number % 2, затем результат участвует в логическом сравнении.

По-русски это можно расшифровать так: «вычислить остаток от деления числа number на 2 и сравнить, равен ли остаток нулю, затем вернуть результат проверки равенства».


Другой пример: напишем функцию, которая принимает строку и проверяет, начинается ли эта строка с латинской буквы a.

Алгоритм:

  1. Получим и запишем в переменную первый символ из строки-аргумента.
  2. Сравним, равен ли символ латинской букве a.
  3. Вернём результат.
def is_first_letter_an_a(string):
    first_letter = string[0]
    return first_letter == 'a'

print(is_first_letter_an_a('orange'))  # => False
print(is_first_letter_an_a('apple'))   # => True

Попробуйте проговорить происходящее по-русски, аналогично тому, как мы расшифровывали процесс в примере с is_even() в начале урока.


Напомним об извлечении символов из строки с помощью квадратных скобок:

first_name = 'Alexander'

first_name[0]  # 'A'
first_name[1]  # 'l'
first_name[2]  # 'e'
first_name[3]  # 'x'
first_name[4]  # 'a'
first_name[5]  # 'n'
first_name[6]  # 'd'
first_name[7]  # 'e'
first_name[8]  # 'r'

Задание

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

Вспомните способ отрезать от строки кусок заданной длины:

string[i:j]

Здесь i — порядковый номер (индекс) символа, начиная с которого будет производиться "обрезка" строки; j — индекс символа, перед которым отрезок должен закончиться. Длина отрезка составит j - i. Примеры:

print('Winterfell'[0:6])  # => 'Winter'
print('Stark'[0:6])       # => 'Stark'

# берём отрезок, начиная с символа с индексом 2
# и заканчивая символом с индексом 4
# (т.е. "перед символом с индексом 5")
print('Absolute'[2:5])  # => 'sol'

# начиная с символа с индексом 3
# и не доходя до символа с индексом 3,
# берём пустой отрезок (3 - 3 == 0)
print('Absolute'[3:3])  # => ''

(во втором примере 'Stark'[0:6]) символов получилось меньше, чем мы хотели, ведь в изначальной строке было меньше шести символов).

Есть укороченный синтаксис для этой операции, когда можно не указывать значение i:

string[:j]

В таком случае, по умолчанию подставляется значение 0 — то есть считается, что отрезок берётся от начала строки до символа с индексом j, не включая оный. Поэтому пару примеров выше мы можем переписать так:

print('Winterfell'[:6])  # => 'Winter'
print('Stark'[:6])       # => 'Stark'

И, естественно, вместо чисел можно использовать переменные:

n = 6
print('Winterfell'[:n])  # => 'Winter'
print('Stark'[:n])       # => 'Stark'

Реализуйте функцию has_targaryen_reference(), которая принимает на вход строку и проверяет, начинается ли она с Targaryen. Эта функция должна извлекать подстроку такой же длины, как и у слова Targaryen, а затем проверять, равна ли извлечённая подстрока строке Targaryen. Напомню, что индексы начинаются с нуля.

print(has_targaryen_reference(''))           # => False
print(has_targaryen_reference('Targari'))    # => False
print(has_targaryen_reference('targaryen'))  # => False
print(has_targaryen_reference('Targaryen'))  # => True

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе