Иерархия конфигурации в Python: изоляция настроек разных клиентов
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Collections в Python: задачи на ChainMap, defaultdict и deque.
Иерархия настроек организаций
Облачная платформа обслуживает независимые организации, для каждой из которых действует собственный набор параметров. Если конкретная настройка не задана для организации индивидуально, система обращается к глобальным значениям по умолчанию. При обработке входящих запросов клиенты могут временно переопределять любые параметры: такие переопределения действуют строго в рамках текущего обращения и не должны влиять на последующие операции того же или других клиентов. Кроме вычисления итоговых значений, платформа ведёт аудит всех ключей, которые хотя бы раз переопределялись для каждой организации.
Что уже дано
Готовый скрипт считывает входной JSON-объект, передаёт данные в функцию resolve_tenant_requests и выводит результат обратно в формате JSON.
Что нужно сделать
Реализуйте функцию resolve_tenant_requests(platform_defaults, tenants_config, requests).
Функция принимает три аргумента:
platform_defaults— словарь базовых настроек платформы по умолчанию;tenants_config— словарь конфигураций организаций, где ключом является строковый идентификатор организации (tenant_id), а значением — словарь её индивидуальных настроек;requests— упорядоченный список запросов.
Каждый элемент списка requests представляет собой словарь со следующими полями:
tenant_id— строковый идентификатор организации (гарантированно присутствует среди ключейtenants_config);overrides— словарь настроек, переопределяемых исключительно для этого запроса;query_keys— список имён настроек, значения которых требуется вернуть в ответе на этот запрос.
Функция должна вернуть словарь ровно с двумя ключами: "responses" и "audit_modified_keys".
Правила формирования списка responses:
- Порядок элементов строго соответствует порядку запросов в
requests. - Каждый словарь ответа содержит только те ключи, которые перечислены в
query_keysтекущего запроса. - Значение для каждого ключа выбирается по строгому приоритету:
- Значение из
overridesтекущего запроса, если ключ в нём присутствует; - Значение из конфигурации организации в
tenants_config, если ключ в нём присутствует; - Значение из глобального словаря
platform_defaults, если ключ в нём присутствует; - Если ключ отсутствует на всех трёх уровнях, его значением становится
None(в JSON —null).
- Значения
False,0, пустые строки илиNoneсчитаются реально заданными значениями, а не признаком отсутствия ключа. - Переопределения из
overridesизолированы: они действуют только в рамках своего запроса и не должны изменять настройки организации или платформы для любых последующих обращений.
Правила формирования словаря audit_modified_keys:
- Ключами являются идентификаторы всех организаций из
tenants_config, включая те, для которых вrequestsне поступило ни одного запроса. - Значением для каждой организации является список уникальных имён ключей, которые хотя бы раз встречались в словаре
overridesзапросов этой организации, отсортированный по возрастанию (лексикографически). - В аудит включаются все ключи из
overrides, даже если их не запрашивали вquery_keys, независимо от их значений (включаяNone,Falseи0). - Если для организации не было запросов или ни в одном из её запросов не передавались ключи в
overrides, значением должен быть пустой список[].
Ввод и вывод
Программа взаимодействует с внешним окружением через стандартные потоки stdin и stdout.
Формат ввода
В стандартный ввод передаётся единый JSON-объект, содержащий:
"platform_defaults"— объект со строковыми ключами настроек платформы по умолчанию;"tenants"— объект, отображающий строковые идентификаторы организаций в объекты их настроек;"requests"— массив объектов, каждый из которых содержит поля"tenant_id","overrides"и"query_keys".
Формат вывода
В стандартный вывод выводится одна JSON-строка — объект с ключами "audit_modified_keys" и "responses", сериализованный с сортировкой ключей и компактными разделителями.
Пример
- Ввод
{"platform_defaults":{"audit_log":false,"max_batch":100,"theme":"light"},"tenants":{"alpha":{"max_batch":250,"tier":"pro"},"beta":{"audit_log":true}},"requests":[{"tenant_id":"alpha","overrides":{"theme":"dark"},"query_keys":["theme","max_batch","audit_log","tier","missing_flag"]},{"tenant_id":"beta","overrides":{"max_batch":500},"query_keys":["audit_log","max_batch","tier"]},{"tenant_id":"alpha","overrides":{"custom_rate":10},"query_keys":["custom_rate","theme"]}]}- Вывод
{"audit_modified_keys":{"alpha":["custom_rate","theme"],"beta":["max_batch"]},"responses":[{"audit_log":false,"max_batch":250,"missing_flag":null,"theme":"dark","tier":"pro"},{"audit_log":true,"max_batch":500,"tier":null},{"custom_rate":10,"theme":"light"}]}
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Удаление ключа из ChainMap в Python: проверка поведения del
- Обратный индекс на Python: группировка уникальных значений через defaultdict
- Подсчёт дефицита ресурсов в Python: квоты и суммы заявок
- ChainMap в Python: исправьте приоритет настроек и удаление переопределений
- Скользящее окно Python: найдите кратчайшую подстроку с тремя символами
- Объединение команд и подсчёт рейтинга на Python
