Домашние задания
Здесь находятся домашние задания по курсу. Если вы зачислены на курс и будете сдавать задания, прочитайте внимательно текст ниже. Оценка за решение выставляется только в том случае, если оно сдано в тестирующую систему. Если вы вольнослушатель, то сдача заданий вам недоступна, но вы можете тестировать решения локально (см. ниже).
Самостоятельность выполнения
Домашние задания выполняются индивидуально. Можно обсуждать условие, общие идеи и подходы, но нельзя обмениваться кодом, отчётом или другими частями решений.
Нельзя передавать другим студентам своё решение или его части, просматривать решения других студентов, совместно разрабатывать, копировать или адаптировать их, в том числе если эти решения были сданы в прошлые годы.
При установленном нарушении академических норм за соответствующее домашнее задание выставляется оценка 0, а преподаватель направляет служебную записку декану факультета. Студенту, намеренно предоставившему своё решение для списывания, также может быть выставлена оценка 0. Подробнее см. правила НИУ ВШЭ о нарушении академических норм.
Использование LLM
При выполнении домашних заданий можно использовать LLM. Если их применение повлияло на сданное решение, его необходимо описать в разделе ## Описание применения генеративных моделей в файле solution/readme.md. Если раздел отсутствует, считается, что генеративные модели при подготовке решения не использовались. Во время устной защиты использовать LLM нельзя, если преподаватель явно не разрешил обратное. Подробные правила приведены в политике использования LLM.
Настройка окружения
Убедитесь, что у вас на компьютере установлен Python. В случае работы на Windows не рекомендуется устанавливать Python из Microsoft Store – это может привести к ошибкам при запуске тестов, поэтому лучше использовать официальный установщик.
Установите Python 3.12 или новее и необходимые зависимости: pip3 install -r requirements.txt. При работе на Windows замените здесь и далее pip3 и python3 на pip и python соответственно.
Также вам понадобится запускать Docker-контейнеры. Для этого надо установить Docker Engine или Docker Desktop под вашу ОС.
Склонируйте репозиторий курса в папку на вашем компьютере. Далее обновляйте вашу копию репозитория с помощью git pull по мере размещения новых заданий и материалов. Во избежание проблем не рекомендуется менять структуру папок внутри репозитория и переносить их в другое место.
Откройте корень репозитория в вашей IDE и откройте файл homework/01-guarantees/solution/guarantees.py. Для автодополнения и проверки типов API AnySystem описан в стабе — файле с объявлениями классов и методов без их реализации. В VS Code с Pylance он подключается через настройки репозитория, дополнительная установка модуля не нужна. Для другой IDE укажите папку typings как каталог стабов согласно её документации. Исходная реализация API доступна в AnySystem 0.3.0.
В AnySystem 0.3.0 Python-модуль встроен в Rust-тестер: при запуске тестов локально или в Docker отдельный anysystem.py и настройка PYTHONPATH не требуются. Запускайте тесты из папки задания, чтобы относительные пути к решениям были корректны. Стаб служит только для IDE.
Регистрация
(Пропустите эту часть, если вы вольнослушатель.)
Перед тем, как сдавать задания, надо пройти регистрацию. Откройте папку homework и выполните команду:
python3 cli.py register https://distsys.ru
Введите registration token, разосланный в канале курса, полное имя (Фамилия Имя Отчество) в точности как в списке студентов и личный адрес электронной почты. Если вас нет в списке студентов, зачисленных на курс, то вы не можете сдавать задания.
После успешной регистрации настройки и токен доступа будут сохранены в файле cli.yaml. Не публикуйте этот файл и не добавляйте его в Git. На указанный адрес придёт письмо с данными учётной записи Gitea.
Войдите в Gitea с временным паролем из вывода команды и сразу смените его. До смены пароля токен не работает. Если токен утрачен, создайте новый в Gitea: Settings -> Applications, имя distsys-cli, разрешение User: Read; затем замените только access_token в cli.yaml. Если недоступен адрес электронной почты или письмо не приходит, обратитесь к преподавателям.
Локальное тестирование решения
Перед сдачей решения в тестирующую систему обязательно проведите локальное тестирование. В каждом задании будет инструкция как это сделать.
Пожалуйста, не пренебрегайте локальным тестированием. Все тесты для заданий открыты, в том числе для того, чтобы вы могли быстро протестировать решение локально после каждой правки, а не отправляли его каждый раз в тестирующую систему и ждали в очереди. Тем самым вы также снизите время ожидания для товарищей, которым действительно надо зафиксировать улучшение своего решения.
В каждом условии приведена Docker-команда для запуска тестов в окружении, аналогичном тестирующей системе. Выполняйте её из папки соответствующего задания.
В некоторых случаях время выполнения тестов, особенно в Docker, может зависеть от вашей системы, архитектуры процессора и т.п. Если в тестах к заданию есть лимит по времени, и при локальном тестировании ваше решение не укладывается в него, попробуйте сдать решение в систему. Возможно тесты там пройдут из-за отличий в скорости выполнения. Референсом в таких тестах служит сервер тестирующей системы. Также можно попробовать запустить тесты локально без Docker по инструкции из условия задания.
ARM64 / Apple Silicon
Опубликованные образы тестов сейчас предназначены для linux/amd64. На компьютерах с ARM64, включая Apple Silicon, Docker запускает их через эмуляцию, поэтому тесты могут выполняться заметно медленнее. Особенно это важно для тестов с лимитом времени: их локальный результат может отличаться от результата в тестирующей системе.
Для заданий 1, 4, 6–9 можно собрать тестовый образ для архитектуры своей машины из открытого tests/Dockerfile. Выполните из папки задания:
docker build --pull -t distsys-tests-local ./tests
docker run --rm -t -v ./solution:/solution distsys-tests-local [ЗДЕСЬ МОЖНО УКАЗАТЬ ОПЦИИ]
Для полного прогона замените [ЗДЕСЬ МОЖНО УКАЗАТЬ ОПЦИИ] параметрами из команды полного тестирования в условии соответствующего задания. Для быстрых итераций можно запускать тесты без Docker по инструкции из условия.
В заданиях 2, 3, 5 и 10 используйте приведённые в условиях инструкции локального запуска сервисов и тестов. Собирать внутренний Docker-in-Docker образ для этого не требуется.
Тестирующая система используется для итоговой проверки и служит эталоном для временных лимитов, но не должна заменять локальное тестирование после каждой правки.
Сдача решения
После локального тестирования откройте папку задания, например homework/01-guarantees, и выполните команду:
python3 ../cli.py submit
Утилита определит идентификатор задания по имени текущей папки и отправит содержимое её поддиректории solution. Она выведет идентификатор и официальное время приёма решения, а также ссылку на запуск workflow. Откройте эту ссылку в Gitea, чтобы следить за проверкой и прочитать её журнал.
В состав решения для каждого задания должен входить краткий отчёт в файле solution/readme.md. Отчёт необходимо сдать вместе с остальными файлами решения до дедлайна задания. При его отсутствии автоматические тесты всё равно запускаются, но защита не проводится и решение не засчитывается. Требования к содержанию отчёта приведены в условии соответствующего задания.
Изоляция процессов AnySystem
В заданиях на AnySystem каждый экземпляр Process моделирует отдельный процесс распределённой системы. Его изменяемое состояние должно храниться только в атрибутах экземпляра (self). Все взаимодействия между процессами должны происходить через сообщения, как и в реальной распределённой системе.
Запрещено использовать общую изменяемую память: изменяемые объекты на уровне модуля или любого класса, включая вспомогательные классы, изменяемые значения аргументов по умолчанию, global, разделяемые замыкания, атрибуты классов и рефлексию для изменения глобального состояния. Перед запуском тестов решение статически проверяется; при нарушении тестер выводит найденные места и выставляет SCORE: 0.
Импорты, вспомогательные функции и классы, а также неизменяемые константы разрешены. Изменяемое состояние вспомогательного объекта допустимо, если каждый процесс создаёт собственный экземпляр и хранит его в self; для полей dataclass используйте field(default_factory=...). Неизменяемые последовательности и множества можно задавать через tuple и frozenset, а таблицы — через types.MappingProxyType с литералом словаря.