Python: Модули
Пока программа маленькая, весь код можно хранить в одном файле. Такой подход удобен для простых примеров и небольших задач. Но со временем программа начинает расти. Когда кода становится много, ориентироваться в одном файле становится сложно. Между тем реальные приложения состоят из десятков тысяч строк (как минимум) и сотен файлов.
Чтобы разделить программу на отдельные логические части, в Python используют модули. Модуль представляет собой файл с кодом и расширением .py. А язык предоставляет механизмы для обращения к функциям и константам из других файлов.
При этом сам Python поставляется уже с набором встроенных (built-in) модулей, которые можно использовать в своем коде. Один из часто используемых модулей это math. В нем находятся математические функции и константы.
Как подключить модуль
Команда import в начале файла делает содержимое модуля доступным:
import math
print(math.floor(3.7)) # => 3
print(math.ceil(3.2)) # => 4После импорта к функциям обращаются через имя модуля и точку. Имя модуля совпадает с именем файла без расширения. math.ceil(3.2) вызывает функцию ceil из модуля math.
С технической точки зрения модуль в Python является объектом. Поэтому доступ через точку работает так же, как и при обращении к методам или свойствам объектов. При этом модуль нужен прежде всего для организации кода. Обычно внутри модуля размещают функции, константы и вспомогательные данные, связанные общей задачей.
Функции модуля math
Разберем несколько функций этого модуля. floor() округляет число вниз до ближайшего целого, ceil() округляет вверх:
import math
print(math.floor(7.9)) # => 7
print(math.ceil(7.1)) # => 8
print(math.ceil(7.0)) # => 7Разница заметна, когда число не целое. floor(7.9) дает 7, а не 8, потому что 7 — ближайшее целое снизу.
Импорт конкретных имен
Когда нужна только часть модуля, можно импортировать конкретные имена:
from math import ceil, floor
print(ceil(3.2)) # => 4
print(floor(3.7)) # => 3Такой импорт позволяет обращаться к ceil и floor напрямую, без префикса math.. Результат тот же, что и при import math. Такой способ удобен, когда из модуля нужно всего несколько функций. Если же модуль большой или имена функций слишком общие, обычно предпочитают обычный import, чтобы было понятно, откуда именно взялась функция.
Модуль внутри функции
Импортированный модуль доступен во всем файле, включая тело функций:
import math
л Вычисляет количество поездок, необходимых для перевозки всех предметов
def trips_needed(items: int, capacity: int) -> int:
return math.ceil(items / capacity)
print(trips_needed(10, 3)) # => 4Конфликты имен
Модули помогают избежать конфликтов имен. В больших программах разные части кода могут содержать функции или переменные с одинаковыми названиями. Например, в программе уже может существовать функция floor, а модуль math тоже содержит функцию с таким именем. Благодаря разделению на модули, мы можем создавать сколько угодно функций с одинаковыми именами, главное чтобы они находились в разных файлах. И это работает даже при импортах:
import math
def floor(number):
return "custom floor"
print(floor(3.7)) # => custom floor
print(math.floor(3.7)) # => 3Благодаря имени модуля Python понимает, какую именно функцию нужно вызвать. Это особенно важно при использовании сторонних библиотек, потому что разные разработчики могут выбирать одинаковые имена для функций.
Проблемы чаще возникают при импорте конкретных имен. Например, если в файле уже существует функция с таким же именем:
from math import floor
def floor(number):
return "custom floor"
print(floor(3.7)) # => custom floorПосле определения новой функции имя floor начинает ссылаться уже на нее. Функция из math становится недоступной по этому имени. По этой причине во многих проектах предпочитают обычный import, особенно в больших программах и при работе со сторонними библиотеками.
Задание
Реализуйте функцию amount_per_person(). Она принимает сумму счета в ресторане, количество человек и процент чаевых, а возвращает сумму, которую платит каждый. Итог округляется вверх - никто не должен недоплачивать.
Для округления используйте функцию math.ceil() из модуля math.
# Счет 300, 4 человека, чаевые 20% — итого 360, каждый платит 90
print(amount_per_person(300, 4, 20)) # => 90
# Счет 350, 3 человека, чаевые 10% — итого 385, каждый платит 129
print(amount_per_person(350, 3, 10)) # => 129Подсказка
- Сначала посчитайте итоговую сумму с чаевыми, затем разделите на количество человек и округлите вверх
- Не забудьте импортировать модуль
mathв начале файла
Полезное
Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект
Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "ИИ-помощник":
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества
Ваше упражнение проверяется по этим тестам
import solution
def test():
assert solution.amount_per_person(300, 4, 0) == 75
assert solution.amount_per_person(300, 4, 20) == 90
assert solution.amount_per_person(350, 3, 10) == 129
assert solution.amount_per_person(100, 3, 0) == 34Решение учителя откроется через:
20:00
