Python: задачки и вопросы
7.6K subscribers
1.23K photos
2 videos
1 file
102 links
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков

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

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

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

Другие наши проекты: https://tprg.ru/media
Download Telegram
Борис Пасхавер, «Pandas в действии», глава 𝟹:

«Параметр 𝚙𝚊𝚛𝚜𝚎_𝚍𝚊𝚝𝚎𝚜 функции 𝚛𝚎𝚊𝚍_𝚌𝚜𝚟 позволяет задать список строковых значений, отмечающих столбцы, текстовые значения из которых 𝚙𝚊𝚗𝚍𝚊𝚜 должна преобразовать в метки даты / времени. В следующем примере в него передается список, содержащий значения "𝙳𝚊𝚝𝚎":»

𝚙𝚍.𝚛𝚎𝚊𝚍_𝚌𝚜𝚟("𝚐𝚘𝚘𝚐𝚕𝚎_𝚜𝚝𝚘𝚌𝚔𝚜.𝚌𝚜𝚟", 𝚙𝚊𝚛𝚜𝚎_𝚍𝚊𝚝𝚎𝚜 = ["𝙳𝚊𝚝𝚎"]).𝚑𝚎𝚊𝚍()

Вот разница между чтением файла без параметра 𝚙𝚊𝚛𝚜𝚎_𝚍𝚊𝚝𝚎𝚜 и с ним:

𝟷. БЕЗ 𝚙𝚊𝚛𝚜𝚎_𝚍𝚊𝚝𝚎𝚜: столбец 𝙳𝚊𝚝𝚎 остается строковым (𝚘𝚋𝚓𝚎𝚌𝚝), значения имеют тип 𝚜𝚝𝚛
𝟸. С 𝚙𝚊𝚛𝚜𝚎_𝚍𝚊𝚝𝚎𝚜=["𝙳𝚊𝚝𝚎"]: столбец 𝙳𝚊𝚝𝚎 преобразуется в 𝚍𝚊𝚝𝚎𝚝𝚒𝚖𝚎𝟼𝟺, значения имеют тип 𝚃𝚒𝚖𝚎𝚜𝚝𝚊𝚖𝚙

Параметр 𝚙𝚊𝚛𝚜𝚎_𝚍𝚊𝚝𝚎𝚜 принимает:
− Список имен столбцов для преобразования в даты
− 𝚃𝚛𝚞𝚎 для автоматического определения столбцов с датами
− Словарь для более сложных преобразований
👍1👎1
Адам Джонсон, участник Django Security Team:

«Несмотря на успешную генерацию случайного числа, функция всегда возвращает 𝟺 из−за 𝚛𝚎𝚝𝚞𝚛𝚗 в 𝚏𝚒𝚗𝚊𝚕𝚕𝚢−блоке, что делает 𝚝𝚛𝚢−блок фактически бесполезным.

𝙿𝙴𝙿 𝟽𝟼𝟻 ввёл 𝚂𝚢𝚗𝚝𝚊𝚡𝚆𝚊𝚛𝚗𝚒𝚗𝚐 на этот случай, объясняя, почему конструкции вроде 𝚛𝚎𝚝𝚞𝚛𝚗 / 𝚋𝚛𝚎𝚊𝚔 / 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎 в 𝚏𝚒𝚗𝚊𝚕𝚕𝚢 могут быть ошибкой — они затмевают поведение основного блока 𝚝𝚛𝚢, сбивая с толку разработчиков.


Способы решения проблемы

Перенести 𝚛𝚎𝚝𝚞𝚛𝚗 в блок 𝚎𝚡𝚌𝚎𝚙𝚝:

𝚍𝚎𝚏 𝚍𝟼() −> 𝚒𝚗𝚝:
𝚝𝚛𝚢:
𝚛𝚎𝚝𝚞𝚛𝚗 𝚛𝚊𝚗𝚍𝚘𝚖.𝚛𝚊𝚗𝚍𝚒𝚗𝚝(𝟷, 𝟼)
𝚎𝚡𝚌𝚎𝚙𝚝 𝙴𝚡𝚌𝚎𝚙𝚝𝚒𝚘𝚗:
# Фолбэк — здесь уместнее
𝚛𝚎𝚝𝚞𝚛𝚗 𝟺

Избавиться от 𝚝𝚛𝚢 / 𝚎𝚡𝚌𝚎𝚙𝚝, если исключения маловероятны:

𝚍𝚎𝚏 𝚍𝟼() −> 𝚒𝚗𝚝:
𝚛𝚎𝚝𝚞𝚛𝚗 𝚛𝚊𝚗𝚍𝚘𝚖.𝚛𝚊𝚗𝚍𝚒𝚗𝚝(𝟷, 𝟼)


Рекомендации автора и сообщества

🔘Избегайте 𝚛𝚎𝚝𝚞𝚛𝚗 и подобных конструкций в 𝚏𝚒𝚗𝚊𝚕𝚕𝚢;
🔘Переносите логику в 𝚎𝚡𝚌𝚎𝚙𝚝, если нужно "подстраховаться" при ошибке;
🔘Удаляйте 𝚏𝚒𝚗𝚊𝚕𝚕𝚢, если он не нужен, либо используйте 𝚠𝚒𝚝𝚑 и контекстные менеджеры;
🔘Разрешённое поведение линтеров — удаление таких конструкций и рефакторинг».
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👎1
🪤 Что выведет код?
Anonymous Quiz
46%
Bob Sue
17%
Sue Sue
31%
Bob Bob
6%
Error
👍1👎1
Марк Лутц «Изучаем 𝙿𝚢𝚝𝚑𝚘𝚗», глава 39:

«Из−за того, что декораторы классов способны перехватывать вызовы, создающие экземпляры, они могут использоваться либо для управления созданием экземпляров классов, либо для реализации паттерна проектирования «одиночка». В последнем случае декоратор обеспечивает, чтобы экземпляр класса существовал в единственном числе, и при последующих вызовах возвращался именно он.»

Декоратор 𝚂𝚒𝚗𝚐𝚕𝚎𝚝𝚘𝚗 работает следующим образом:

− В словаре 𝚒𝚗𝚜𝚝𝚊𝚗𝚌𝚎𝚜 хранятся созданные экземпляры для каждого класса;
− При первом вызове 𝙿𝚎𝚛𝚜𝚘𝚗('𝙱𝚘𝚋') создается экземпляр и сохраняется в словаре;
− При втором вызове 𝙿𝚎𝚛𝚜𝚘𝚗('𝚂𝚞𝚎') декоратор проверяет, что экземпляр уже существует, и возвращает тот же объект;
− Поэтому и 𝚋𝚘𝚋, и 𝚜𝚞𝚎 ссылаются на один и тот же объект с именем '𝙱𝚘𝚋'.

Таким образом, при выводе 𝚋𝚘𝚋.𝚗𝚊𝚖𝚎 и 𝚜𝚞𝚎.𝚗𝚊𝚖𝚎 мы получаем '𝙱𝚘𝚋' дважды, поскольку это один и тот же объект.
👍1👎1
🧩 Что выведет код?
Anonymous Quiz
7%
1
52%
2
19%
3
23%
Error
👍21👎1
Марк Лутц «Изучаем Python», глава 39:

«В этом коде класс 𝚆𝚛𝚊𝚙𝚙𝚎𝚛 перехватывает доступ к любым именованным атрибутам внутреннего объекта, выводит трассировочное сообщение и применяет встроенную функцию __𝚐𝚎𝚝𝚊𝚝𝚝𝚛__ для передачи запроса 𝚠𝚛𝚊𝚙𝚙𝚎𝚍−объекту.»

Механизм работы:

− При создании экземпляра 𝚆𝚛𝚊𝚙𝚙𝚎𝚛([𝟷, 𝟸, 𝟹]) сохраняется список в атрибуте 𝚜𝚎𝚕𝚏.𝚠𝚛𝚊𝚙𝚙𝚎𝚍
− При вызове 𝚡.𝚊𝚙𝚙𝚎𝚗𝚍(𝟺) 𝙿𝚢𝚝𝚑𝚘𝚗 не находит метод 𝚊𝚙𝚙𝚎𝚗𝚍 у класса 𝚆𝚛𝚊𝚙𝚙𝚎𝚛
− Срабатывает метод __𝚐𝚎𝚝𝚊𝚝𝚝𝚛__ с параметром 𝚊𝚝𝚝𝚛𝚗𝚊𝚖𝚎 = '𝚊𝚙𝚙𝚎𝚗𝚍'
− Выводится сообщение «𝚃𝚛𝚊𝚌𝚎: 𝚊𝚙𝚙𝚎𝚗𝚍»
− Функция 𝚐𝚎𝚝𝚊𝚝𝚝𝚛(𝚜𝚎𝚕𝚏.𝚠𝚛𝚊𝚙𝚙𝚎𝚍, 𝚊𝚝𝚝𝚛𝚗𝚊𝚖𝚎) находит метод 𝚊𝚙𝚙𝚎𝚗𝚍 у обернутого списка и вызывает его
− Список [𝟷, 𝟸, 𝟹] становится [𝟷, 𝟸, 𝟹, 𝟺]
− При выводе 𝚡.𝚠𝚛𝚊𝚙𝚙𝚎𝚍 выводится содержимое обернутого списка: [𝟷, 𝟸, 𝟹, 𝟺]

«В частности, он отслеживает доступ к атрибутам, осуществляемый вызовом метода класса 𝚠𝚛𝚊𝚙𝚙𝚎𝚍−объекта; доступ к другим методам внутреннего объекта не перехватывается и не подлежит обработке по определению».
👍1👎1
Всем тимлидам, разработчикам, тестировщикам и админам!

Счастливого Дня программиста!

Желаем вам всегда зелёных билдов, отзывчивых кластеров и тихих дежурных смен. Пусть ваши логи будут чисты от ошибок, а мониторинг предупреждает о проблемах раньше, чем о них узнают пользователи.

И чтобы пожелание точно сбылось, обязательно воспользуйтесь подарками из нашей IT-коробки. Готовили с любовью в сердце вместе с нашими друзьями.

С праздником!
❤‍🔥1
🪤 Что выведет код?
Anonymous Quiz
53%
Bob Sue
24%
Bob Bob
16%
Sue Sue
7%
Error
👍1👎1
В данном коде демонстрируется корректная работа декоратора 𝚃𝚛𝚊𝚌𝚎𝚛 с множественными экземплярами.

Марк Лутц «Изучаем Python», глава 39:

«Однако, как теоретически обсуждалось ранее, такая альтернатива, где используются только классы, подвержена множеству классов, но не вполне нормально работает с множеством экземпляров заданного класса: каждый вызов, создающий экземпляр, запускает метод __𝚌𝚊𝚕𝚕__, который перезаписывает предыдущий экземпляр».

Механизм работы:

