В теле цикла, как и в теле функции, можно выполнять инструкции. Поэтому внутри цикла можно использовать все изученное ранее, например — условные конструкции.
Представьте функцию, которая считает, сколько раз входит буква в предложение. Пример ее работы:
count_chars('Fear cuts deeper than swords.', 'e') # 4
# Если вы ничего не нашли, то результат — 0 совпадений
count_chars('Sansa', 'y') # 0
Перед тем как посмотреть содержимое функции, подумайте:
def count_chars(string, char):
index = 0
count = 0
while index < len(string):
if string[index] == char:
# Считаем только подходящие символы
count = count + 1
# Счетчик увеличивается в любом случае
index = index + 1
return count
Это агрегирующая задача. Несмотря на то, что она считает не все символы, чтобы подсчитать сумму, приходится анализировать каждый символ. Ключевое отличие этого цикла от рассмотренных — внутри тела есть условие.
Переменная count
увеличивается только в том случае, когда рассматриваемый символ совпадает с ожидаемым. В остальном — это типичная агрегатная функция, которая возвращает количество нужных символов.
Функция my_substr()
, которую вы реализовали в прошлом уроке, содержит много ошибок. Она прошла проверку, так как в ней не было пограничных случаев. Функция работала с нормальными аргументами. А теперь представим, что ей передали такие варианты длины:
0
Функция my_substr()
не рассчитана на такие варианты. Код будет запускаться в разных ситуациях, с разными комбинациями условий и данных. Нельзя быть уверенным, что аргументы всегда будут корректными, поэтому нужно учитывать все случаи.
Ошибки в пограничных случаях — частая причина логических ошибок в программах. Программисты всегда забывают что-нибудь учесть. Такие ошибки часто проявляются не сразу и могут долго не приводить к видимым проблемам.
Программа продолжает работать, но в какой-то момент обнаруживается, что в результатах есть ошибки. Часто причина в динамической типизации Python.
Вы научитесь справляться с такими ошибками с опытом.
Представим расширенную функцию my_substr()
. Она принимает три аргумента: строку, индекс и длину извлекаемой подстроки. Функция возвращает подстроку указанной длины, начиная с указанного индекса. Примеры вызова:
string = 'If I look back I am lost'
print(my_substr(string, 0, 1)) # => 'I'
print(my_substr(string, 3, 6)) # => 'I look'
Какие пограничные случаи стоит учитывать:
Когда функция реализуется, каждый пограничный случай будет отдельным куском кода. Скорее всего, он будет реализовываться с помощью if
.
Чтобы написать функцию my_substr()
и защититься от этих случаев, стоит реализовать отдельную функцию, которая будет проверять аргументы на корректность.
Работа с циклами обычно сводится к двум сценариям:
Рассмотрим алгоритм проверки простоты числа. Будем делить искомое число x
на все числа из диапазона от двух до x - 1
и смотреть остаток. Если в этом диапазоне не найден делитель, который делит число x
без остатка, значит, перед нами простое число.
В этом случае достаточно проверять числа не до x - 1
, а до половины числа. Например, 11 не делится на 2, 3, 4, 5. Но и дальше не будет делиться на числа больше своей половины. Значит, можно оптимизировать алгоритм и проверять деление только до x / 2
:
def is_prime(number):
if number < 2:
return False
divider = 2
while divider <= number / 2:
if number % divider == 0:
return False
divider += 1
return True
print(is_prime(1)) # => False
print(is_prime(2)) # => True
print(is_prime(3)) # => True
print(is_prime(4)) # => False
Представим, что по алгоритму последовательного деления на числа до x / 2
нашлось одно, которое делит без остатка. Значит, переданный аргумент — не простое число, и дальнейшие вычисления не имеют смысла. В этом месте стоит возврат False
.
Если цикл отработал целиком, и не нашлось число, которое делит без остатка, значит, число — простое.
Вам ответят команда поддержки Хекслета или другие студенты.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт