💻 Примеры: арифметические выражения

← К оглавлению урока

⚡ Минимальный набор

a, b = 7, 3
print(a / b, a // b, a % b, a ** b)   # 2.333... 2 1 343

x = 5
x += 3            # то же, что x = x + 3
print(x)          # 8

print(int("10"), float("3.14"), str(10), bool(0))
ОператорЧто делаетПримерРезультат
/Деление, всегда float8 / 24.0
//Целая часть, округление вниз-7 // 2-4
%Остаток от деления7 % 31
+= и др.Составное присваиваниеx += 3то же, что x = x + 3
int()/float()Явное преобразование строки в числоint("10")10
Топ-3 ошибки: делить на ноль (ZeroDivisionError) · забыть int()/float() для input() · думать, что num + 3 без присваивания меняет num.

Примеры идут от простого к сложному: сами операторы и их приоритет, деление и его варианты, ошибки времени выполнения, неизменяемость чисел, виды присваивания и явные преобразования типов. Весь вывод в комментариях получен запуском кода.

Пример 1. Операторы для 7 и 3

Семь базовых арифметических операторов на одной паре чисел.

# 01_operations.py
a = 7
b = 3

print("Сложение:", a + b)              # 10
print("Вычитание:", a - b)             # 4
print("Умножение:", a * b)             # 21
print("Деление:", a / b)               # 2.3333333333333335
print("Целочисленное деление:", a // b)  # 2
print("Остаток:", a % b)               # 1
print("Степень:", a ** b)              # 343

Что происходит: / всегда возвращает float, даже когда числа делятся нацело. // и % — парные операции: a == b * (a // b) + a % b.

Пример 2. Приоритет операций

Python считает выражения по обычному математическому приоритету: скобки → степень → умножение/деление////% → сложение/вычитание.

# 02_precedence.py
print(5 + 3 * 2)          # 11  — сначала умножение
print((5 + 3) * 2)        # 16  — скобки меняют порядок
print(2 * 3 ** 2)         # 18  — сначала степень: 3**2=9, потом *2
print(10 / 2 * 3)         # 15.0 — при равном приоритете считаем слева направо
print(2 + 3 * 2 ** 2 - 1) # 13

Почему так: при одинаковом приоритете (например, / и *) Python вычисляет выражение слева направо, поэтому 10 / 2 * 3 — это (10 / 2) * 3, а не 10 / (2 * 3).

Пример 3. Деление, типы результата и отрицательные числа

Тип результата зависит от операндов, а целочисленное деление отрицательных чисел округляет не к нулю, а вниз.

# 03_division_types.py
print(8 / 2, type(8 / 2))      # 4.0 <class 'float'>
print(8 // 2, type(8 // 2))    # 4   <class 'int'>
print(8 // 2.0, type(8 // 2.0))# 4.0 <class 'float'>

print(-7 // 2)   # -4, а не -3
print(-7 % 2)    # 1

Почему так: если хотя бы один операнд — float, результат // тоже становится float. Отрицательное -7 // 2 даёт -4, потому что // округляет результат вниз (к минус бесконечности), а не отбрасывает дробную часть — это частая неожиданность, если ожидать поведения как в языках с усечением к нулю.

⚠️ Проверить по документации: точное определение целочисленного деления — Binary arithmetic operations.

Пример 4. ZeroDivisionError

Деление, целочисленное деление и остаток от деления на ноль — все три вызывают исключение.

# 04_zero_division.py
for expr in ["10 / 0", "10 // 0", "10 % 0"]:
    try:
        eval(expr)
    except ZeroDivisionError as error:
        print(f"{expr} -> ZeroDivisionError: {error}")
# 10 / 0 -> ZeroDivisionError: division by zero
# 10 // 0 -> ZeroDivisionError: integer division or modulo by zero
# 10 % 0 -> ZeroDivisionError: integer modulo by zero

Что происходит: без обработки исключения такая строка аварийно останавливает программу. Проверка знаменателя перед делением — тема условных конструкций из следующих уроков.

Пример 5. Числа — неизменяемый тип

Выражение num + 2 без присваивания не меняет num: Python создаёт новый объект-число, а старый остаётся как был.

# 05_immutable.py
num = 5
address_1 = id(num)
num + 2
print(num)          # 5 — не изменилось

num = num + 2
address_2 = id(num)
print(num)           # 7
print("Тот же объект?", address_1 == address_2)  # False

Почему так: id() возвращает идентификатор объекта в памяти. После num = num + 2 имя num стало ссылаться на другой объект — число 7, а не на изменённый на месте 5. Изменяемые типы (списки) ведут себя иначе — это станет заметно в теме списков.

Пример 6. Составные присваивания

Компактная запись «взять текущее значение, изменить, сохранить обратно».

# 06_augmented.py
x = 5
x += 3    # x = x + 3
print(x)  # 8
x -= 2
print(x)  # 6
x *= 4
print(x)  # 24
x /= 2
print(x)  # 12.0
x //= 2
print(x)  # 6.0
x **= 3
print(x)  # 216.0

Что происходит: каждый составной оператор — сокращение для «обычная операция + присваивание». Обратите внимание: после x /= 2 тип x стал float и остаётся float дальше, даже если следующая операция — целочисленная по смыслу.

Пример 7. Множественное присваивание, цепочка и обмен значениями

# 07_multiple_assignment.py
a, b, c = 1, 5, 10
print(a, b, c)   # 1 5 10

x = y = z = 0    # цепочка: все три получают одно и то же значение
print(x, y, z)   # 0 0 0

a, b = 5, 10
a, b = b, a      # обмен без временной переменной
print(a, b)      # 10 5

Что происходит: в a, b = b, a Python сначала полностью вычисляет правую часть — кортеж (b, a) из старых значений, — и только потом распаковывает его в a и b. Поэтому промежуточная переменная не нужна.

Пример 8. Явное преобразование типов

int(), float(), str(), bool() — четыре функции, которые есть почти в каждой программе.

# 08_conversion.py
print(int("10"), float("10"), str(10), bool(0), bool(1))
# 10 10.0 10 False True

print(int(3.9))    # 3  — обрезает дробную часть, а не округляет
print(int(-3.9))   # -3

print(bool(""), bool("0"), bool([]), bool([0]))
# False True False True   — непустая строка "0" истинна!

value = 5
value += 3.14
print(value, type(value))  # 8.14 <class 'float'>   — int + float даёт float

Почему так: int() от дробного числа отбрасывает дробную часть в сторону нуля — это не то же самое, что округление: int(3.9) даёт 3, а не 4. Строка "0" непустая, поэтому bool("0") — True, хотя интуитивно кажется, что «ноль» должен быть ложным.

Пример 9. ValueError при неверном преобразовании

# 09_value_error.py
try:
    number = int("10.0")
except ValueError as error:
    print("ValueError:", error)
# ValueError: invalid literal for int() with base 10: '10.0'

try:
    number = float("abc")
except ValueError as error:
    print("ValueError:", error)
# ValueError: could not convert string to float: 'abc'

print(float("10.0"))  # 10.0 — а float() ту же строку принимает

Что происходит: int() не умеет напрямую разбирать дробную запись в строке — сначала нужно float("10.0"), а затем при необходимости int(float("10.0")). Тип аргумента (строка) подходит, но его содержимое не превращается в нужное число — поэтому это именно ValueError, а не TypeError.

Пример 10. Практика: расчёт сдачи

Собираем несколько операций и преобразование input() в одной прикладной задаче из лекции.

# 10_change.py
price = 250      # int(input("Введите стоимость товара: "))
quantity = 3      # int(input("Введите количество товара: "))
payment = 1000     # int(input("Введите сумму оплаты: "))

total_cost = price * quantity
change = payment - total_cost
print("Сдача:", change, "рублей")
# Сдача: 250 рублей

Что происходит: все три значения из input() — строки, поэтому их обязательно оборачивают в int() до умножения и вычитания; без этого price * quantity либо упадёт с ошибкой, либо (для * со строкой и числом) даст неожиданный результат.

Что делать дальше

Разберите файлы репозитория — там те же идеи в исходном виде, затем переходите к заданиям. Если что-то из примеров не запустилось — сначала загляните в типичные ошибки.