Python: Агрегация данных (Числа)
Отдельный класс задач, который не обходится без циклов, называется агрегированием данных. К таким задачам относятся поиск максимального или минимального значения, суммы, среднего арифметического. В их случае результат зависит от всего набора данных. В этом уроке разберем, как агрегация применяется к числам и строкам.

Допустим, нам нужно найти сумму набора чисел. Реализуем функцию, которая складывает числа в указанном диапазоне, включая границы. Диапазон представляет собой ряд чисел от конкретного начала до определенного конца. Например, диапазон [1, 10] включает целые числа от одного до десяти.
Пример:
sum_numbers_from_range(5, 7) # 5 + 6 + 7 = 18
sum_numbers_from_range(1, 2) # 1 + 2 = 3
# [1, 1] диапазон с одинаковым началом и концом тоже является диапазоном
# Он включает одно число — саму границу диапазона
sum_numbers_from_range(1, 1) # 1
sum_numbers_from_range(100, 100) # 100Чтобы реализовать такой код, понадобится цикл, так как сложение чисел является итеративным процессом, то есть повторяется для каждого числа. Количество итераций зависит от размера диапазона. Вот код этой функции:
def sum_numbers_from_range(start: int, finish: int) -> int:
# Технически можно менять start
# Но входные аргументы нужно оставлять в исходном значении
# Это сделает код проще для анализа
i = start
sum = 0 # Инициализация суммы
while i <= finish: # Двигаемся до конца диапазона
sum = sum + i # Считаем сумму для каждого числа
i = i + 1 # Переходим к следующему числу в диапазоне
# Возвращаем получившийся результат
return sumСтруктура цикла здесь стандартная. Есть счетчик, который инициализируется начальным значением диапазона, цикл с условием остановки при достижении конца диапазона и изменение счетчика в конце тела цикла. Количество итераций в таком цикле равно finish - start + 1. Для диапазона [5, 7] это 7 - 5 + 1, то есть три итерации.
Главное отличие от обычной обработки состоит в логике вычислений результата. В задачах на агрегацию всегда есть переменная, которая хранит внутри себя результат работы цикла. В коде выше это sum. На каждой итерации цикла к ней прибавляется следующее число в диапазоне: sum = sum + i.
Наглядно этот процесс выглядит следующим образом.
# Для вызова sum_numbers_from_range(2, 5)
sum = 0
sum = sum + 2 # 2
sum = sum + 3 # 5
sum = sum + 4 # 9
sum = sum + 5 # 14
# 14 — результат сложения чисел в диапазоне [2, 5]Наглядно процесс накопления суммы выглядит так.
sum_numbers_from_range(2, 5):
i=2: sum = 0 + 2 = 2
i=3: sum = 2 + 3 = 5
i=4: sum = 5 + 4 = 9
i=5: sum = 9 + 5 = 14
└── результатУ переменной sum есть начальное значение, с которого начинается любая повторяющаяся операция. В примере выше это 0. Почему так?
В математике есть понятие нейтральный элемент, и у каждой операции он свой. Операция с этим элементом не изменяет то значение, над которым работает. Например, в сложении любое число плюс ноль дает само число. При вычитании нейтральный элемент тот же: 0. У конкатенации нейтральным элементом является пустая строка: '' + 'one' будет 'one'. Поэтому если бы мы умножали, то вместо 0 использовали бы 1.
Задание
Реализуйте функцию calculate_electricity_bill(), которая принимает количество израсходованных киловатт-часов и возвращает сумму счета за электричество.
В этом задании действует ступенчатый тариф. Первые 100 кВт⋅ч стоят по 5 рублей, следующие 100 кВт⋅ч стоят по 7 рублей, а все кВт⋅ч сверх 200 стоят по 10 рублей.
Пройдите расход с помощью цикла и постепенно накопите итоговую сумму.
calculate_electricity_bill(80) # 400
calculate_electricity_bill(150) # 850
calculate_electricity_bill(250) # 1700Полезное
Ваше упражнение проверяется по этим тестам
import solution
def test1():
assert solution.calculate_electricity_bill(0) == 0
assert solution.calculate_electricity_bill(80) == 400
assert solution.calculate_electricity_bill(100) == 500
assert solution.calculate_electricity_bill(150) == 850
assert solution.calculate_electricity_bill(250) == 1700Решение учителя откроется через:
20:00
