Пример 1. Встроенные математические функции
Часть функций доступна «из коробки», без импорта — abs, pow, round, min, max, sum.
numbers = [12, -5, 8, 3, -1]
print("Модуль -5:", abs(-5))
print("Максимум:", max(numbers))
print("Минимум:", min(numbers))
print("Сумма:", sum(numbers))
print("2 в степени 10:", pow(2, 10))
print("Округление 3.14159 до 2 знаков:", round(3.14159, 2))
# Модуль -5: 5
# Максимум: 12
# Минимум: -5
# Сумма: 17
# 2 в степени 10: 1024
# Округление 3.14159 до 2 знаков: 3.14
Пример 2. dir() и help(): что доступно в модуле
Прежде чем искать функцию в документации, можно спросить у самого Python: dir(module) перечисляет имена, help(func) печатает справку.
import math
print("Функций и констант в модуле math:", len(dir(math)))
print("sqrt" in dir(math), "pi" in dir(math))
# Функций и констант в модуле math: 65
# True True
Что происходит: dir(math) возвращает список всех имён модуля — по нему видно, что sqrt и pi там есть. help(math.sqrt) (не запускается здесь — печатает интерактивную справку) показывает сигнатуру и описание функции.
Пример 3. Разные способы импорта
Модуль — это файл .py с кодом; чтобы использовать чужой код, его нужно импортировать. Есть несколько равнозначных по результату, но разных по стилю способов.
# Явный импорт — рекомендуется
import math
print(math.sqrt(16))
# Импорт конкретных имён — допустимо
from math import sqrt, pi
print(sqrt(16))
print(pi)
# Псевдоним — удобно для длинных имён
import math as m
print(m.sqrt(16))
# Звёздочка — работает, но лучше избегать
from math import *
print(sqrt(16))
# 4.0
# 4.0
# 3.141592653589793
# 4.0
# 4.0
Почему так: все четыре варианта дают одинаковый результат для sqrt(16). Но from math import * затягивает в текущее пространство имён все имена модуля сразу — при импорте из нескольких модулей это может незаметно перезаписать одно имя другим.
Пример 4. Точка входа if __name__ == "__main__"
Специальная переменная __name__ равна "__main__", если файл запущен напрямую, и имени модуля — если он импортирован из другого файла. Это позволяет отделить код для запуска от кода для импорта.
print("Имя этого модуля при прямом запуске:", __name__)
if __name__ == "__main__":
print("Код в этом блоке выполнится только при прямом запуске файла.")
# Имя этого модуля при прямом запуске: __main__
# Код в этом блоке выполнится только при прямом запуске файла.
Что происходит: сейчас файл выполняется напрямую, поэтому __name__ == "__main__" истинно. Если бы этот же файл импортировали как модуль (import examples), __name__ оказался бы равен "examples", и код внутри if не выполнился бы.
Пример 5. Площадь и длина круга
import math
radius = 5.0 # результат float(input("Введите радиус: "))
area = math.pi * radius ** 2
circumference = 2 * math.pi * radius
print(f"Площадь: {area:.2f}")
print(f"Длина окружности: {circumference:.2f}")
# Площадь: 78.54
# Длина окружности: 31.42
Пример 6. Банковское округление
round() использует «банковское округление» (round half to even): дробная часть ровно 0.5 округляется к ближайшему чётному числу, а не всегда вверх.
for value in (1.5, 2.5, 3.5, 4.5, 5.5, 6.5):
print(f"round({value}) = {round(value)}")
print(round(-1.5))
print(round(4.235, 2))
# для округления, всегда идущего в одну сторону, используй math.floor / math.ceil
import math
print(math.floor(2.7))
print(math.ceil(2.1))
# round(1.5) = 2
# round(2.5) = 2
# round(3.5) = 4
# round(4.5) = 4
# round(5.5) = 6
# round(6.5) = 6
# -2
# 4.24
# 2
# 3
Что происходит: 2.5 округляется до 2 (ближайшее чётное), а 3.5 — до 4. Это уменьшает статистическую погрешность при большом количестве округлений, поэтому приём часто используют в финансовых расчётах. round(4.235, 2) даёт 4.24, а не «ожидаемые» 4.23 или 4.24 по правилу 0.5 — виновата двоичная неточность самого числа 4.235, см. пример 7.
Пример 7. Проблема точности float
Числа с плавающей точкой хранятся в двоичном виде (IEEE 754); не все десятичные дроби представимы в нём точно, отсюда «неожиданные» результаты сравнений.
total = 0.1 + 0.2
print(total)
print(total == 0.3)
print(math.isclose(total, 0.3, rel_tol=1e-9))
print(round(total, 2) == 0.3)
# 0.30000000000000004
# False
# True
# True
Почему так: 0.1 и 0.2 не представимы в двоичном виде точно, поэтому их сумма чуть-чуть отличается от 0.3. Сравнивать float через == напрямую ненадёжно — вместо этого используют math.isclose() (сравнение с допуском) или округление до нужного числа знаков.
Пример 8. Точные расчёты с Decimal
Модуль decimal хранит цифры в десятичном виде, а не в двоичном, поэтому не наследует ошибки округления float — важно для денег и финансов.
from decimal import Decimal
price = Decimal('19.99')
quantity = Decimal('3')
total = price * quantity
print(total)
# Правильное сравнение
print(Decimal('0.1') + Decimal('0.2') == Decimal('0.3'))
# Неправильно: передача float вместо строки
print(Decimal(0.1))
# 59.97
# True
# 0.1000000000000000055511151231257827021181583404541015625
Почему так: Decimal('0.1'), созданный из строки, хранит именно 0.1. А Decimal(0.1), созданный из float, сначала «наследует» неточное двоичное представление числа 0.1 — и эта неточность становится видна при выводе. Правило: Decimal создавайте из строк, не из float.
Пример 9. Тригонометрия
import math
angle = 30.0 # результат float(input("Введите угол в градусах: "))
radians = math.radians(angle)
print(f"sin({angle}°) = {math.sin(radians):.4f}")
print(f"cos({angle}°) = {math.cos(radians):.4f}")
print(f"tan({angle}°) = {math.tan(radians):.4f}")
# sin(30.0°) = 0.5000
# cos(30.0°) = 0.8660
# tan(30.0°) = 0.5774
Что происходит: функции math.sin/cos/tan принимают угол в радианах, а не в градусах, поэтому math.radians() сначала переводит градусы в радианы.
Пример 10. Стандартная библиотека: встроенный модуль или нет
Модули бывают встроенными (идут с Python, ничего доустанавливать не нужно) и сторонними (ставятся через pip). sys.stdlib_module_names позволяет проверить это программно.
import sys
for name in ("os", "math", "numpy"):
print(name, "->", "встроенный" if name in sys.stdlib_module_names else "нужно установить")
# os -> встроенный
# math -> встроенный
# numpy -> нужно установить
sys.stdlib_module_names появился в Python 3.10 — на других версиях используйте python -m pydoc modules из терминала.
Пример 11. Ловушка: смешивание Decimal и float напрямую
Decimal нельзя складывать с обычным float в одном выражении — Python не рискует молча потерять точность и поднимает ошибку.
from decimal import Decimal
try:
result = Decimal('10.5') + 2.5
except TypeError as error:
print(f"Ошибка: {error}")
# правильно: обернуть float в Decimal через строку
result = Decimal('10.5') + Decimal(str(2.5))
print(result)
# Ошибка: unsupported operand type(s) for +: 'decimal.Decimal' and 'float'
# 13.0
Что происходит: Decimal('10.5') + 2.5 вызывает TypeError — типы Decimal и float напрямую не складываются. Обходной путь — Decimal(str(2.5)): превратить float в строку, а потом в Decimal, чтобы не потерять контроль над точностью.
Как запустить в VS Code
- Создайте файл, например
circle.py, в рабочей папке урока. - Скопируйте код из примера.
- Откройте терминал в VS Code (Ctrl + `).
- Активируйте виртуальное окружение:
venv\Scriptsctivate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python circle.py