🔘 При создании 𝚋𝚘𝚋 = 𝙿𝚎𝚛𝚜𝚘𝚗('𝙱𝚘𝚋') вызывается метод __𝚌𝚊𝚕𝚕__ декоратора 𝚃𝚛𝚊𝚌𝚎𝚛
🔘 В 𝚜𝚎𝚕𝚏.𝚠𝚛𝚊𝚙𝚙𝚎𝚍 сохраняется экземпляр 𝙿𝚎𝚛𝚜𝚘𝚗 с именем '𝙱𝚘𝚋'
🔘 𝚋𝚘𝚋 ссылается на объект 𝚃𝚛𝚊𝚌𝚎𝚛, который содержит экземпляр 𝙿𝚎𝚛𝚜𝚘𝚗('𝙱𝚘𝚋')
🔘 При создании 𝚜𝚞𝚎 = 𝙿𝚎𝚛𝚜𝚘𝚗('𝚂𝚞𝚎') создается новый объект 𝚃𝚛𝚊𝚌𝚎𝚛
🔘 В новом объекте 𝚃𝚛𝚊𝚌𝚎𝚛 в 𝚜𝚎𝚕𝚏.𝚠𝚛𝚊𝚙𝚙𝚎𝚍 сохраняется экземпляр 𝙿𝚎𝚛𝚜𝚘𝚗 с именем '𝚂𝚞𝚎'
🔘 𝚜𝚞𝚎 ссылается на новый объект 𝚃𝚛𝚊𝚌𝚎𝚛, который содержит экземпляр 𝙿𝚎𝚛𝚜𝚘𝚗('𝚂𝚞𝚎')

При обращении к 𝚋𝚘𝚋.𝚗𝚊𝚖𝚎 и 𝚜𝚞𝚎.𝚗𝚊𝚖𝚎:
🔘 𝚋𝚘𝚋.𝚗𝚊𝚖𝚎 обращается к атрибуту 𝚗𝚊𝚖𝚎 через __𝚐𝚎𝚝𝚊𝚝𝚝𝚛__ первого объекта 𝚃𝚛𝚊𝚌𝚎𝚛
🔘 __𝚐𝚎𝚝𝚊𝚝𝚝𝚛__ делегирует запрос к 𝚜𝚎𝚕𝚏.𝚠𝚛𝚊𝚙𝚙𝚎𝚍 первого объекта (содержит 𝙿𝚎𝚛𝚜𝚘𝚗('𝙱𝚘𝚋'))
🔘 Поэтому 𝚋𝚘𝚋.𝚗𝚊𝚖𝚎 возвращает '𝙱𝚘𝚋'
🔘𝚜𝚞𝚎.𝚗𝚊𝚖𝚎 обращается к атрибуту 𝚗𝚊𝚖𝚎 через __𝚐𝚎𝚝𝚊𝚝𝚝𝚛__ второго объекта 𝚃𝚛𝚊𝚌𝚎𝚛
🔘 __𝚐𝚎𝚝𝚊𝚝𝚝𝚛__ делегирует запрос к 𝚜𝚎𝚕𝚏.𝚠𝚛𝚊𝚙𝚙𝚎𝚍 второго объекта (содержит 𝙿𝚎𝚛𝚜𝚘𝚗('𝚂𝚞𝚎'))
🔘 Поэтому 𝚜𝚞𝚎.𝚗𝚊𝚖𝚎 возвращает '𝚂𝚞𝚎'

В данном случае каждый вызов 𝙿𝚎𝚛𝚜𝚘𝚗() создает новый объект 𝚃𝚛𝚊𝚌𝚎𝚛, поэтому проблема с перезаписью экземпляров не проявляется.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👎1
🧩 Что выведет код?
Anonymous Quiz
20%
1
15%
2
59%
3
7%
Error
👍1👎1
В данном коде демонстрируется декоратор регистрации, который добавляет объекты в словарь для будущей обработки.

Предположим, что вы требуете от методов или классов, используемых приложением, регистрации в API−интерфейсе для будущей обработки (может быть, API−интерфейс позже будет обращаться к объектам и отвечать на текущие события). Несмотря на то что это могли бы предоставить регистрационные функции, которые выполняли вызову вручную после того, как объекты определены, декораторы сделают ваше решение более элегантным.

Механизм работы:

