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

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

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

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

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

«Pandas при сортировке ставит символы в верхнем регистре перед символами в нижнем. Таким образом, строка с заглавной буквы 𝚉 будет располагаться в очереди раньше строки со строчной буквы 𝚊».

В нашем случае:
− '𝙱𝚘𝚋' начинается с заглавной '𝙱'
− '𝙳𝚊𝚟𝚒𝚍' начинается с заглавной '𝙳'
− '𝚊𝚕𝚒𝚌𝚎' начинается со строчной '𝚊'
− '𝚌𝚑𝚊𝚛𝚕𝚒𝚎' начинается со строчной '𝚌'

Поэтому после сортировки порядок будет: сначала все строки с заглавными буквами (𝙱𝚘𝚋, 𝙳𝚊𝚟𝚒𝚍), затем со строчными (𝚊𝚕𝚒𝚌𝚎, 𝚌𝚑𝚊𝚛𝚕𝚒𝚎).

Для сортировки без учета регистра можно использовать параметр 𝚔𝚎𝚢 с функцией 𝚜𝚝𝚛.𝚕𝚘𝚠𝚎𝚛:

𝚍𝚏.𝚜𝚘𝚛𝚝_𝚟𝚊𝚕𝚞𝚎𝚜('𝙽𝚊𝚖𝚎', 𝚔𝚎𝚢=𝚕𝚊𝚖𝚋𝚍𝚊 𝚡: 𝚡.𝚜𝚝𝚛.𝚕𝚘𝚠𝚎𝚛())

Это даст естественный алфавитный порядок: ['𝚊𝚕𝚒𝚌𝚎', '𝙱𝚘𝚋', '𝚌𝚑𝚊𝚛𝚕𝚒𝚎', '𝙳𝚊𝚟𝚒𝚍'].
👍1👎1
🪤 Что выведет код?
Anonymous Quiz
27%
1
21%
2
28%
3
23%
Error
👎3👍1
В данной задаче рассматривается механизм наследования атрибутов от метаклассов. Код создает два метакласса 𝙼𝟷 и 𝙼𝟸 с атрибутами 𝚊𝚝𝚝𝚛𝟷 (со значениями 𝟷 и 𝟸 соответственно), затем определяет классы 𝙲𝟷 и 𝙲𝟸 с атрибутами 𝚊𝚝𝚝𝚛𝟷 (со значениями 𝟹 и 𝟺 соответственно), где 𝙲𝟸 наследует от 𝙲𝟷 и использует метакласс 𝙼𝟸. Ключевой момент заключается в том, что экземпляры классов НЕ наследуют атрибуты от метаклассов напрямую.

Марк Лутц, «Изучаем 𝙿𝚢𝚝𝚑𝚘𝚗», глава 𝟺𝟶:

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

Однако есть важное ограничение:

«Главное отличие состоит в том, что наследование экземпляров не проходит по ссылке __𝚌𝚕𝚊𝚜𝚜__ класса, но имеет ограниченный свой охват словарем __𝚍𝚒𝚌𝚝__ каждого класса в дереве согласно 𝙼𝚁𝙾 – следуя только __𝚋𝚊𝚜𝚎𝚜__ на уровне каждого класса и применяя ссылку __𝚌𝚕𝚊𝚜𝚜__ экземпляра только один раз.»

>>> 𝙸.𝚊𝚝𝚝𝚛𝟷
𝙰𝚝𝚝𝚛𝚒𝚋𝚞𝚝𝚎𝙴𝚛𝚛𝚘𝚛: '𝙲𝟸' 𝚘𝚋𝚓𝚎𝚌𝚝 𝚑𝚊𝚜 𝚗𝚘 𝚊𝚝𝚝𝚛𝚒𝚋𝚞𝚝𝚎 '𝚊𝚝𝚝𝚛𝟷'
# Хотя __𝚌𝚕𝚊𝚜𝚜__ класса нормально не проходит
# ошибку атрибутов: объект 𝙲𝟸 не имеет атрибута 𝚊𝚝𝚝𝚛𝟷»

