Summary session не вводит новых тем — она проверяет, как уживаются вместе арифметика из урока 04 и логика из урока 06. Примеры ниже идут по тому же плану, что source: сначала арифметика и переменные, затем преобразование типов, затем bool и логические операторы, и в конце — две практические задачи, где всё это используется вместе. Весь вывод в комментариях получен запуском кода.
Пример 1. Арифметические операции и приоритет
Шесть операторов из урока 04 и порядок их выполнения: скобки → ** → * / // % → + -.
print("Сложение:", 3 + 5) # 8
print("Умножение:", 4 * 6.0) # 24.0 — float заражает результат
print("Деление:", 8 / 2) # 4.0 — / всегда float
print("Целочисленное деление:", 7 // 2.0) # 3.0 — // с float даёт float
print("Остаток от деления:", 7 % 3) # 1
print("Возведение в степень:", 2 ** 3) # 8
print(2 + 3 * 4) # 14 — сначала умножение
print((2 + 3) * 4) # 20 — скобки меняют порядок
print(2 + 3 ** 2) # 11 — сначала степень
Что происходит: если хотя бы один операнд — float, результат тоже становится float, даже у //. Это первая из типичных ловушек контрольных вопросов блока 1.
Пример 2. Переменная и неизменяемость чисел
Числа в Python — неизменяемый тип: выражение num + 2 вычисляет новое значение и никак не трогает переменную num, если результат никуда не присвоен.
num = 5
num + 2 # результат вычислен и тут же забыт
print(num) # 5 — переменная не изменилась
num = num + 2 # а вот так — присвоили обратно
print(num) # 7
Почему так: строка без присваивания не «сохраняет» результат. Переменная меняется только оператором = (или его сокращённой формой, см. пример 3) — сам факт использования переменной в выражении её не меняет.
Пример 3. Составное присваивание
a += b — это a = a + b, записанное короче. То же самое есть для -=, *=, //= и остальных операторов.
score = 10
score += 5 # score = score + 5
print(score) # 15
score -= 3 # 12
print(score)
score *= 2 # 24
print(score)
score //= 4 # 6
print(score)
Как проверить себя: мысленно разверните сокращение в полную форму score = score ... — если результат совпал, сокращение прочитано верно.
Пример 4. Множественное присваивание, общее значение и обмен
Три разных приёма легко перепутать на контрольных вопросах: раздача значений по позициям, одно значение сразу нескольким именам и обмен без временной переменной.
a, b, c = 1, 2, 3
print(a, b, c) # 1 2 3
x = y = z = 0 # все три ссылаются на одно и то же число 0
x += 1 # но += создаёт новое значение только для x
print(x, y, z) # 1 0 0
a, b = 5, 10
a, b = b, a # обмен значениями за один шаг
print(a, b) # 10 5
Почему так: x = y = z = 0 — это не «связь» между переменными, а тройное присваивание одного и того же числа. После x += 1 имя x указывает на новое значение 1, а y и z по-прежнему указывают на 0. Это самый частый повод ошибиться в контрольных вопросах блока 1.
Пример 5. Преобразование строк в числа и ValueError
int() и float() справляются не с любой строкой: если строка выглядит не как целое число, int() откажется её конвертировать напрямую.
num1 = "10"
num2 = "5.0"
result = int(num1) / float(num2)
print(result) # 2.0
try:
int("5.0") # int() не умеет читать точку внутри строки
except ValueError as error:
print("ValueError:", error)
# invalid literal for int() with base 10: '5.0'
print(int(float("5.0"))) # 5 — сначала float(), потом int()
float(), а int() применяйте уже к результату, а не к исходной строке.
Пример 6. int() отбрасывает дробную часть — это не округление
int(5.99) даёт 5, а не 6 — частая ошибка контрольного вопроса 1.7. Если нужно именно округление, есть отдельная встроенная функция.
print(int(5.99)) # 5 — просто отброшена дробная часть
print(int(-5.99)) # -5 — отброшена в сторону нуля, а не вниз
print(round(5.99)) # 6 — round() округляет по правилам математики
print(round(5.49)) # 5
round() не входит в source этого урока (только int()/float()). Сверьтесь с docs.python.org — round(), включая замечание про округление «к чётному» на границе .5.
Пример 7. bool() и таблица истинности значений
Контрольный вопрос 2.2 просит сопоставить значения с их bool. Правило одно: «пустое» или нулевое — False, всё остальное — True, включая непустую строку с текстом "None".
values = [0, 1, -1, 0.0, "", "0", "None", None, [], [0]]
for value in values:
print(repr(value), "->", bool(value))
# 0 -> False 1 -> True -1 -> True
# 0.0 -> False '' -> False '0' -> True
# 'None' -> True None -> False [] -> False [0] -> True
Ловушка: bool(None) — False, а bool("None") — True, потому что это уже непустая строка из четырёх символов, а не сам объект None. Питон не «понимает» текст, он смотрит только на то, пуста строка или нет.
Пример 8. Цепочки сравнений
Python позволяет писать двойное неравенство почти как в математике — это не опечатка и не два раза одно и то же условие, а один читаемый оператор.
a = 5
b = 10
c = 10
print(a <= b <= c) # True — 5 <= 10 и 10 <= 10
print(a <= b and b <= c) # True — то же самое через and
print(0 < a < 5) # False — 5 не строго меньше 5
Что происходит: a <= b <= c — это сокращение для a <= b and b <= c, только значение b проверяется один раз, а не вычисляется дважды.
Пример 9. Приоритет not/and/or и короткое замыкание
Порядок вычисления логических операторов: not связывает сильнее всего, затем and, и только потом or. А ещё and/or не всегда вычисляют оба операнда.
a = False
b = True
c = True
print(not a or b and c) # True — сначала not a, затем b and c, потом or
print(not (a or b) and c) # False — скобки меняют порядок целиком
def probe(name, value):
print(" проверяю", name)
return value
print(probe("left", True) or probe("right", True))
# проверяю left
# True — правая часть даже не вызывалась
print(probe("left", False) and probe("right", True))
# проверяю left
# False — то же самое: and видит False слева и останавливается
Почему так: без скобок not a or b and c читается как (not a) or (b and c) — расстановка скобок в примере 2 меняет смысл на противоположный. Короткое замыкание — не просто оптимизация: если правая часть вызывает функцию с побочным эффектом, важно понимать, вызовется она или нет.
Пример 10. Собираем вместе: две практические задачи из source
Обе задачи — это преобразование типов (пример 5) плюс базовая арифметика (пример 1), применённые к процентам.
bill = 150.0
tip_percent = 8.0
tip = bill * tip_percent / 100
print("Сумма чаевых:", tip) # 12.0
salary = 50000.0
tax_percent = 13.0
tax = salary * tax_percent / 100
net_salary = salary - tax
print('Сумма "на руки":', net_salary) # 43500.0
В реальном скрипте bill и salary приходят из input() и требуют float(input(...)) — без преобразования получится та же ошибка, что в ошибке 3 из раздела «Ошибки».
Пример 11. Разбор ДЗ: bool как множитель 0/1
Разбор домашнего задания использует приём на стыке тем этого урока: bool — подтип int, поэтому True и False ведут себя как 1 и 0 в арифметике.
used_mb = 650
base_price = 30
extra_mb = used_mb - 500
total_price = base_price + extra_mb * 0.2 * int(used_mb > 500)
print("Общая стоимость:", total_price) # 60.0 — превышение было, доплата посчиталась
used_mb2 = 300
extra_mb2 = used_mb2 - 500 # -200, отрицательное превышение
total_price2 = base_price + extra_mb2 * 0.2 * int(used_mb2 > 500)
print("Общая стоимость:", total_price2) # 30.0 — превышения не было, доплата обнулилась
Что важно: int(used_mb > 500) превращает True/False в 1/0 и «включает» или «выключает» доплату одним умножением — без if. Условия через if/else, которые делают то же самое явно и понятнее для сложных случаев, — тема урока 08, следующего после этого повторения.