$ sudo teach IT
Модуль 2 · Первые шаги · Урок 2.5

Числа и арифметика

Как Python считает, делит и округляет, и почему 10 / 2 выдаёт не совсем то, что вы ожидаете.

Теория~20 минутНовичок

Вы уже умеете хранить числа в переменных и выводить их на экран. Настоящая сила программы — в вычислениях: посчитать сдачу, разделить сумму на всех, перевести секунды в часы и минуты. Для этого в Python есть арифметические операторы, и у пары из них поведение отличается от привычного калькулятора. Разберёмся по порядку.

Арифметические операторы

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

Такой символ называется оператором, а числа, к которым он применяется, — операндами. В выражении 10 + 3 оператор — это +, а 10 и 3 — операнды. У Python есть все привычные операторы, плюс два не самых очевидных — // и %, о них дальше.

+
Сложение
Складывает два числа.
−
Вычитание
Вычитает второе число из первого.
*
Умножение
Перемножает числа.
/
Деление
Делит, результат всегда дробный.
Особенность Python 3. Оператор / всегда возвращает дробное число (float), даже если результат делится без остатка. Это сознательное решение авторов языка, чтобы тип числа не зависел от того, ровно поделилось или нет.
a = 10
b = 3

print(a + b)   # 13
print(a - b)   # 7
print(a * b)   # 30
print(a / b)   # 3.3333333333333335
print(10 / 2)  # 5.0
a = 10 и b = 3 — две переменные с числами, дальше используем их вместо того, чтобы каждый раз писать числа заново.
print(a + b) — складывает значения переменных: 10 + 3 даёт 13.
print(a / b) — делит 10 на 3. Ровно не делится, поэтому Python выводит длинную дробь.
print(10 / 2) — деление ровное, но результат всё равно 5.0: точка после числа показывает, что это float, а не int.

Целочисленное деление и остаток

Представьте, что вы делите 7 кусков пиццы на 2 человек поровну. Целых кусков каждому достанется по 3, а один останется — резать его пополам никто не будет. Именно эту задачу — «сколько целых» и «что осталось» — решают два оператора.