🔘 Декоратор 𝚛𝚎𝚐𝚒𝚜𝚝𝚎𝚛 добавляет функции в словарь 𝚛𝚎𝚐𝚒𝚜𝚝𝚛𝚢 по их имени
🔘 При декорировании @𝚛𝚎𝚐𝚒𝚜𝚝𝚎𝚛 функции 𝚜𝚙𝚊𝚖 и 𝚎𝚐𝚐𝚜 автоматически регистрируются
🔘 𝚛𝚎𝚐𝚒𝚜𝚝𝚛𝚢[𝚘𝚋𝚓.__𝚗𝚊𝚖𝚎__] = 𝚘𝚋𝚓 сохраняет ссылку на функцию в словаре
🔘 𝚛𝚎𝚝𝚞𝚛𝚗 𝚘𝚋𝚓 возвращает саму функцию, а не обертку

Поскольку он возвращает сам объект, а не оболочку, он не перехватывает будущие вызовы.

Вывод кода:
🔘 𝚁𝚎𝚐𝚒𝚜𝚝𝚛𝚢: показывает содержимое словаря 𝚛𝚎𝚐𝚒𝚜𝚝𝚛𝚢 с именами функций, их объектами и типами
🔘 𝙼𝚊𝚗𝚞𝚊𝚕 𝚌𝚊𝚕𝚕𝚜: прямые вызовы функций 𝚜𝚙𝚊𝚖(𝟺) = 𝟷𝟼, 𝚎𝚐𝚐𝚜(𝟾) = 𝟻𝟷𝟸
🔘 𝚁𝚎𝚐𝚒𝚜𝚝𝚛𝚢 𝚌𝚊𝚕𝚕𝚜: вызовы функций через словарь 𝚛𝚎𝚐𝚒𝚜𝚝𝚛𝚢 с аргументом 𝟸: 𝚜𝚙𝚊𝚖(𝟸) = 𝟺, 𝚎𝚐𝚐𝚜(𝟸) = 𝟾

Таким образом, регистр хранит ссылки на функции и классы, и их можно вызывать напрямую через регистр.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👎1
🧩 Что выведет код?
Anonymous Quiz
5%
None
87%
Bob is 45 years old
3%
Bob
5%
TypeError
👍1👎1
В данном коде демонстрируется декоратор проверки вхождения значений в диапазон для позиционных аргументов.

🔘 Декоратор @𝚛𝚊𝚗𝚐𝚎𝚝𝚎𝚜𝚝((𝟷, 𝟶, 𝟷𝟸𝟶)) проверяет, что аргумент с индексом 𝟷 (𝚊𝚐𝚎) находится в диапазоне от 𝟶 до 𝟷𝟸𝟶
🔘 Если __𝚍𝚎𝚋𝚞𝚐__ = 𝚃𝚛𝚞𝚎 (режим отладки), функция оборачивается проверкой
🔘 При вызове 𝚙𝚎𝚛𝚜𝚒𝚗𝚏𝚘('𝙱𝚘𝚋', 𝟺𝟻) проверяется: 𝟺𝟻 >= 𝟶 и 𝟺𝟻 <= 𝟷𝟸𝟶
🔘 Условие выполняется, поэтому функция выполняется нормально и выводит «𝙱𝚘𝚋 𝚒𝚜 𝟺𝟻 𝚢𝚎𝚊𝚛𝚜 𝚘𝚕𝚍»

В имеющемся коде объект функции обертывается представленной формой исследования, если активен режим 𝚍𝚎𝚋𝚞𝚐 (по умолчанию 𝚃𝚛𝚞𝚎). В противном случае возвращается сама функция, и код выполняется без дополнительных проверок.

Если бы 𝚊𝚐𝚎 был вне диапазона (например, 𝟷𝟻𝟶), то возникло бы исключение 𝚃𝚢𝚙𝚎𝙴𝚛𝚛𝚘𝚛 с сообщением «𝙰𝚛𝚐𝚞𝚖𝚎𝚗𝚝 𝟷 𝚗𝚘𝚝 𝚒𝚗 𝟶..𝟷𝟸𝟶».
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👎1