Это происходит потому, что алгоритм наследования для экземпляров работает следующим образом:

𝟷. Если атрибут ищется в экземпляре, 𝙿𝚢𝚝𝚑𝚘𝚗 выполняет следующие шаги:
а) Выполняется поиск в __𝚍𝚒𝚌𝚝__ экземпляра.
б) Если не найдено, то ищется во всех классах в __𝚖𝚛𝚘__, найденном в __𝚌𝚕𝚊𝚜𝚜__ экземпляра.
в) Если не найдено, то ищется во всех классах в __𝚖𝚛𝚘__, найденном в __𝚌𝚕𝚊𝚜𝚜__ класса.
г) Если не найдено, то ошибка 𝙰𝚝𝚝𝚛𝚒𝚋𝚞𝚝𝚎𝙴𝚛𝚛𝚘𝚛.

В данном случае атрибут 𝚊𝚝𝚝𝚛𝟷 определен в нескольких местах: в метаклассах 𝙼𝟷 (значение 𝟷) и 𝙼𝟸 (значение 𝟸), а также в классах 𝙲𝟷 (значение 𝟹) и 𝙲𝟸 (значение 𝟺). При обращении к 𝙸.𝚊𝚝𝚝𝚛𝟷 𝙿𝚢𝚝𝚑𝚘𝚗 следует алгоритму наследования для экземпляров:

🔘 Сначала ищет в __𝚍𝚒𝚌𝚝__ экземпляра 𝙸 (не найдено)
🔘 Затем ищет в 𝙼𝚁𝙾 класса 𝙲𝟸: ['𝙲𝟸', '𝙲𝟷', '𝚘𝚋𝚓𝚎𝚌𝚝']
🔘 Находит 𝚊𝚝𝚝𝚛𝟷 в классе 𝙲𝟸 со значением 𝟺

Таким образом, код выведет 𝟺, поскольку экземпляр 𝙸 наследует атрибут 𝚊𝚝𝚝𝚛𝟷 от своего класса 𝙲𝟸, а не от метаклассов 𝙼𝟷 или 𝙼𝟸.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤡3👍1👎1
🧩 Что выведет код?
Anonymous Quiz
16%
1
51%
2
19%
3
13%
Error
👍3👎1👏1🖕1
Код демонстрирует работу дескриптора не данных. Класс 𝙳 определяет только метод __𝚐𝚎𝚝__, но не определяет __𝚜𝚎𝚝__, что делает его дескриптором не данных.

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

«И наоборот, если этот дескриптор не определяет __𝚜𝚎𝚝__, то имя в словаре экземпляра скроет имя в классе согласно нормальному наследованию».

В коде происходит следующее:

🔘 Создается экземпляр 𝙸 класса 𝙲
🔘 При обращении к 𝙸.𝚍 вызывается метод __𝚐𝚎𝚝__ дескриптора 𝙳𝟸, выводится '__𝚐𝚎𝚝__'
🔘 В словарь экземпляра 𝙸.__𝚍𝚒𝚌𝚝__ добавляется ключ '𝚍' со значением '𝚜𝚙𝚊𝚖'
🔘 При повторном обращении к 𝙸.𝚍 имя '𝚍' в словаре экземпляра скрывает дескриптор в классе, поэтому выводится '𝚜𝚙𝚊𝚖'

>>> 𝙸.𝚍 # Доступ к унаследованному дескриптору не данных
__𝚐𝚎𝚝__
>>> 𝙸.__𝚍𝚒𝚌𝚝__['𝚍'] = '𝚜𝚙𝚊𝚖'
>>> 𝙸.𝚍 # Скрываем имя в классе согласно правилам нормального наследования экземпляров
'𝚜𝚙𝚊𝚖'

