Python: задачки и вопросы
6.9K subscribers
1.35K photos
1 video
1 file
125 links
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Другие наши проекты: https://tprg.ru/media
Download Telegram
Python: задачки и вопросы
Развёрнутое пояснение:

1. Создаётся функция load_rate, которая при вызове печатает строку «резерв» и возвращает 99.

2. В словарь rates записывается существующий тариф standard со значением 10.

3. Перед вызовом rates.get Python вычисляет все переданные аргументы, включая выражение load_rate().

4. load_rate печатает «резерв» и возвращает 99, которое становится запасным значением для get.

5. Метод get находит ключ standard, поэтому возвращает 10, а уже вычисленное запасное значение 99 не использует.

6. Последний print выводит 10, поэтому итоговый вывод состоит из строк «резерв» и «10».

Почему это важно

Задача проверяет порядок вычисления аргументов функции. В реальном проекте передача затратной загрузки или запроса к резервному сервису прямо в dict.get может выполнять лишнюю работу даже при наличии ключа. Для ленивого получения запасного значения сначала проверяют наличие ключа или используют другую явную ветвь выполнения.
✍2
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. defaults содержит исходные значения timeout и retries, а env изначально пуст.

2. ChainMap объединяет отображения для чтения, причём env имеет приоритет перед defaults.

3. Присваивание через config не ищет отображение, где ключ уже существует: значение retries записывается в первое отображение env.

4. Удаление через ChainMap также применяется только к первому отображению. Ключа timeout в env нет, поэтому возникает KeyError, хотя он доступен для чтения из defaults.

5. Обработчик перехватывает KeyError и печатает env с добавленным retries и неизменённый defaults, поэтому вывод равен {'retries': 5} {'timeout': 30, 'retries': 2}.

Почему это важно: задача проверяет модель записи и удаления в ChainMap. В многослойных конфигурациях чтение проходит по всем слоям, но изменения не переносятся автоматически в слой, где найдено исходное значение.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. Кортеж regions задаёт два ключа: eu и us.

2. dict.fromkeys(regions, []) создаёт словарь, в котором оба ключа ссылаются на один и тот же пустой список.

3. append изменяет этот общий список, поэтому order-7 становится виден через оба ключа.

4. Выражение queues["us"] + ["order-8"] создаёт новый список, не изменяя исходный.

5. Присваивание связывает ключ us с новым списком, а eu сохраняет ссылку на прежний; поэтому вывод содержит order-7 у eu и оба заказа у us.

Почему это важно

Задача проверяет понимание общего изменяемого состояния и различия между изменением объекта и заменой ссылки. Такое поведение встречается при создании словарей очередей, групп и накопителей через dict.fromkeys.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
Python: задачки и вопросы
Развёрнутое пояснение:

1. Вызов orders() создаёт объект генератора, но его тело пока не выполняется.

2. next(stream) запускает генератор: печатается open, затем выполнение доходит до yield 101 и приостанавливается.

3. Внешний print получает значение 101 и печатает его.

4. Следующий print выводит done, поскольку генератор всё ещё приостановлен на yield.

5. stream.close() передаёт в точку приостановки служебное исключение GeneratorExit. Обычное продолжение после yield не происходит, поэтому строка next не печатается.

6. Перед завершением генератор обязательно выполняет блок finally, который печатает close. Итоговый порядок строк: open, 101, done, close.

Почему это важно

Задача проверяет жизненный цикл генераторов и гарантированную очистку ресурсов. В потоковой обработке генератор может удерживать файл, соединение или транзакцию; если потребитель прекращает чтение досрочно, явный вызов close() запускает очистку из finally, но не продолжает обычную обработку оставшихся элементов.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Разбор задачи

1️⃣Строковая переменная name содержит значение report.txt.

2️⃣Метод strip принимает множество символов: переданный аргумент .txt воспринимается как набор из точки, t и x.

3️⃣Интерпретатор удаляет символы из этого набора с обоих концов строки, пока не встретит первый символ, отсутствующий в наборе.

4️⃣Слева буква r не входит в набор, а справа удаляются расширение .txt и последняя буква t из слова report, после чего процесс останавливается на букве r.

5️⃣На экран выводится строка repor.

Почему это важно
Чтобы отрезать расширение, используйте name.removesuffix(".txt") (есть с Python 3.9) или pathlib.Path(name).stem. strip, lstrip и rstrip для этого не годятся: они портят имя каждый раз, когда его крайние буквы совпадают с символами расширения.
Please open Telegram to view this post
VIEW IN TELEGRAM
✍2
Please open Telegram to view this post
VIEW IN TELEGRAM
По шагам:

1️⃣Строка s состоит из шести кириллических букв.

2️⃣Первый вызов len(s) считает количество символов Юникода в строке, поэтому возвращает значение 6.

3️⃣Метод encode без параметров кодирует строку в байты по стандарту UTF-8, в котором каждый символ кириллицы занимает по два байта.

4️⃣Второй вызов len(s.encode()) определяет размер полученного объекта bytes, что даёт 12 байт.

5️⃣В итоге на экран выводится 6 12.

Почему это важно
Заголовок HTTP Content-Length и многие лимиты протоколов считают байты, а не символы. Если проверять такой лимит через len(s), русский текст окажется вдвое длиннее разрешённого. А если обрезать байты посреди буквы, например "привет".encode()[:3].decode(), будет UnicodeDecodeError. Для байтовых лимитов длину считают через len(s.encode()).
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1