Что такое итераторы/генераторы/генераторные выражения, чем они отличаются и когда и как все это нужно использовать.
Ответ
Здесь важно, чтобы кандидат понимал различие и мог с той или иной степенью погружения рассказать про эти различия. Если кратко, то итератор в Python – это любой объект, который использует метод next() для получения следующего значения последовательности. Генератор – функция, которая производит или выдает последовательность значений с использованием метода yield. Концептуально, итератор — это механизм поэлементного обхода данных, а генератор позволяет отложено создавать результат при итерации. Генератор может создавать результат на основе какого-то алгоритма или брать элементы из источника данных (коллекция, файлы, сетевое подключения и др.) и изменять их.
Подробности доступны в очень большом количестве статей с той или иной степенью погружения в детали, например, здесь.
#junior
@python_job_interview
Ответ
Здесь важно, чтобы кандидат понимал различие и мог с той или иной степенью погружения рассказать про эти различия. Если кратко, то итератор в Python – это любой объект, который использует метод next() для получения следующего значения последовательности. Генератор – функция, которая производит или выдает последовательность значений с использованием метода yield. Концептуально, итератор — это механизм поэлементного обхода данных, а генератор позволяет отложено создавать результат при итерации. Генератор может создавать результат на основе какого-то алгоритма или брать элементы из источника данных (коллекция, файлы, сетевое подключения и др.) и изменять их.
Подробности доступны в очень большом количестве статей с той или иной степенью погружения в детали, например, здесь.
#junior
@python_job_interview
👍18🔥4❤1
Что такое абстрактная фабрика, как ее реализовать и зачем ее применяют?
Ответ
Абстрактная фабрика — порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.
Допустим у нас есть 2 операционные системы Mac Os и Linux, нам необходимо реализовать произвольное окно с кнопкой или кнопками в каждой из этих операционных систем. Естественно окна и кнопки в MacOs и linux выглядят по разному, так сказать имеют разные стили оформления.
Наша задача состоит в том, что бы создать универсальный интерфейс который будет создавать окно с кнопкой в не зависимости от того на какой операционной системе запущенна программа.
Т.е. функции которая будет конструировать окно с кнопкой, будет работать вне зависимости от того какое окно мы захотим создать
Для начала опишем класс абстрактной фабрики картинка1.
Обратите внимание на строки return cls.Window(name) и return cls.Button(name), как видите в обоих случаях мы возвращаем некий класс(cls) у которого есть подкласс Window\Button, но в настоящий момент мы не описали ни класс Window, ни класс Button, давайте это сделаем.
➡️ Читать дальше
@python_job_interview
Ответ
Абстрактная фабрика — порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.
Допустим у нас есть 2 операционные системы Mac Os и Linux, нам необходимо реализовать произвольное окно с кнопкой или кнопками в каждой из этих операционных систем. Естественно окна и кнопки в MacOs и linux выглядят по разному, так сказать имеют разные стили оформления.
Наша задача состоит в том, что бы создать универсальный интерфейс который будет создавать окно с кнопкой в не зависимости от того на какой операционной системе запущенна программа.
Т.е. функции которая будет конструировать окно с кнопкой, будет работать вне зависимости от того какое окно мы захотим создать
Для начала опишем класс абстрактной фабрики картинка1.
Обратите внимание на строки return cls.Window(name) и return cls.Button(name), как видите в обоих случаях мы возвращаем некий класс(cls) у которого есть подкласс Window\Button, но в настоящий момент мы не описали ни класс Window, ни класс Button, давайте это сделаем.
➡️ Читать дальше
@python_job_interview
👍12🔥3
Что такое цикломатическая сложность ? Какие бывают метрики для измерения сложности кода ?
Ответ
Цикломатическая сложность — это мера количества независимых путей кода в вашем приложении. Путь — это последовательность операторов, которой интерпретатор может следовать, чтобы добраться до конца приложения.
Один из способов думать о цикломатической сложности и путях кода — это представить, что ваш код в виде железнодорожной сети.
Для поездки вам может понадобиться смена поезда, чтобы добраться до пункта назначения. Железнодорожная система метрополитена Лиссабона в Португалии проста и удобна для навигации. Цикломатическая сложность любой поездки равна количеству линий, по которым вам нужно пройти.
Метрики для измерения сложности
Вот некоторые метрики сложности для языков программирования. Они применимы ко многим языкам, а не только к Python.
Количество строк кода
LOC ( Lines of Code), или Количество строк, является самой грубой мерой сложности. Это спорный вопрос , есть ли прямая связь между количеством строк кода и сложностью приложения, но косвенная корреляция очевидна. В конце концов, программа с 5 строками, вероятно, проще, чем программа с 5 миллионами.
При просмотре метрик Python мы стараемся игнорировать пустые строки и строки, содержащие комментарии.
Количество строк кода можно подсчитать с помощью команды wc в Linux и Mac OS, где file.py — это имя файла, который вы хотите измерить:
$ wc -l file.py
Если вы хотите подсчитать строки во всех файлах в папке путем рекурсивного поиска в файлах *.py, вы можете объединить wc с командой find:
$ find . -name \*.py | xargs wc -l
В ответе вы увидите общее количество строк.
Почему строки кода используются для количественной оценки объема кода в вашем приложении? Предполагается, что строка кода примерно соответствует одной операцией.
В Python рекомендуется размещать по одной инструкции в каждой строке.
➡️ Читать дальше
@python_job_interview
Ответ
Цикломатическая сложность — это мера количества независимых путей кода в вашем приложении. Путь — это последовательность операторов, которой интерпретатор может следовать, чтобы добраться до конца приложения.
Один из способов думать о цикломатической сложности и путях кода — это представить, что ваш код в виде железнодорожной сети.
Для поездки вам может понадобиться смена поезда, чтобы добраться до пункта назначения. Железнодорожная система метрополитена Лиссабона в Португалии проста и удобна для навигации. Цикломатическая сложность любой поездки равна количеству линий, по которым вам нужно пройти.
Метрики для измерения сложности
Вот некоторые метрики сложности для языков программирования. Они применимы ко многим языкам, а не только к Python.
Количество строк кода
LOC ( Lines of Code), или Количество строк, является самой грубой мерой сложности. Это спорный вопрос , есть ли прямая связь между количеством строк кода и сложностью приложения, но косвенная корреляция очевидна. В конце концов, программа с 5 строками, вероятно, проще, чем программа с 5 миллионами.
При просмотре метрик Python мы стараемся игнорировать пустые строки и строки, содержащие комментарии.
Количество строк кода можно подсчитать с помощью команды wc в Linux и Mac OS, где file.py — это имя файла, который вы хотите измерить:
$ wc -l file.py
Если вы хотите подсчитать строки во всех файлах в папке путем рекурсивного поиска в файлах *.py, вы можете объединить wc с командой find:
$ find . -name \*.py | xargs wc -l
В ответе вы увидите общее количество строк.
Почему строки кода используются для количественной оценки объема кода в вашем приложении? Предполагается, что строка кода примерно соответствует одной операцией.
В Python рекомендуется размещать по одной инструкции в каждой строке.
➡️ Читать дальше
@python_job_interview
👍15🔥2❤1👎1
Зачем нужен __new__ в Python и каково его практическое применение?
Ответ
Когда вы создаете экземпляр класса, Python сначала вызывает метод __new() для создания объекта, а затем вызывает метод init() __для инициализации атрибутов объекта.
__new() — это статический метод класса объекта. Он имеет следующую сигнатуру:
object.new(class, *args, **kwargs)__
Первый аргумент метода new — это класс нового объекта, который вы хотите создать. Параметры *args и **kwargs должны совпадать с параметрами init() класса. Метод new() также их использует.
Чтобы создать объект класса, нужно вызывать метод super().new().
Практическое применение new
Как правило, init() используется для инициализации вновь созданного объекта, а new() для управления способом создания объекта. Мы также можем использовать new() для инициализации атрибутов объекта, но по логике это должно быть внутри init().
Однако одним из частых практических применений new() является ограничение количества объектов, созданных из класса.
Примеры частных случаев использования new
Создание одноэлементного шаблона (хотя это не единственный способ).
Динамическое расширение классов из внешних модулей без фактического редактирования исходного кода.
Настройка классов в метаклассе (аналогично использованию call)
Расширение неизменяемого класса datetime.datetime. Это нужно, чтобы вернуть текущее время, если он создается без аргументов, и результат вызова strptime для аргумента, если он вызывается с одним строковым аргументом.
@python_job_interview
Ответ
Когда вы создаете экземпляр класса, Python сначала вызывает метод __new() для создания объекта, а затем вызывает метод init() __для инициализации атрибутов объекта.
__new() — это статический метод класса объекта. Он имеет следующую сигнатуру:
object.new(class, *args, **kwargs)__
Первый аргумент метода new — это класс нового объекта, который вы хотите создать. Параметры *args и **kwargs должны совпадать с параметрами init() класса. Метод new() также их использует.
Чтобы создать объект класса, нужно вызывать метод super().new().
Практическое применение new
Как правило, init() используется для инициализации вновь созданного объекта, а new() для управления способом создания объекта. Мы также можем использовать new() для инициализации атрибутов объекта, но по логике это должно быть внутри init().
Однако одним из частых практических применений new() является ограничение количества объектов, созданных из класса.
Примеры частных случаев использования new
Создание одноэлементного шаблона (хотя это не единственный способ).
Динамическое расширение классов из внешних модулей без фактического редактирования исходного кода.
Настройка классов в метаклассе (аналогично использованию call)
Расширение неизменяемого класса datetime.datetime. Это нужно, чтобы вернуть текущее время, если он создается без аргументов, и результат вызова strptime для аргумента, если он вызывается с одним строковым аргументом.
@python_job_interview
👍13🔥3❤1
Расскажите про асинхронный режим в сравнении с многопоточностью на Python?
Ответ
Для асинхронного программирования в Python помимо зеленых потоков, сопрограмм и обратных вызовов используется мощная библиотека Asyncio. Библиотека доступна для использования с версии Python 3.5. Удобно и то, что она полностью встроена в ядро.
Асинхронный режим в сравнении с многопоточностью имеет ряд преимуществ:
- Функции асинхронности намного легче потоков. Это значит, что сотни и тысячи асинхронных операций, выполняемых одновременно, будут расходовать гораздо меньше ресурсов, чем сотни и тысячи потоков.
- По сравнению с потоками асинхронными операциями намного легче управлять. Например, их можно отменять, задействовав объект Task — asyncio.create_task().
В цикле асинхронных событий задачи выполняются в одном потоке, их проще понимать, контролировать и отслеживать.
- Фактически асинхронность идет рука об руку с многопроцессорностью в Python. Есть возможность использовать asyncio.run_in_executor() для задач, которые интенсивно используют центральный процессор. Также асинхронность решает проблемы потоков:
- Библиотека Asyncio осуществляет переключение контекста на уровне программы, а не процессора. Используется цикл событий.
- Отсутствие состояние гонки. Поскольку с Asyncio переключение контекста осуществляется в заранее созданных точках, код не испытывает проблему гонки.
- Запускается одна сопрограмма, которая переключается только в заданных вами точках.
- Гораздо меньшее ресурсное голодание. Конечно, в Asyncio имеется пул потоков, который может влиять на расходование ресурсов (запуск большого количества процессов). Но тем не менее запуск сопрограмм в одном потоке задействует гораздо меньше памяти на выполнение процессов.
Взаимная блокировка. Отсутствие гонки потоков практически сводит к нулю различного рода блокировки.
Есть и небольшие недостатки использования асинхронной библиотеки Asyncio. Во избежание блокировки цикла событий и временных потерь на выполнении асинхронных функций весь код также должен быть асинхронным.
Тем не менее мы можем наблюдать динамику увеличения количества асинхронных библиотек и специального программного обеспечения, предоставляющего асинхронные неблокирующие версии баз данных, сетевых протоколов. Например, репозиторий aio-libs — набор библиотек, созданный на основе Asyncio, в котором представлена асинхронная библиотека aiohttp для веб-доступа. Или же в каталоге пакетов Python также много библиотек с async.
Даже такие монстры как Facebook, Twitter, фреймворк React Native и база данных RocksDB используют асинхронность.
@python_job_interview
Ответ
Для асинхронного программирования в Python помимо зеленых потоков, сопрограмм и обратных вызовов используется мощная библиотека Asyncio. Библиотека доступна для использования с версии Python 3.5. Удобно и то, что она полностью встроена в ядро.
Асинхронный режим в сравнении с многопоточностью имеет ряд преимуществ:
- Функции асинхронности намного легче потоков. Это значит, что сотни и тысячи асинхронных операций, выполняемых одновременно, будут расходовать гораздо меньше ресурсов, чем сотни и тысячи потоков.
- По сравнению с потоками асинхронными операциями намного легче управлять. Например, их можно отменять, задействовав объект Task — asyncio.create_task().
В цикле асинхронных событий задачи выполняются в одном потоке, их проще понимать, контролировать и отслеживать.
- Фактически асинхронность идет рука об руку с многопроцессорностью в Python. Есть возможность использовать asyncio.run_in_executor() для задач, которые интенсивно используют центральный процессор. Также асинхронность решает проблемы потоков:
- Библиотека Asyncio осуществляет переключение контекста на уровне программы, а не процессора. Используется цикл событий.
- Отсутствие состояние гонки. Поскольку с Asyncio переключение контекста осуществляется в заранее созданных точках, код не испытывает проблему гонки.
- Запускается одна сопрограмма, которая переключается только в заданных вами точках.
- Гораздо меньшее ресурсное голодание. Конечно, в Asyncio имеется пул потоков, который может влиять на расходование ресурсов (запуск большого количества процессов). Но тем не менее запуск сопрограмм в одном потоке задействует гораздо меньше памяти на выполнение процессов.
Взаимная блокировка. Отсутствие гонки потоков практически сводит к нулю различного рода блокировки.
Есть и небольшие недостатки использования асинхронной библиотеки Asyncio. Во избежание блокировки цикла событий и временных потерь на выполнении асинхронных функций весь код также должен быть асинхронным.
Тем не менее мы можем наблюдать динамику увеличения количества асинхронных библиотек и специального программного обеспечения, предоставляющего асинхронные неблокирующие версии баз данных, сетевых протоколов. Например, репозиторий aio-libs — набор библиотек, созданный на основе Asyncio, в котором представлена асинхронная библиотека aiohttp для веб-доступа. Или же в каталоге пакетов Python также много библиотек с async.
Даже такие монстры как Facebook, Twitter, фреймворк React Native и база данных RocksDB используют асинхронность.
@python_job_interview
👍30🔥2❤1
Почему в Python-сообществе называют способ передачи аргументов передачей через присваивание, а не передачей ссылок по значению?
Чем принципиально имя переменной в Python отличается от ссылки на объект в Java? Поведение не выглядит даже немного отличающимся
Ответ
«Переменная» в Python — это не традиционная переменная. Вместо этого это привязка к объекту. По сути, указатель, но на объект, а не на ячейку памяти. Со списком это легко увидеть .
Вот что происходит под капотом, более или менее:
Вы создаете объект списка со значением [1, 2, 3, 4]. Мы назовем этот идентификатор объекта 1. Затем вы привяжете имя «list_one» к идентификатору объекта 1. Вы говорите ему привязать «list_two» к тому же объекту, к которому привязан «list_one». На данный момент они оба привязаны к идентификатору объекта 1. Вы изменяете объект с идентификатором 1. Поскольку список является изменяемым (mutable), содержимое может измениться, и оба имени могут оставаться привязанными к идентификатору 1. Поскольку и «list_one», и «list_two» связаны с идентификатором объекта 1 , печать любого из них возвращает [1, 2, 3, 4, 5].
Что делать с такими вещами, как целые числа и строки? Почему они не ведут себя так же?
Происходит то же самое, но тип объекта имеет значение Рисунок 2.
Вы создаете целочисленный объект со значением 1. Мы назовем этот объект с идентификатором 1. Затем вы привяжете имя «int_one» к объекту с идентификатором 1. Вы говорите ему привязать «int_two» к тому же объекту, на который указывает «int_one».
Они оба связаны с идентификатором объекта 1. Вы пытаетесь изменить идентификатор объекта 1, но он неизменяем (immutable), поэтому вы не можете изменить содержимое. Из-за этого он просматривает значение объекта с идентификатором 1, добавляет к нему 10, чтобы получить 11, и создает новый целочисленный объект (идентификатор 2) со значением 11. Затем он повторно привязывает «int_two» к объекту с идентификатором 2, но оставляет «int_one» в покое. Поскольку «int_one» и «int_two» теперь привязаны к разным объектам, их печать даст разные результаты.Если вы снова измените значение «int_two», будет создан третий объект с новым значением, а второй объект останется в памяти без привязок. Не беспокойтесь о потраченной впустую памяти - нужна сборка мусора.
===========================================
В Python аргументы передаются путем присваивания.(official guide)
Фактические параметры (аргументы) вызова функции вводятся в локальную таблицу символов вызываемой функции при ее вызове; таким образом, аргументы передаются с использованием вызова по значению, «где значение всегда является ссылкой на объект, а не значением объекта», там же сноска добавляет:
На самом деле, «вызов по ссылке на объект» был бы лучшим описанием, поскольку, если передается изменяемый (mutable) объект, вызывающая сторона увидит любые изменения, внесенные в нее вызываемой стороной (элементы, вставленные в список).
@python_job_interview
Чем принципиально имя переменной в Python отличается от ссылки на объект в Java? Поведение не выглядит даже немного отличающимся
Ответ
«Переменная» в Python — это не традиционная переменная. Вместо этого это привязка к объекту. По сути, указатель, но на объект, а не на ячейку памяти. Со списком это легко увидеть .
Вот что происходит под капотом, более или менее:
Вы создаете объект списка со значением [1, 2, 3, 4]. Мы назовем этот идентификатор объекта 1. Затем вы привяжете имя «list_one» к идентификатору объекта 1. Вы говорите ему привязать «list_two» к тому же объекту, к которому привязан «list_one». На данный момент они оба привязаны к идентификатору объекта 1. Вы изменяете объект с идентификатором 1. Поскольку список является изменяемым (mutable), содержимое может измениться, и оба имени могут оставаться привязанными к идентификатору 1. Поскольку и «list_one», и «list_two» связаны с идентификатором объекта 1 , печать любого из них возвращает [1, 2, 3, 4, 5].
Что делать с такими вещами, как целые числа и строки? Почему они не ведут себя так же?
Происходит то же самое, но тип объекта имеет значение Рисунок 2.
Вы создаете целочисленный объект со значением 1. Мы назовем этот объект с идентификатором 1. Затем вы привяжете имя «int_one» к объекту с идентификатором 1. Вы говорите ему привязать «int_two» к тому же объекту, на который указывает «int_one».
Они оба связаны с идентификатором объекта 1. Вы пытаетесь изменить идентификатор объекта 1, но он неизменяем (immutable), поэтому вы не можете изменить содержимое. Из-за этого он просматривает значение объекта с идентификатором 1, добавляет к нему 10, чтобы получить 11, и создает новый целочисленный объект (идентификатор 2) со значением 11. Затем он повторно привязывает «int_two» к объекту с идентификатором 2, но оставляет «int_one» в покое. Поскольку «int_one» и «int_two» теперь привязаны к разным объектам, их печать даст разные результаты.Если вы снова измените значение «int_two», будет создан третий объект с новым значением, а второй объект останется в памяти без привязок. Не беспокойтесь о потраченной впустую памяти - нужна сборка мусора.
===========================================
В Python аргументы передаются путем присваивания.(official guide)
Фактические параметры (аргументы) вызова функции вводятся в локальную таблицу символов вызываемой функции при ее вызове; таким образом, аргументы передаются с использованием вызова по значению, «где значение всегда является ссылкой на объект, а не значением объекта», там же сноска добавляет:
На самом деле, «вызов по ссылке на объект» был бы лучшим описанием, поскольку, если передается изменяемый (mutable) объект, вызывающая сторона увидит любые изменения, внесенные в нее вызываемой стороной (элементы, вставленные в список).
@python_job_interview
👍13🔥6
✒️ Собеседование Middle Python Engineer
00:00 - Опыт Разработки
06:08 - План Интервью
07:00 - _slots__
07:41 - match/case
08:24 - _call__
08:55 - Конструктор класса
10:10 - hash/hash table
11:12 - Доступ к элементам словаря
11:56 - Генераторы и итераторы
13:57 - Контекстные менеджеры
16:05 - Инкапсуляция
20:00 - Django vs DRF
22:07 - SerializerMethodField
22:40 - to_internal_value/to_representation
25:05 - Какой способ построения api с помощью DRF более удобный
25:57 - Миксины
27:34 - Django ORM
30:26 - @sync_to_async/@async_to_sync
31:23 - n+1
32:25 - django-debug-toolbar
33:27 - Когда prefetch_related увеличивает количество запросов
35:40 - Когда queryset делает запрос
38:01 - Онлайн кодинг
53:40 - БД
01:02:40 - Асинхронность, многопоточность, многопроцессорность
01:07:26 - Фидбек
https://www.youtube.com/watch?v=nbSbjbAwg9M
@python_job_interview
00:00 - Опыт Разработки
06:08 - План Интервью
07:00 - _slots__
07:41 - match/case
08:24 - _call__
08:55 - Конструктор класса
10:10 - hash/hash table
11:12 - Доступ к элементам словаря
11:56 - Генераторы и итераторы
13:57 - Контекстные менеджеры
16:05 - Инкапсуляция
20:00 - Django vs DRF
22:07 - SerializerMethodField
22:40 - to_internal_value/to_representation
25:05 - Какой способ построения api с помощью DRF более удобный
25:57 - Миксины
27:34 - Django ORM
30:26 - @sync_to_async/@async_to_sync
31:23 - n+1
32:25 - django-debug-toolbar
33:27 - Когда prefetch_related увеличивает количество запросов
35:40 - Когда queryset делает запрос
38:01 - Онлайн кодинг
53:40 - БД
01:02:40 - Асинхронность, многопоточность, многопроцессорность
01:07:26 - Фидбек
https://www.youtube.com/watch?v=nbSbjbAwg9M
@python_job_interview
👍28👏3❤2🔥1😢1
Расскажите о ПО позволяющее создавать виртуальное окружение в Python.
Ответ
Программное обеспечение, которое позволяет создавать виртуальные окружения в Python можно разделить на те, что входят в стандартную библиотеку Python и не входят в нее. Сделаем краткий обзор доступных инструментов (хороший пост на эту тем есть на stackoverflow).
Начнем с инструментов, которые входят в PyPI. Если кто не знает PyPI – это Python Package Index (PyPI) – репозиторий пакетов Python, доступный для любого разработчика и пользователя Python ().
virtualenv
Это, наверное, одни из самых популярных инструментов, позволяющих создавать виртуальные окружения. Он прост в установке и использовании. В сети довольно много руководств по virtualenv, самые интересные, на наш взгляд, будут собраны в конце урока в разделе “Полезные ссылки”. В общем, этот инструмент нужно обязательно освоить, как минимум, потому что описание развертывания и использования многих систем, созданных с использованием Python, включает в себя процесс создания виртуального окружения с помощью virtualenv.
pyenv
Инструмент для изоляции версий Python. Чаще всего применяется, когда на одной машине вам нужно иметь несколько версий интерпретатора для тестирования на них разрабатываемого вами ПО.
virtualenvwrapper
Virtualenvwrapper – это обертка для virtualenv позволяющая хранить все изолированные окружения в одном месте, создавать их, копировать и удалять. Предоставляет удобный способ переключения между окружениями и возможность расширять функционал за счет plug-in’ов.
Существуют ещё инструменты и plug-in’ы, выполняющие работу по изоляции частей системы Python, но мы их не будем рассматривать.
Инструменты, входящие в стандартную библиотеку Python.
venv
Этот модуль появился в Python3 и не может быть использован для решения задачи изоляции в Python2. По своему функционалу очень похож на virtualenv. Если вы работаете с третьим Python, то можете смело использовать данный инструмент.
➡️ Подробнее
@python_job_interview
Ответ
Программное обеспечение, которое позволяет создавать виртуальные окружения в Python можно разделить на те, что входят в стандартную библиотеку Python и не входят в нее. Сделаем краткий обзор доступных инструментов (хороший пост на эту тем есть на stackoverflow).
Начнем с инструментов, которые входят в PyPI. Если кто не знает PyPI – это Python Package Index (PyPI) – репозиторий пакетов Python, доступный для любого разработчика и пользователя Python ().
virtualenv
Это, наверное, одни из самых популярных инструментов, позволяющих создавать виртуальные окружения. Он прост в установке и использовании. В сети довольно много руководств по virtualenv, самые интересные, на наш взгляд, будут собраны в конце урока в разделе “Полезные ссылки”. В общем, этот инструмент нужно обязательно освоить, как минимум, потому что описание развертывания и использования многих систем, созданных с использованием Python, включает в себя процесс создания виртуального окружения с помощью virtualenv.
pyenv
Инструмент для изоляции версий Python. Чаще всего применяется, когда на одной машине вам нужно иметь несколько версий интерпретатора для тестирования на них разрабатываемого вами ПО.
virtualenvwrapper
Virtualenvwrapper – это обертка для virtualenv позволяющая хранить все изолированные окружения в одном месте, создавать их, копировать и удалять. Предоставляет удобный способ переключения между окружениями и возможность расширять функционал за счет plug-in’ов.
Существуют ещё инструменты и plug-in’ы, выполняющие работу по изоляции частей системы Python, но мы их не будем рассматривать.
Инструменты, входящие в стандартную библиотеку Python.
venv
Этот модуль появился в Python3 и не может быть использован для решения задачи изоляции в Python2. По своему функционалу очень похож на virtualenv. Если вы работаете с третьим Python, то можете смело использовать данный инструмент.
➡️ Подробнее
@python_job_interview
👍17❤3🔥3
Интервью Junior Python разработчик. Лайф кодинг
https://www.youtube.com/watch?v=c4nysYAufF0
@python_job_interview
https://www.youtube.com/watch?v=c4nysYAufF0
@python_job_interview
👍20😢1
С помощью чего можно получить логический xor двух переменных в Python?
Ответ
В Пайтоне есть оператор побитового XOR, который также отлично работает с логическими значениями, но его поведение легко повторить.
Исключающее "или" ведёт себя как обычное "или" за одним исключением — два True на входе даёт результат False.
Можно так и поступить — возвращать False в этом особом случае, во всех остальных использовать or.
Однако, если мы внимательно посмотрим на результаты, то окажется, что нам нужно True если значения не равны. Поэтому реализацию XOR можно записать проще (картинка 2).
@python_job_interview
Ответ
В Пайтоне есть оператор побитового XOR, который также отлично работает с логическими значениями, но его поведение легко повторить.
Исключающее "или" ведёт себя как обычное "или" за одним исключением — два True на входе даёт результат False.
Можно так и поступить — возвращать False в этом особом случае, во всех остальных использовать or.
Однако, если мы внимательно посмотрим на результаты, то окажется, что нам нужно True если значения не равны. Поэтому реализацию XOR можно записать проще (картинка 2).
@python_job_interview
👍11🔥3
🔥 Полезнейшая Подборка каналов
🐍 Python
@pythonl – python для датасаентиста
@pro_python_code – python на русском
@python_job_interview – подготовка к Python собеседованию
@python_testit тесты на python
@pythonlbooks - книги Python
@Django_pythonl django
@python_djangojobs - работа Python
🦾 Machine learning
@ai_machinelearning_big_data – все о машинном обучении
@data_analysis_ml – все о анализе данных.
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседования Data Science
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@neural – все о нейронных сетях
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
☕️ Java
@javatg - Java для програмистов
@javachats Java чат
@java_library - книги Java
@android_its Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит
💡 Javascript / front
@javascriptv - javascript изучение
@about_javascript - javascript продвинутый
@JavaScript_testit -тесты JS
@htmlcssjavas - web
@hashdev - web разработка
🦫 Golang
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.
@Golang_google - go для разработчиков
@golangtests - тесты и задачи GO
@golangl - чат Golang
@GolangJobsit - вакансии и работа GO
@golang_jobsgo - чат вакансий
@golang_books - книги Golang
@golang_speak - обсуждение задач Go
🐧 Linux
@inux_kal - чат kali linux
@inuxkalii - linux kali
@linux_read - книги linux
👷♂️ IT работа
@hr_itwork - ит-ваканнсии
🔋 SQL
@sqlhub - базы данных
@chat_sql - базы данных чат
🤡It memes
@memes_prog - ит-мемы
⚙️ Rust
@rust_code - язык программирования rust
@rust_chats - чат rust
#️⃣ c# c++
@csharp_ci - c# c++кодинг
@csharp_cplus чат
🐍 Python
@pythonl – python для датасаентиста
@pro_python_code – python на русском
@python_job_interview – подготовка к Python собеседованию
@python_testit тесты на python
@pythonlbooks - книги Python
@Django_pythonl django
@python_djangojobs - работа Python
🦾 Machine learning
@ai_machinelearning_big_data – все о машинном обучении
@data_analysis_ml – все о анализе данных.
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседования Data Science
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@neural – все о нейронных сетях
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
☕️ Java
@javatg - Java для програмистов
@javachats Java чат
@java_library - книги Java
@android_its Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит
💡 Javascript / front
@javascriptv - javascript изучение
@about_javascript - javascript продвинутый
@JavaScript_testit -тесты JS
@htmlcssjavas - web
@hashdev - web разработка
🦫 Golang
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.
@Golang_google - go для разработчиков
@golangtests - тесты и задачи GO
@golangl - чат Golang
@GolangJobsit - вакансии и работа GO
@golang_jobsgo - чат вакансий
@golang_books - книги Golang
@golang_speak - обсуждение задач Go
🐧 Linux
@inux_kal - чат kali linux
@inuxkalii - linux kali
@linux_read - книги linux
👷♂️ IT работа
@hr_itwork - ит-ваканнсии
🔋 SQL
@sqlhub - базы данных
@chat_sql - базы данных чат
🤡It memes
@memes_prog - ит-мемы
⚙️ Rust
@rust_code - язык программирования rust
@rust_chats - чат rust
#️⃣ c# c++
@csharp_ci - c# c++кодинг
@csharp_cplus чат
👍12🔥3😁1
В чем разница между func и func()?
Ответ
Вопрос должен проверить ваше понимание, что все функции в Python также являются объектами (см Картинку)
func — это представляющий функцию объект, который можно назначить переменной или передать другой функции. Функция func() с круглыми скобками вызывает функцию и возвращает результат.
@python_job_interview
Ответ
Вопрос должен проверить ваше понимание, что все функции в Python также являются объектами (см Картинку)
func — это представляющий функцию объект, который можно назначить переменной или передать другой функции. Функция func() с круглыми скобками вызывает функцию и возвращает результат.
@python_job_interview
👍18🔥2
Объясните, как работает функция map
Ответ
Она возвращает объект (итератор), который перебирает значения, применяя функцию к каждому элементу. В случае необходимости объект можно преобразовать в список. В примере на картинке к каждому элементу в списке мы добавляем число 3.
@python_job_interview
Ответ
Она возвращает объект (итератор), который перебирает значения, применяя функцию к каждому элементу. В случае необходимости объект можно преобразовать в список. В примере на картинке к каждому элементу в списке мы добавляем число 3.
@python_job_interview
👍36😁1
Расскажите про асинхронные web-фреймворки на Python.
Асинхронность уже не является просто модным словечком в сообществе Python. После выпуска библиотеки asyncio в версии 3.5, разработчики Python признали влияние Node.js в сфере веб-разработки и ввели в язык два новых ключевых слова – async и await. Это был крайне важный момент, потому что разработчики максимально осторожно относятся к расширению основного синтаксиса, если только нет острой необходимости, что только указывает на то, насколько принципиально необходимыми считались асинхронные возможности.
Перечислим некоторые из лучших асинхронных фреймворков:
- Tornado
- Sanic
- Vibora
- Quart
- FastApi
➡️ Читать дальше
@python_job_interview
Асинхронность уже не является просто модным словечком в сообществе Python. После выпуска библиотеки asyncio в версии 3.5, разработчики Python признали влияние Node.js в сфере веб-разработки и ввели в язык два новых ключевых слова – async и await. Это был крайне важный момент, потому что разработчики максимально осторожно относятся к расширению основного синтаксиса, если только нет острой необходимости, что только указывает на то, насколько принципиально необходимыми считались асинхронные возможности.
Перечислим некоторые из лучших асинхронных фреймворков:
- Tornado
- Sanic
- Vibora
- Quart
- FastApi
➡️ Читать дальше
@python_job_interview
👍15👎1
Объясните, как работает функция filter
Функция делает буквально то, о чем говорит ее название: она фильтрует элементы в последовательности.
Каждый элемент передается функции, которая включает его в последовательность, если по условию получает True, и отбрасывает в случае False.
Обратите внимание, как удалены все элементы, которые не делятся на 2.
@python_job_interview
Функция делает буквально то, о чем говорит ее название: она фильтрует элементы в последовательности.
Каждый элемент передается функции, которая включает его в последовательность, если по условию получает True, и отбрасывает в случае False.
Обратите внимание, как удалены все элементы, которые не делятся на 2.
@python_job_interview
👍26👎5🤨1
В чем разница между глубокой и мелкой копиями?
Обсудим это в контексте изменяемого объекта — списка. Для неизменяемых объектов глубокое и мелкое (поверхностное) копирование обычно не отличаются.
Рассмотрим три сценария.
I) Поставьте ссылку на исходный объект. Она отсылает новое имя li2 к тому же месту в памяти, на которое указывает li1. Поэтому любое изменение в li1 также происходит с li2:
II) Создайте мелкую копию оригинала. Ее можно создать с помощью конструктора list() или mylist.copy().
Мелкая копия создает новый объект, но заполняет его ссылками на оригинал. Таким образом, добавление нового объекта в исходный список li3 не отразится в li4, а вот изменение объектов в li3 — отразится:
III) Создайте глубокую копию. Это делается с помощью copy.deepcopy(). Оригинал и копия полностью независимы, а изменения в одном не оказывают никакого влияния на другой:
@python_job_interview
Обсудим это в контексте изменяемого объекта — списка. Для неизменяемых объектов глубокое и мелкое (поверхностное) копирование обычно не отличаются.
Рассмотрим три сценария.
I) Поставьте ссылку на исходный объект. Она отсылает новое имя li2 к тому же месту в памяти, на которое указывает li1. Поэтому любое изменение в li1 также происходит с li2:
li1 = [['a'],['b'],['c']]
li2 = li1
li1.append(['d'])
print(li2)
#=> [['a'], ['b'], ['c'], ['d']]
II) Создайте мелкую копию оригинала. Ее можно создать с помощью конструктора list() или mylist.copy().
Мелкая копия создает новый объект, но заполняет его ссылками на оригинал. Таким образом, добавление нового объекта в исходный список li3 не отразится в li4, а вот изменение объектов в li3 — отразится:
li3 = [['a'],['b'],['c']]
li4 = list(li3)
li3.append([4])
print(li4)
#=> [['a'], ['b'], ['c']]
li3[0][0] = ['X']
print(li4)
#=> [[['X']], ['b'], ['c']]
III) Создайте глубокую копию. Это делается с помощью copy.deepcopy(). Оригинал и копия полностью независимы, а изменения в одном не оказывают никакого влияния на другой:
import copy
li5 = [['a'],['b'],['c']]
li6 = copy.deepcopy(li5)
li5.append([4])
li5[0][0] = ['X']
print(li6)
#=> [['a'], ['b'], ['c']]
@python_job_interview
👍28🔥3
Что такое временная сложность алгоритма (time complexity)
Оценка сложности
Сложность алгоритмов обычно оценивают по времени выполнения или по используемой памяти. В обоих случаях сложность зависит от размеров входных данных: массив из 100 элементов будет обработан быстрее, чем аналогичный из 1000. При этом точное время мало кого интересует: оно зависит от процессора, типа данных, языка программирования и множества других параметров. Важна лишь асимптотическая сложность, т. е. сложность при стремлении размера входных данных к бесконечности.
Допустим, некоторому алгоритму нужно выполнить 4n3 + 7n условных операций, чтобы обработать n элементов входных данных. При увеличении n на итоговое время работы будет значительно больше влиять возведение n в куб, чем умножение его на 4 или же прибавление 7n. Тогда говорят, что временная сложность этого алгоритма равна О(n3), т. е. зависит от размера входных данных кубически.
Использование заглавной буквы О (или так называемая О-нотация) пришло из математики, где её применяют для сравнения асимптотического поведения функций. Формально O(f(n)) означает, что время работы алгоритма (или объём занимаемой памяти) растёт в зависимости от объёма входных данных не быстрее, чем некоторая константа, умноженная на f(n).
Примеры
O(n) — линейная сложность
Такой сложностью обладает, например, алгоритм поиска наибольшего элемента в не отсортированном массиве. Нам придётся пройтись по всем n элементам массива, чтобы понять, какой из них максимальный.
O(log n) — логарифмическая сложность
Простейший пример — бинарный поиск. Если массив отсортирован, мы можем проверить, есть ли в нём какое-то конкретное значение, методом деления пополам. Проверим средний элемент, если он больше искомого, то отбросим вторую половину массива — там его точно нет. Если же меньше, то наоборот — отбросим начальную половину. И так будем продолжать делить пополам, в итоге проверим log n элементов.
O(n2) — квадратичная сложность
Такую сложность имеет, например, алгоритм сортировки вставками. В канонической реализации он представляет из себя два вложенных цикла: один, чтобы проходить по всему массиву, а второй, чтобы находить место очередному элементу в уже отсортированной части. Таким образом, количество операций будет зависеть от размера массива как n * n, т. е. n2.
Бывают и другие оценки по сложности, но все они основаны на том же принципе.
Также случается, что время работы алгоритма вообще не зависит от размера входных данных. Тогда сложность обозначают как O(1). Например, для определения значения третьего элемента массива не нужно ни запоминать элементы, ни проходить по ним сколько-то раз. Всегда нужно просто дождаться в потоке входных данных третий элемент и это будет результатом, на вычисление которого для любого количества данных нужно одно и то же время.
Аналогично проводят оценку и по памяти, когда это важно. Однако алгоритмы могут использовать значительно больше памяти при увеличении размера входных данных, чем другие, но зато работать быстрее. И наоборот. Это помогает выбирать оптимальные пути решения задач исходя из текущих условий и требований.
Тут можно посмотреть сложность основных алгоритмов сортировки и работы с данными.
@python_job_interview
Оценка сложности
Сложность алгоритмов обычно оценивают по времени выполнения или по используемой памяти. В обоих случаях сложность зависит от размеров входных данных: массив из 100 элементов будет обработан быстрее, чем аналогичный из 1000. При этом точное время мало кого интересует: оно зависит от процессора, типа данных, языка программирования и множества других параметров. Важна лишь асимптотическая сложность, т. е. сложность при стремлении размера входных данных к бесконечности.
Допустим, некоторому алгоритму нужно выполнить 4n3 + 7n условных операций, чтобы обработать n элементов входных данных. При увеличении n на итоговое время работы будет значительно больше влиять возведение n в куб, чем умножение его на 4 или же прибавление 7n. Тогда говорят, что временная сложность этого алгоритма равна О(n3), т. е. зависит от размера входных данных кубически.
Использование заглавной буквы О (или так называемая О-нотация) пришло из математики, где её применяют для сравнения асимптотического поведения функций. Формально O(f(n)) означает, что время работы алгоритма (или объём занимаемой памяти) растёт в зависимости от объёма входных данных не быстрее, чем некоторая константа, умноженная на f(n).
Примеры
O(n) — линейная сложность
Такой сложностью обладает, например, алгоритм поиска наибольшего элемента в не отсортированном массиве. Нам придётся пройтись по всем n элементам массива, чтобы понять, какой из них максимальный.
O(log n) — логарифмическая сложность
Простейший пример — бинарный поиск. Если массив отсортирован, мы можем проверить, есть ли в нём какое-то конкретное значение, методом деления пополам. Проверим средний элемент, если он больше искомого, то отбросим вторую половину массива — там его точно нет. Если же меньше, то наоборот — отбросим начальную половину. И так будем продолжать делить пополам, в итоге проверим log n элементов.
O(n2) — квадратичная сложность
Такую сложность имеет, например, алгоритм сортировки вставками. В канонической реализации он представляет из себя два вложенных цикла: один, чтобы проходить по всему массиву, а второй, чтобы находить место очередному элементу в уже отсортированной части. Таким образом, количество операций будет зависеть от размера массива как n * n, т. е. n2.
Бывают и другие оценки по сложности, но все они основаны на том же принципе.
Также случается, что время работы алгоритма вообще не зависит от размера входных данных. Тогда сложность обозначают как O(1). Например, для определения значения третьего элемента массива не нужно ни запоминать элементы, ни проходить по ним сколько-то раз. Всегда нужно просто дождаться в потоке входных данных третий элемент и это будет результатом, на вычисление которого для любого количества данных нужно одно и то же время.
Аналогично проводят оценку и по памяти, когда это важно. Однако алгоритмы могут использовать значительно больше памяти при увеличении размера входных данных, чем другие, но зато работать быстрее. И наоборот. Это помогает выбирать оптимальные пути решения задач исходя из текущих условий и требований.
Тут можно посмотреть сложность основных алгоритмов сортировки и работы с данными.
@python_job_interview
👍22🐳5❤🔥2
🐍 Собеседование Python. Разбор вопросов
00:00 Agenda
00:41 Как справиться со стрессом
04:00 Начало собеседования
13:37 Типы данных в Python
22:46 Lambda-функции
24:40 Тернарный оператор
26:50 Глубокая и поверхностная копия
28:40 Виртуальные окружения
33:45 Big O Notation
41:48 Классы
48:35 Декораторы
56:53 Абстрактные классы
59:57 Метаклассы
1:02:52 ООП
1:10:24 MRO
1:13:00 Итератор
1:14:24 Генератор
1:17:00 ОФФТОП
1:31:07 Конкурентность, асинхронность
1:36:20 Тестирование кода
1:43:32 ORM
1:46:34 Best practices
1:55:35 Базы данных
2:04:48 Git
2:07:28 Docker
2:12:37 Web
2:19:24 Linux
2:23:10 ОФФТОП
➡️ Смотреть
@python_job_interview
00:00 Agenda
00:41 Как справиться со стрессом
04:00 Начало собеседования
13:37 Типы данных в Python
22:46 Lambda-функции
24:40 Тернарный оператор
26:50 Глубокая и поверхностная копия
28:40 Виртуальные окружения
33:45 Big O Notation
41:48 Классы
48:35 Декораторы
56:53 Абстрактные классы
59:57 Метаклассы
1:02:52 ООП
1:10:24 MRO
1:13:00 Итератор
1:14:24 Генератор
1:17:00 ОФФТОП
1:31:07 Конкурентность, асинхронность
1:36:20 Тестирование кода
1:43:32 ORM
1:46:34 Best practices
1:55:35 Базы данных
2:04:48 Git
2:07:28 Docker
2:12:37 Web
2:19:24 Linux
2:23:10 ОФФТОП
➡️ Смотреть
@python_job_interview
👍29💩3