Целочисленное деление (//) возвращает только целую часть результата, отбрасывая всё после запятой. Остаток от деления (%, читается как «модуло») возвращает то, что осталось после такого деления.

kuskov = 7
lyudej = 2

kazhdomu = kuskov // lyudej
ostatok = kuskov % lyudej

print(kazhdomu)   # 3
print(ostatok)    # 1
kuskov // lyudej — делит 7 на 2 и оставляет только целую часть: 3. Дробная часть отбрасывается, округления здесь нет.
kuskov % lyudej — считает, что осталось после того, как разложили по 3 куска каждому: 7 − 3*2 = 1.

Частый случай — перевести общее число секунд в часы, минуты и секунды. Здесь // и % применяются несколько раз подряд, каждый раз к остатку от предыдущего шага:

total = 3725

chasy = total // 3600
ostatok = total % 3600
minuty = ostatok // 60
sekundy = ostatok % 60

print(f"{chasy}ч {minuty}мин {sekundy}сек")   # 1ч 2мин 5сек
chasy = total // 3600 — в часе 3600 секунд, целочисленное деление даёт число полных часов: 1.
ostatok = total % 3600 — секунды, не влезшие в целые часы: 3725 − 3600 = 125.
minuty = ostatok // 60 — тот же приём для минут: сколько целых минут в 125 секундах — 2.
sekundy = ostatok % 60 — то, что не влезло в минуты: 125 − 120 = 5.
f"{chasy}ч {minuty}мин {sekundy}сек" — f-строка подставляет все три значения в одну строку для вывода.

Возведение в степень

Когда нужно умножить число само на себя несколько раз — например, посчитать площадь квадрата — писать x * x * x неудобно и легко сбиться со счётом. Для этого есть отдельный оператор.

Возведение в степень в Python записывается как ** (две звёздочки подряд). Слева стоит число, которое возводим в степень, справа — сама степень. Степень может быть и дробной — тогда ** считает корень.

print(2 ** 10)     # 1024
print(3 ** 3)      # 27
print(9 ** 0.5)    # 3.0
2 ** 10 — 2, умноженное само на себя 10 раз: 1024.
3 ** 3 — куб числа 3, то есть 3 * 3 * 3: 27.
9 ** 0.5 — степень 0.5 означает «извлечь квадратный корень»: получаем 3.0, потому что 3 * 3 = 9.

Сокращённая запись: +=, -=, *=

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

Это оператор присваивания с операцией. Запись x += 5 означает то же самое, что x = x + 5: взять текущее значение x, прибавить 5 и записать результат обратно в x. Так же работают -= (вычесть и присвоить) и *= (умножить и присвоить).

score = 0
score += 10
score += 10
score *= 2

print(score)   # 40

balance = 1000
balance -= 250
print(balance)   # 750
score = 0 — начальное значение счёта.
Первая score += 10 — было 0, стало 10. Вторая — добавляем ещё 10 к уже изменённому значению: стало 20.
score *= 2 — то же, что score = score * 2: было 20, стало 40.
balance -= 250 — то же, что balance = balance - 250: было 1000, стало 750.

Готовые функции для чисел

Раньше вы уже пользовались функциями round(), abs(), max() и min() — разберём их подробнее применительно к числам. Напомним: функция — готовый блок кода с именем, который делает одно действие, если передать ему данные (аргументы). У round() есть необязательный второй аргумент — сколько знаков после запятой оставить.

print(round(3.14159, 2))   # 3.14
print(round(3.7))          # 4
print(abs(-7))             # 7
print(max(3, 8, 1))        # 8
print(min(3, 8, 1))        # 1
round(3.14159, 2) — второй аргумент 2 говорит: оставить два знака после запятой — получаем 3.14.
round(3.7) — без второго аргумента округляет до целого: 4.
abs(-7) — убирает знак минус: 7.
max(3, 8, 1) и min(3, 8, 1) — наибольшее и наименьшее из перечисленных чисел: 8 и 1.

Модуль math: готовые формулы

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

Чтобы им воспользоваться, в начале программы пишут import math — команда «подключи модуль math». После неё доступна, например, константа math.pi — число π (примерно 3.14159), уже посчитанное с высокой точностью.

import math

radius = 5

length = 2 * math.pi * radius
area = math.pi * radius ** 2

print(round(length, 2))   # 31.42
print(round(area, 2))     # 78.54
import math — первая строка программы, подключает модуль. Без неё math.pi использовать нельзя.
math.pi — точка означает «внутри модуля math возьми значение с именем pi».
length = 2 * math.pi * radius и area = math.pi * radius ** 2 — школьные формулы длины окружности и площади круга, записанные кодом Python.
В задачах этого урока модуль math уже подключён за вас первой строкой — используйте math.pi так же, как в примере выше.

Частые ошибки

Перепутать / и //. Новички ждут от / целый результат, если числа делятся ровно, и удивляются лишней точке.
print(10 / 5)    # 2.0, а не 2 — это float
print(10 // 5)   # 2 — это int
Деление на ноль. И /, и //, и % вызывают ошибку, если второй операнд равен нулю.
a = 10
b = 0
print(a / b)
# ZeroDivisionError: division by zero
Банковское округление. round(2.5) возвращает 2, а не 3, хотя в школе учили округлять «половинку» вверх. Python округляет к ближайшему чётному числу — это снижает накопленную ошибку при многократных округлениях.
print(round(2.5))   # 2, ближайшее чётное
print(round(3.5))   # 4, ближайшее чётное

Что важно запомнить

  • Оператор / в Python всегда возвращает дробное число (float), даже если делится без остатка. Для целого результата используйте //.
  • // даёт целую часть от деления, % — остаток. Вместе они разбивают число на «целых частей» и «что осталось».
  • ** — возведение в степень. Дробная степень считает корень: x ** 0.5 — квадратный корень из x.
  • +=, -=, *= — короткая запись, чтобы изменить значение переменной, не повторяя её имя дважды.
  • round() округляет к ближайшему чётному числу на «половинках» — это не баг, а осознанное поведение Python.
  • Модуль math подключается строкой import math и даёт готовые математические константы вроде math.pi.
  • Деление на ноль всегда останавливает программу ошибкой ZeroDivisionError — проверяйте делитель заранее.

Проверьте себя

3 вопроса

Длина окружности и площадь круга

Используя модуль math (он уже подключён в заготовке) и константу math.pi, вычислите длину окружности и площадь круга для радиуса 5. Результаты округлите до 2 знаков после запятой и выведите.

Пример вывода:

31.42
78.54

Конвертер секунд

Дано общее количество секунд total = 7384. Используя операторы // и %, разбейте это значение на часы, минуты и секунды. Выведите результат в формате Ч:М:С.

Пример вывода:

2:3:4