Это отличается от дескрипторов данных, которые перекрывают имена в словаре экземпляра благодаря наличию метода __𝚜𝚎𝚝__.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤡2👍1👎1
🧩 Что выведет код?
Anonymous Quiz
57%
A.x <class '__main__.B'>
19%
A.x
12%
None
12%
Error
👍2👎1
Данный код демонстрирует работу методов метаклассов. Класс 𝙰 наследуется от 𝚝𝚢𝚙𝚎, что делает его метаклассом. Класс 𝙱 создается с использованием метакласса 𝙰 через синтаксис 𝚖𝚎𝚝𝚊𝚌𝚕𝚊𝚜𝚜=𝙰.

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

🔘 «Методы метакласса можно вызывать как обычные методы экземпляров, но они получают экземпляр метакласса — сам класс»
🔘 «Метод класса: передается экземпляр класса, не экземпляр самого класса. Метод метакласса: передается сам класс»

В данном случае:
🔘 Метод 𝚡 определен в метаклассе 𝙰
🔘 При вызове 𝙱.𝚡() метод получает сам класс 𝙱 как аргумент 𝚌𝚕𝚜
🔘 Функция 𝚙𝚛𝚒𝚗𝚝 выводит строку '𝙰.𝚡' и представление класса 𝙱 в виде <𝚌𝚕𝚊𝚜𝚜 '__𝚖𝚊𝚒𝚗__.𝙱'>

Методы метаклассов предназначены для управления данными уровня класса и доступны непосредственно на уровне класса без необходимости явного объявления ссылок.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👎2
🪤 Что выведет код?
Anonymous Quiz
3%
Ni!
7%
Ni!Ni!
69%
Ni!Ni!Ni!Ni!
21%
Error
👍3👎1
В данном коде демонстрируется ручное расширение класса — добавление нового метода к классу после его создания.

Принцип работает, потому что методы всегда можно присваивать классу после того, как он был создан. До тех пор пока присваиваемые методы являются функциями с дополнительным первым аргументом для получения нового экземпляра 𝚜𝚎𝚕𝚏».

Разберем выполнение кода по шагам:

🔘 Создается класс 𝙲𝚕𝚒𝚎𝚗𝚝𝟷 с конструктором, который принимает 𝚟𝚊𝚕𝚞𝚎 и сохраняет его в атрибут экземпляра
🔘 Определяется функция 𝚎𝚐𝚐𝚜𝚏𝚞𝚗𝚌(𝚘𝚋𝚓), которая принимает объект и возвращает 𝚘𝚋𝚓.𝚟𝚊𝚕𝚞𝚎 ∗ 𝟺
🔘 Происходит присваивание 𝙲𝚕𝚒𝚎𝚗𝚝𝟷.𝚎𝚐𝚐𝚜 = 𝚎𝚐𝚐𝚜𝚏𝚞𝚗𝚌 — функция становится методом класса
🔘 Создается экземпляр 𝚇 = 𝙲𝚕𝚒𝚎𝚗𝚝𝟷('𝙽𝚒!'), где 𝚟𝚊𝚕𝚞𝚎 становится '𝙽𝚒!'
🔘 Вызывается 𝚇.𝚎𝚐𝚐𝚜()

При вызове 𝚇.𝚎𝚐𝚐𝚜() происходит следующее:
− Python автоматически передает экземпляр 𝚇 как первый аргумент в функцию 𝚎𝚐𝚐𝚜𝚏𝚞𝚗𝚌
− Функция получает 𝚘𝚋𝚓 = 𝚇, где 𝚇.𝚟𝚊𝚕𝚞𝚎 = '𝙽𝚒!'
− Выполняется 𝚛𝚎𝚝𝚞𝚛𝚗 𝚘𝚋𝚓.𝚟𝚊𝚕𝚞𝚎 ∗ 𝟺, что дает '𝙽𝚒!' ∗ 𝟺 = '𝙽𝚒!𝙽𝚒!𝙽𝚒!𝙽𝚒!'

Данный аргумент может использоваться для обращения к информации о состоянии, доступной из экземпляра класса, хотя функции определены независимо от класса.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👎1🫡1
Что выведет команда 'python - < showargs.py a b -c'?
Anonymous Quiz
20%
['-', 'a', 'b', '-c']
48%
['showargs.py', 'a', 'b', '-c']
17%
['python', '-', 'a', 'b', '-c']
15%
Error
👍1👎1
В данной задаче рассматривается запуск кода с использованием символа «−» для чтения из стандартного входного потока.

Марк Лутц, «Изучаем 𝙿𝚢𝚝𝚑𝚘𝚗», Приложение А тома 2:

«Другие варианты специфицирования формата кода позволяют предоставлять интерпретатору Python код, подлежащий запуску, в самой командной строке (−𝚌) и принимать код из стандартного входного потока (символ − означает чтение из канала или входного потока, перенаправленного в файл)»

Команда «𝚙𝚢𝚝𝚑𝚘𝚗 − < 𝚜𝚑𝚘𝚠𝚊𝚛𝚐𝚜.𝚙𝚢 𝚊 𝚋 −𝚌» работает следующим образом:

🔘 Символ «−» указывает интерпретатору 𝙿𝚢𝚝𝚑𝚘𝚗 читать код из стандартного входного потока
🔘 Оператор перенаправления «<» направляет содержимое файла 𝚜𝚑𝚘𝚠𝚊𝚛𝚐𝚜.𝚙𝚢 в стандартный входной поток
🔘 Аргументы «𝚊 𝚋 −𝚌» передаются как аргументы командной строки

В результате:
🔘 𝚜𝚢𝚜.𝚊𝚛𝚐𝚟[𝟶] = '−' (символ, указывающий на чтение из стандартного входного потока)
🔘 𝚜𝚢𝚜.𝚊𝚛𝚐𝚟[𝟷] = '𝚊'
🔘 𝚜𝚢𝚜.𝚊𝚛𝚐𝚟[𝟸] = '𝚋'
🔘 𝚜𝚢𝚜.𝚊𝚛𝚐𝚟[𝟹] = '−𝚌'

Поэтому правильный ответ: ['−', '𝚊', '𝚋', '−𝚌']

Это демонстрирует, что при использовании символа «−» для чтения из стандартного входного потока, 𝙿𝚢𝚝𝚑𝚘𝚗 помещает сам символ «−» в качестве первого элемента 𝚜𝚢𝚜.𝚊𝚛𝚐𝚟, а все остальные аргументы командной строки добавляются после него.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤯2👎1
Разработчики Unix давно придумали протокол для назначения программам запускаемого кода. В большинстве систем Unix (включая такие как Linux и macOS) можно встретить файлы сценариев оболочки, содержащие первые строки, которые задают, какая именно программа должна использоваться для выполнения содержимого файла. Эти строки начинаются с символов #!, за которыми указывается полное имя интерпретатора.

Примеры использования:
🔘 #! /𝚞𝚜𝚛/𝚋𝚒𝚗/𝚙𝚢𝚝𝚑𝚘𝚗
🔘 #! /𝚞𝚜𝚛/𝚋𝚒𝚗/𝚎𝚗𝚟 𝚙𝚢𝚝𝚑𝚘𝚗

Символы #! в начале файла называются «𝚜𝚑𝚎𝚋𝚊𝚗𝚐» и служат для указания операционной системе, какой интерпретатор использовать для выполнения данного файла. Это позволяет запускать скрипты напрямую без явного указания интерпретатора.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5👎1
Когда хотел просто поиграть, но случайно спас марсианскую базу…

Советуем пройти космическую одиссею, которую сделали вместе с «МойОфис». Всего 10 минут, три локации и задачки по Go, которые под силу трушному гоферу. В общем, некогда объяснять — срочно помогите главным героям спасти марсианских колонизаторов.

Кстати, первые 10 игроков с максимальным результатом получат тематические подарки: комплект космической еды и крутой мерч.

Запрыгивайте в квест: https://tprg.ru/EdHP

Реклама