⚡️ Задача с собеседования |: #Junior
Условие
Числа Фибоначчи представляют последовательность, получаемую в результате сложения двух предыдущих элементов.
Начинается коллекция с чисел 1 и 1.
Она достаточно быстро растет, поэтому вычисление больших значений занимает немало времени.
Создайте функцию
Для реализации этой функции потребуется обратиться к инструкции
Она не сохраняет в оперативной памяти огромную последовательность, а дает возможность “доставать” промежуточные результаты по одному.
Необходимо превратить функцию в генератор при помощи инструкции yield, чтобы вычисления осуществлялись не сразу, а по мере надобности.
Решение
👉 Пишите свое решение в комментариях👇
@python_job_interview
Условие
Числа Фибоначчи представляют последовательность, получаемую в результате сложения двух предыдущих элементов.
Начинается коллекция с чисел 1 и 1.
Она достаточно быстро растет, поэтому вычисление больших значений занимает немало времени.
Создайте функцию
fib(n)
, генерирующую n чисел Фибоначчи с минимальными затратами ресурсов.Для реализации этой функции потребуется обратиться к инструкции
yield
. Она не сохраняет в оперативной памяти огромную последовательность, а дает возможность “доставать” промежуточные результаты по одному.
Необходимо превратить функцию в генератор при помощи инструкции yield, чтобы вычисления осуществлялись не сразу, а по мере надобности.
Решение
def fib(n):
fib0 = 1
yield fib0
fib1 = 1
yield fib1
for i in range(n - 2):
fib0, fib1 = fib1, fib0 + fib1
yield fib1
# Тест
for num in fib(112121):
pass
print(num)
👉 Пишите свое решение в комментариях👇
@python_job_interview
⚡️ Задача
Требуется создать csv-файл
– № - номер по порядку (от 1 до 300);
– Секунда – текущая секунда на вашем ПК;
– Микросекунда – текущая миллисекунда на часах.
На каждой итерации цикла искусственно приостанавливайте скрипт на 0,01 секунды.
Для работы с файлами подобного текстового формата потребуется встроенная в Python библиотека csv.
Решение
В итоге создастся требуемый файл. Приведем первые строки его содержимого:
Содержимое файла rows_300.csv
👉 Пишите ваше решение в комментариях👇
@python_job_interview
Требуется создать csv-файл
«rows_300.csv»
со следующими столбцами:– № - номер по порядку (от 1 до 300);
– Секунда – текущая секунда на вашем ПК;
– Микросекунда – текущая миллисекунда на часах.
На каждой итерации цикла искусственно приостанавливайте скрипт на 0,01 секунды.
Для работы с файлами подобного текстового формата потребуется встроенная в Python библиотека csv.
Решение
import csv
import datetime
import time
with open('rows_300.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerow(['№', 'Секунда ', 'Микросекунда'])
for line in range(1, 301):
writer.writerow([line, datetime.datetime.now().second, datetime.datetime.now().microsecond])
time.sleep(0.01)
В итоге создастся требуемый файл. Приведем первые строки его содержимого:
Содержимое файла rows_300.csv
№,Секунда ,Микросекунда
1,51,504807
2,51,515807
3,51,526819
4,51,537817
5,51,548800
6,51,558817
…
👉 Пишите ваше решение в комментариях👇
@python_job_interview
❓ Когда применяются ленивые вычисления и в чем их логика
Ленивые вычисления предполагают, что не нужно ничего делать до тех пор, пока в этом нет необходимости. Так, если мы не обратились к свойству класса (которое определяется некими математическими операциями, например), то не нужно заранее его рассчитывать. На этом базируется, в том числе, логика генераторов. Многие итераторы также являются ленивыми. Это не просто удобно, но позволяет экономить память и время на вычисление.
Нагляднее всего можно понять преимущество ленивых вычислений (и итераторов) на следующем примере.
# Создадим итерабельный объект
Функция
Если вы рискнете преобразовать этот массив чисел в список, то случится одно из двух: либо выведется ошибка о нехватке памяти на компьютере, либо очень-очень долго будет формироваться список всех объектов.
@python_job_interview
Ленивые вычисления предполагают, что не нужно ничего делать до тех пор, пока в этом нет необходимости. Так, если мы не обратились к свойству класса (которое определяется некими математическими операциями, например), то не нужно заранее его рассчитывать. На этом базируется, в том числе, логика генераторов. Многие итераторы также являются ленивыми. Это не просто удобно, но позволяет экономить память и время на вычисление.
Нагляднее всего можно понять преимущество ленивых вычислений (и итераторов) на следующем примере.
# Создадим итерабельный объект
nums = range(1, 12121212112)
nums[10543210010]
10543210011 # Практически моментальный вывод
list(nums)
MemoryError
Функция
range()
– ленивая. Она заранее не формирует последовательность из гигантского количества чисел. А когда мы обращаемся к некому ее элементу по индексу (это разрешено, так как она создает итерабельный объект), он выводится почти сразу.Если вы рискнете преобразовать этот массив чисел в список, то случится одно из двух: либо выведется ошибка о нехватке памяти на компьютере, либо очень-очень долго будет формироваться список всех объектов.
@python_job_interview
❓Что такое дескрипторы данных?
Очень часто переменные, инициализируемые в классе, являются однотипными. Например, есть класс Employee (сотрудник), принимающий параметры: имя, фамилия, отчество, должность. Все они являются строками. Следовательно, прежде чем создать экземпляр класса, нужно проверить, что пользователь ввел строки. А для этого потребуются сеттеры, проверяющие тип вводимых параметров. В итоге, мы 4 раза повторим код проверки. Нарушается принцип DRY (don't repeat yourself).
Для таких ситуаций удобно использовать дескрипторы (они, к слову, широко применяются во фреймворке Django при создании моделей).
Дескриптор - такой атрибут объекта, поведение которого переопределяется специальными методами. Проще говоря, доступ к какому-то свойству экземпляра можно переопределить с учетом дополнительных проверок. Если делать эти верификации без дескрипторов, то один и тот же код начнет повторяться.
Существует 4 метода протокола дескрипторов:
Если применяется только метод
Покажем использование дескрипторов на вышеупомянутом примере.
Пример – IDE
---
# Создаем класс с протоколами дескриптора
# Инициализируем свойства с учетом требуемых проверок
# Тесты
Результат выполнения
---
ValueError: Нужно предоставить строку
ValueError: Минимум две буквы в атрибуте требуется
@python_job_interview
Очень часто переменные, инициализируемые в классе, являются однотипными. Например, есть класс Employee (сотрудник), принимающий параметры: имя, фамилия, отчество, должность. Все они являются строками. Следовательно, прежде чем создать экземпляр класса, нужно проверить, что пользователь ввел строки. А для этого потребуются сеттеры, проверяющие тип вводимых параметров. В итоге, мы 4 раза повторим код проверки. Нарушается принцип DRY (don't repeat yourself).
Для таких ситуаций удобно использовать дескрипторы (они, к слову, широко применяются во фреймворке Django при создании моделей).
Дескриптор - такой атрибут объекта, поведение которого переопределяется специальными методами. Проще говоря, доступ к какому-то свойству экземпляра можно переопределить с учетом дополнительных проверок. Если делать эти верификации без дескрипторов, то один и тот же код начнет повторяться.
Существует 4 метода протокола дескрипторов:
get__()
- получить значение свойства;set__()
- задать значение;delete__()
- удалить атрибут;set_name__()
- присвоить имя свойству (появился в Питоне версии 3.6).Если применяется только метод
__get__(),
то мы имеем дело с дескриптором без данных, а если есть еще и __set__()
, то речь будет идти о дескрипторе данных.Покажем использование дескрипторов на вышеупомянутом примере.
Пример – IDE
---
# Создаем класс с протоколами дескриптора
class StringChecker:
# Получаем доступ к свойству
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
# Меняем свойство
def __set__(self, instance, str_value):
if not isinstance(str_value, str):
raise ValueError('Нужно предоставить строку')
elif len(str_value) < 2:
raise ValueError('Необходимо минимум 2 буквы')
instance.__dict__[self.name] = str_value
# Задаем имя свойстваdef __set_name__(self, owner, name):
self.name = name
class Employee:
# Определяем атрибуты (их может быть любое количество)
name = StringChecker()
surname = StringChecker()
patronymic = StringChecker()
post = StringChecker()
# Инициализируем свойства с учетом требуемых проверок
def __init__(self, name, surname, patronymic, post):
self.name = name
self.surname = surname
self.patronymic = patronymic
self.post = post
# Тесты
director = Employee('Иван', 'Николаевич', 'Прогин', 'Директор')
print(director.__dict__)
director.name = 1
director.name = 'A'
Результат выполнения
---
{'name': 'Иван', 'surname': 'Николаевич', 'patronymic': 'Прогин', 'post': 'Директор'}
ValueError: Нужно предоставить строку
ValueError: Минимум две буквы в атрибуте требуется
@python_job_interview
⚡️ Задача
Инструкция yield позволяет создавать генераторы.
Инструкция
В отличие от объявления return в функции, где возвращается один объект, yield при каждом вызове функции генерирует новый объект.
Фактически это дает возможность использовать генераторы в циклах.
Самая важная причина применения такой инструкции - экономия памяти, когда не требуется сохранять всю последовательность, а можно получать ее элементы по одному.
Ученик написал генератор
Сократите код функции.
Код
---
Конструкция
Решение - IDE
@python_job_interview
Инструкция yield позволяет создавать генераторы.
Инструкция
yield
позволяет создавать генераторы. В отличие от объявления return в функции, где возвращается один объект, yield при каждом вызове функции генерирует новый объект.
Фактически это дает возможность использовать генераторы в циклах.
Самая важная причина применения такой инструкции - экономия памяти, когда не требуется сохранять всю последовательность, а можно получать ее элементы по одному.
Ученик написал генератор
show_letters(some_str)
, выводящий все символы строки на печать, но только в том случае, если они являются буквами (остальные игнорируются). Сократите код функции.
Код
---
def show_letters(some_str):
clean_str = ''.join([letter for letter in some_str if letter.isalpha()])
for symbol in clean_str:
yield symbol
Конструкция
yield
from позволяет полностью убрать цикл из функции. Она "вкладывает" один генератор внутрь другого, что дает возможность управления несколькими генераторами.Решение - IDE
def show_letters(some_str):
yield from ''.join([letter for letter in some_str if letter.isalpha()])
random_str = show_letters('A!sdf 09 _ w')
print(next(random_str))
print(next(random_str))
Результат выполнения
A
s
@python_job_interview
⚡️ Задача: найдите первый неповторяющийся символ в строке, выполнив только один обход
Для заданной строки найдите в ней первый неповторяющийся символ, выполнив только один ее обход.
Например,
Простым решением было бы сохранить количество каждого символа в словаре или списке, пройдя его один раз.
Затем еще раз просмотреть строку, чтобы найти первый символ, имеющий значение 1. Временная сложность этого решения равна O(n), где n длина входной строки. Проблема с этим решением заключается в том, что строка проходится дважды, что нарушает ограничения программы.
Мы можем решить эту задачу за один обход строки. Идея состоит в том, чтобы использовать словарь для хранения количества каждого отдельного символа и индекса его первого или последнего вхождения в строку. Затем пройтись по словарю и найти символ с минимальным индексом строки.
👉 Пишите ваше решение в комментариях👇
@python_job_interview
Для заданной строки найдите в ней первый неповторяющийся символ, выполнив только один ее обход.
Например,
Input:
string is ABCDBAGHC
Output:
первый неповторяющийся символ: D
Простым решением было бы сохранить количество каждого символа в словаре или списке, пройдя его один раз.
Затем еще раз просмотреть строку, чтобы найти первый символ, имеющий значение 1. Временная сложность этого решения равна O(n), где n длина входной строки. Проблема с этим решением заключается в том, что строка проходится дважды, что нарушает ограничения программы.
Мы можем решить эту задачу за один обход строки. Идея состоит в том, чтобы использовать словарь для хранения количества каждого отдельного символа и индекса его первого или последнего вхождения в строку. Затем пройтись по словарю и найти символ с минимальным индексом строки.
# Функция поиска первого неповторяющегося символа в
# строк
е, выполнив только один ее обход
def findNonRepeatingChar(s):
# Базовый вариант
if not s:
return -1
# словарь # для хранения количества символов и индекса их
# последнее вхождение в строку
d = {}
for index, char in enumerate(s):
frequency, prevIndex = d.get(char, (0, index))
d[char] = (frequency + 1, index)
# хранит индекс первого неповторяющегося символа
min_index = -1
# Проходим словарь и находим символ
for key, values in d.items():
count, firstIndex = values
if count == 1 and (min_index == -1 or firstIndex < min_index):
min_index = firstIndex
return min_index
if __name__ == '__main__':
s = 'ABCDBAGHC'
index = findNonRepeatingChar(s)
if index != -1:
print('первый неповторяющийся символ: ', s[index])
else:
print('Таких символов нет')
👉 Пишите ваше решение в комментариях👇
@python_job_interview
⚡️ Что такое coroutine (Сопрограмма) в Python?
Сопрограмма (coroutine) — результат вызова асинхронной функции, представляющий собой выполнение этой функции, способное приостанавливаться. Так как в общем случае невозможно определить сколько раз и на какое время выполнение будет приостановлено, невозможно и сказать когда оно будет закончено. Ваш код может либо ждать завершения выполнения сопрограммы с помощью оператора await, либо поручить ожидание циклу событий и продолжить свой выполнение.
В первом случае
выполнение caller приостановится до выполнения callee. В этот момент какие-то другие операции в каких-то других сопрограммах могут продолжаться, но
Во втором случае
caller сразу же продолжит свою работу. Строка
Но что если, callee будет возвращать какое-то значение, которое нужно вызывающей стороне, но не прямо сейчас, а когда будет готово? Вот тут-то на сцену выходят футуры.
Футура (Future) - будущий результат выполнения сопрограммы. Метод
Или может заняться своими делами, периодически проверяя готовность
Или может собрать их в список и ждать все. Или не все, а только ту, которая будет выполнена первой, а остальные проигнорировать. Или передать футуру другой сопрограмме, а самой заняться каким-нибудь другим делом. В общем, это "очень полезный горшок, куда можно класть какие хочешь вещи".
Осталось только разобраться, чем отличаются футуры от задач. Ничем не отличаются, по большому счёту. Класс
Подытоживая: Task - это задача, поставленная циклу событий, на выполнение
@python_job_interview
Сопрограмма (coroutine) — результат вызова асинхронной функции, представляющий собой выполнение этой функции, способное приостанавливаться. Так как в общем случае невозможно определить сколько раз и на какое время выполнение будет приостановлено, невозможно и сказать когда оно будет закончено. Ваш код может либо ждать завершения выполнения сопрограммы с помощью оператора await, либо поручить ожидание циклу событий и продолжить свой выполнение.
В первом случае
async def callee():
print('Hello')
async def caller():
await callee()
print('World')
выполнение caller приостановится до выполнения callee. В этот момент какие-то другие операции в каких-то других сопрограммах могут продолжаться, но
caller
будет ждать там, где выполнил await
.Во втором случае
async def callee():
print('Hello')
async def caller():
asyncio.create_task(callee())
print('World')
caller сразу же продолжит свою работу. Строка
"World"
будет выведена раньше, чем "Hello".
Здесь мы видим, что caller поставил циклу событий задачу выполнить сопрограмму callee.Но что если, callee будет возвращать какое-то значение, которое нужно вызывающей стороне, но не прямо сейчас, а когда будет готово? Вот тут-то на сцену выходят футуры.
Футура (Future) - будущий результат выполнения сопрограммы. Метод
ensure_future
поручает циклу событий выполнить сопрограмму и сразу же, в момент вызова, возвращает футуру, в которой будет значение, но неизвестно когда. Вызывающая сторона может подождать выполнения футуры так же, как ожидало саму сопрограмму
async def callee():
return 'Hello'
async def caller():
loop = asyncio.get_event_loop()
future = loop.ensure_future(callee())
result = await future
print(result + ' World')
Или может заняться своими делами, периодически проверяя готовность
async def caller():
loop = asyncio.get_event_loop()
future = loop.ensure_future(callee())
while not future.done():
# Какие-нибудь циклические дела
print(future.result() + ' World')
Или установить на футуру колбэк
async def caller():
loop = asyncio.get_event_loop()
future = loop.ensure_future(callee())
future.add_done_callback(lambda f: print(f.result() + ' World'))
# какие-нибудь другие важные дела
Или может собрать их в список и ждать все. Или не все, а только ту, которая будет выполнена первой, а остальные проигнорировать. Или передать футуру другой сопрограмме, а самой заняться каким-нибудь другим делом. В общем, это "очень полезный горшок, куда можно класть какие хочешь вещи".
Осталось только разобраться, чем отличаются футуры от задач. Ничем не отличаются, по большому счёту. Класс
Task
- это наследник класса Future
. А существенная разница между asyncio.create_task() и loop.ensure_future()
только в том, что первой не было до Python 3.7.Подытоживая: Task - это задача, поставленная циклу событий, на выполнение
coroutine
, одновременно являющаяся Future
, которая представляет собой результат выполнения Task
когда-нибудь в будущем.@python_job_interview
⚡️ Что такое интроспекция?
Introspection in Python
Интроспекция — это способность программы исследовать тип или свойства объекта во время работы программы. Вы можете поинтересоваться, каков тип объекта, является ли он экземпляром класса. Некоторые языки даже позволяют узнать иерархию наследования объекта. Возможность интроспекции есть в таких языках, как Ruby, Java, PHP, Python, C++ и других. В целом, инстроспекция — это очень простое и очень мощное явление. Вот несколько примеров использования инстроспекции:
В Python самой распространённой формой интроспекции является использование метода dir для вывода списка атрибутов объекта:
@python_job_interview
Introspection in Python
Интроспекция — это способность программы исследовать тип или свойства объекта во время работы программы. Вы можете поинтересоваться, каков тип объекта, является ли он экземпляром класса. Некоторые языки даже позволяют узнать иерархию наследования объекта. Возможность интроспекции есть в таких языках, как Ruby, Java, PHP, Python, C++ и других. В целом, инстроспекция — это очень простое и очень мощное явление. Вот несколько примеров использования инстроспекции:
// Java
if(obj instanceof Person){
Person p = (Person)obj;
p.walk();
}
//PHP
if ($obj instanceof Person) {
// делаем что угодно
}
В Python самой распространённой формой интроспекции является использование метода dir для вывода списка атрибутов объекта:
# Python
class foo(object):
def __init__(self, val):
self.x = val
def bar(self):
return self.x
...
dir(foo(5))
=> ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'bar', 'x']
@python_job_interview
Интроспекция позволяет вам изучать атрибуты объекта во время выполнения программы, а рефлексия — манипулировать ими.
Рефлексия — это способность компьютерной программы изучать и модифицировать свою структуру и поведение (значения, мета-данные, свойства и функции) во время выполнения.
Простым языком: она позволяет вам вызывать методы объектов, создавать новые объекты, модифицировать их, даже не зная имён интерфейсов, полей, методов во время компиляции.
Из-за такой природы рефлексии её труднее реализовать в статически типизированных языках, поскольку ошибки типизации возникают во время компиляции, а не исполнения программы (подробнее об этом здесь). Тем не менее, она возможна, ведь такие языки, как Java, C# и другие допускают использование как интроспекции, так и рефлексии (но не C++, он позволяет использовать лишь интроспекцию).
По той же причине рефлексию проще реализовать в интерпретируемых языках, поскольку когда функции, объекты и другие структуры данных создаются и вызываются во время работы программы, используется какая-то система распределения памяти. Интерпретируемые языки обычно предоставляют такую систему по умолчанию, а для компилируемых понадобится дополнительный компилятор и интерпретатор, который следит за корректностью рефлексии.
Пример:
# Без рефлексии
Foo().hello()
# С рефлексией
getattr(globals()['Foo'](), 'hello')()
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Полный список вопрос и ответов.
📌 Читать
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Строки в Питоне сравниваются на основании значений символов. Т.е. если мы захотим выяснить, что больше: «Apple» или «Яблоко», – то «Яблоко» окажется бОльшим.
А все потому, что английская буква «A» имеет значение 65 (берется из таблицы кодировки), а русская буква «Я» – 1071 (с помощью функции ord() это можно выяснить).
Такое положение дел не устроило программиста.
Он считает, что строки нужно сравнивать по количеству входящих в них символов.
Для этого программист создал класс RealString и реализовал озвученный инструментарий. Сравнивать между собой можно как объекты класса, так и обычные строки с экземплярами класса RealString.
К слову, программисту понадобилось только 3 метода внутри класса (включая
__init__()
) для воплощения задуманного.В общем случае для создания такого класса понадобится 4 метода, так как в Питоне реализованы «богатые» сравнения. Это значит, что если имеется сравнение «больше», то автоматом появится возможность осуществлять сравнение «меньше».
Решение
class RealString:
def __init__(self, some_str):
self.some_str = str(some_str)
def __eq__(self, other):
if not isinstance(other, RealString):
other = RealString(other)
return len(self.some_str) == len(other.some_str)
def __lt__(self, other):
if not isinstance(other, RealString):
other = RealString(other)
return len(self.some_str) < len(other.some_str)
def __le__(self, other):
return self == other or self < other
Чтобы повторить класс, придуманный программистом (с тремя методами), требуется воспользоваться декоратором @total_ordering из модуля functools (упрощает реализацию сравнений. Требует лишь 2 дополняющих варианта сравнения - например, больше и равно - чтобы автоматически "дописать" остальные).
from functools import total_ordering
@total_ordering
class RealString:
def __init__(self, some_str):
self.some_str = str(some_str)
def __eq__(self, other):
if not isinstance(other, RealString):
other = RealString(other)
return len(self.some_str) == len(other.some_str)
def __lt__(self, other):
if not isinstance(other, RealString):
other = RealString(other)
return len(self.some_str) < len(other.some_str)
# Тесты
str1 = RealString('Молоко')
str2 = RealString('Абрикосы растут')
str3 = 'Золото'
str4 = [1, 2, 3]
print(str1 < str4)
print(str1 >= str2)
print(str1 == str3)
Вывод:
True
False
True
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Циклический сдвиг массива — это когда каждый элемент кроме последнего сдвигается вправо, а последний элемент массива становится первым.
На вход подаются массив A и целое число K. Сделайте циклический сдвиг входного массива K раз и верните получившийся массив.
Например, для данных:
A = [2, 5, 1, 4, 6]
K = 3
Циклический сдвиг должен быть выполнен трижды:
[2, 5, 1, 4, 6] -> [6, 2, 5, 1, 4]
[6, 2, 5, 1, 4] -> [4, 6, 2, 5, 1]
[4, 6, 2, 5, 1] -> [1, 4, 6, 2, 5]
И программа должна вернуть
[1, 4, 6, 2, 5]
Если
K = 0
, то сдвиг не делается.Для
K = 5:
[2, 5, 1, 4, 6] -> [2, 5, 1, 4, 6]
Наивное решение:
1. Определяем, что такое ротировать массив один раз.
2. Делаем это K раз.
def rotate(A, K):
""" Rotates a list K times """
if not A:
return []
for i in range(K):
A = rotate_once(A)
return A
def rotate_once(A):
""" Rotates a list once """
A.insert(0, A[-1])
del A[-1]
return A
Это решение не оптимальное, потому что каждый insert()
передвигает все элементы исходного списка. Также оно не учитывает, что после len(A
) ротаций список возвращается в исходное состояние. Индексы элементов в новом массиве несложно рассчитать аналитически, поэтому:
def rotate(A, K):
""" Rotates a list K times """
result = []
if K == 0:
return A
else:
for i in range(len(A)):
new_index = (i - K) % len(A)
result.append(A[new_index])
return result
Это лучше, потому что
▪ результат получается за один проход
▪ и время работы не увеличивается на больших K.
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 Задача с собеседования | Уровень: #Easy
Условие:
Создать функцию которая принимает строку и заменяет каждую букву на её позицию в алфавите. Если что-то в тексте не является буквой, игнорируйте это и не возвращайте. На выходе получаем строку.
Пример:
Ф-ция принимает:
Ф-ция возвращает:
Решение
👉 Пишите ваше решение в комментариях👇
@python_job_interview
Условие:
Создать функцию которая принимает строку и заменяет каждую букву на её позицию в алфавите. Если что-то в тексте не является буквой, игнорируйте это и не возвращайте. На выходе получаем строку.
Пример:
Ф-ция принимает:
"I learn Python with Python Job"
Ф-ция возвращает:
"9 12 5 1 18 14 16 25 20 8 15 14 23 9 20 8 16 25 20 8 15 14 10 15 2"
Решение
import string
def str_to_int(s: str = ''):
if not s:
return 'входная строка пустая'
alphabet = list(string.ascii_lowercase)
position_in_alphabet = [str(i + 1) for i in range(len(alphabet))]
dict_alphabet = dict(zip(alphabet, position_in_alphabet))
s_to_i = ''
for char in s.lower():
if char in dict_alphabet:
s_to_i += dict_alphabet.get(char) + ' '
return s_to_i
print(str_to_int('I learn Python with Python Job'))
👉 Пишите ваше решение в комментариях👇
@python_job_interview
📌 Задача
У продавца и покупателя имеется неограниченное кол-во монет достоинством
Покупатель купил товар на сумму n. Hужно найти
минимальное кол-во монет, которые будут использованы при расплате. Деньги может давать как покупатель, так и продавец.
Решение
Какая временная сложность данного алгоритма?
👉 Пишите ваше решение в комментариях👇
@python_job_interview
У продавца и покупателя имеется неограниченное кол-во монет достоинством
(1,2,5,10,20,50,100,200,500)
. Покупатель купил товар на сумму n. Hужно найти
минимальное кол-во монет, которые будут использованы при расплате. Деньги может давать как покупатель, так и продавец.
Решение
a = input('Введите сумму: ')
d = dict.fromkeys([500, 200, 100, 50, 20, 10, 5, 2, 1], 0)
def get_nearest_value(iterable, value):
return min(iterable, key=lambda x: abs(x - value))
for i in d.keys():
d[i] = _i = int(a)/i
a = int(a)%i
_key = get_nearest_value(d.keys(), a)
d[_key] += 1
for k in d.keys():
print('%s - %d' % (k, d[k]))
Какая временная сложность данного алгоритма?
👉 Пишите ваше решение в комментариях👇
@python_job_interview
#junior
"Напишите программу на Python для получения строки из заданной строки, в которой все вхождения первого символа заменены на '$', кроме самого первого символа."
Пример:
print(change_char('restart'))
»»» resta$t
👉 Пишите ваше решение в комментариях👇
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
class Developer:
coffee_cups = 0
def __init__(self, name):
self.name = name
self.coffee_cups += 1
def speak(self):
print(f"I'm {self.name} and I've had {self.coffee_cups} cups
of coffee today")
rover = Developer("Steve")
spot = Developer("Bob")
👉 Пишите ваше решение в комментариях👇
@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 Подборка каналов для Дата сайентиста
⭐️ Нейронные сети
@vistehno - chatgpt ведет блог, решает любые задачи и отвечает на любые ваши вопросы.
@aigen - сети для генерации картинок. видео, музыки и многого другого.
@neural – погружение в нейросети.
🖥 Machine learning
@ai_ml – погружение в нейросети, ai, Chatgpt, midjourney, машинное обучение.
@datasc - дата сайнс обучение самой востребованной профессии.
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседованию.
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
@Machinelearning_Jobs - чат работы мл
🖥 SQL базы данных
@sqlhub - Повышение эффективности кода с грамотным использованием бд.
@chat_sql - чат изучения бд.
🖥 Python
@pythonl - главный канал самого популярного языка программирования.
@pro_python_code – учим python с ментором.
@python_job_interview – подготовка к Python собеседованию.
@python_testit - проверочные тесты на python
@pythonlbooks - современные книги Python
@python_djangojobs - работа для Python программистов
@python_django_work - чат обсуждения вакансий
🖥 Javascript / front
@react_tg - - 40,14% разработчиков сайтов использовали React в 2022 году - это самая популярная библиотека для создания сайтов.
@javascript -канал для JS и FrontEnd разработчиков. Лучшие практики и примеры кода. Туториалы и фишки JS
@Js Tests - каверзные тесты JS
@hashdev - погружение в web разработку.
@javascriptjobjs - отборные вакансии и работа FrontEnd.
@jsspeak - чат поиска FrontEnd работы.
🖥 Java
@javatg - выучить Java с senior разработчиком по профессиональной методике.
@javachats - чат для ответов на вопросы по Java
@java_library - библиотека книг Java
@android_its - Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит
👣 Golang
@Golang_google - восхитительный язык от Google, мощный и перспективный.
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.
@golangtests - интересные тесты и задачи GO
@golangl - чат изучающих Go
@GolangJobsit - отборные вакансии и работа GO
@golang_jobsgo - чат для ищущих работу.
@golang_books - полезные книги Golang
@golang_speak - обсуждение языка Go
🖥 Linux
@linux -топ фишки, гайды, уроки по работе с Linux.
@linux chat - чат linux для обучения и помощи.
@linux_read - бесплатные книги linux
👷♂️ IT работа
@hr_itwork -кураторский список актуальных ит-ваканнсии
🤡It memes
@memes_prog - ит-мемы
⚙️ Rust
@rust_code - Rust избавлен от болевых точек, которые есть во многих современных яп
@rust_chats - чат rust
#️⃣ c# c++
C# - объединяет лучшие идеи современных языков программирования
@csharp_cplus чат
С++ - Универсальность. Возможно, этот главный плюс C++.
📓 Книги
@programming_books_it - большая библиотека. программиста
@datascienceiot -ds книги
@pythonlbooks - python библиотека.
@golang_books - книги Golang
@frontendbooksit - front книги
@progersit - ит-шпаргалки
@linux_read - Linux books
@java_library - Java books
🖥 Github
@github_code - лучшие проекты с github
@bigdatai - инструменты по работе с данными
🖥 Devops
Devops - специалист общего профиля, которому нужны обширные знания в области разработки.
📢 English for coders
@english_forprogrammers - Английский для программистов
@vistehno - chatgpt ведет блог, решает любые задачи и отвечает на любые ваши вопросы.
@aigen - сети для генерации картинок. видео, музыки и многого другого.
@neural – погружение в нейросети.
@ai_ml – погружение в нейросети, ai, Chatgpt, midjourney, машинное обучение.
@datasc - дата сайнс обучение самой востребованной профессии.
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседованию.
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
@Machinelearning_Jobs - чат работы мл
@sqlhub - Повышение эффективности кода с грамотным использованием бд.
@chat_sql - чат изучения бд.
@pythonl - главный канал самого популярного языка программирования.
@pro_python_code – учим python с ментором.
@python_job_interview – подготовка к Python собеседованию.
@python_testit - проверочные тесты на python
@pythonlbooks - современные книги Python
@python_djangojobs - работа для Python программистов
@python_django_work - чат обсуждения вакансий
@react_tg - - 40,14% разработчиков сайтов использовали React в 2022 году - это самая популярная библиотека для создания сайтов.
@javascript -канал для JS и FrontEnd разработчиков. Лучшие практики и примеры кода. Туториалы и фишки JS
@Js Tests - каверзные тесты JS
@hashdev - погружение в web разработку.
@javascriptjobjs - отборные вакансии и работа FrontEnd.
@jsspeak - чат поиска FrontEnd работы.
@javatg - выучить Java с senior разработчиком по профессиональной методике.
@javachats - чат для ответов на вопросы по Java
@java_library - библиотека книг Java
@android_its - Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит
@Golang_google - восхитительный язык от Google, мощный и перспективный.
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.
@golangtests - интересные тесты и задачи GO
@golangl - чат изучающих Go
@GolangJobsit - отборные вакансии и работа GO
@golang_jobsgo - чат для ищущих работу.
@golang_books - полезные книги Golang
@golang_speak - обсуждение языка Go
@linux -топ фишки, гайды, уроки по работе с Linux.
@linux chat - чат linux для обучения и помощи.
@linux_read - бесплатные книги linux
👷♂️ IT работа
@hr_itwork -кураторский список актуальных ит-ваканнсии
🤡It memes
@memes_prog - ит-мемы
⚙️ Rust
@rust_code - Rust избавлен от болевых точек, которые есть во многих современных яп
@rust_chats - чат rust
#️⃣ c# c++
C# - объединяет лучшие идеи современных языков программирования
@csharp_cplus чат
С++ - Универсальность. Возможно, этот главный плюс C++.
📓 Книги
@programming_books_it - большая библиотека. программиста
@datascienceiot -ds книги
@pythonlbooks - python библиотека.
@golang_books - книги Golang
@frontendbooksit - front книги
@progersit - ит-шпаргалки
@linux_read - Linux books
@java_library - Java books
@github_code - лучшие проекты с github
@bigdatai - инструменты по работе с данными
Devops - специалист общего профиля, которому нужны обширные знания в области разработки.
@english_forprogrammers - Английский для программистов
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 Задача
У вас есть девять цифр:
Три функции:
-
-
Здесь просится решение, избавленное от if-ов и кодирования операций с помощью символов.
👉 Это не оптимальное решение. Пишите свое решение в комментариях👇
@python_job_interview
У вас есть девять цифр:
1, 2, …, 9.
Именно в таком порядке. Вы можете вставлять между ними знаки «+», «-»
или ничего. У вас будут получаться выражения вида 123+45-6+7+89
. Найдите все из них, которые равны 100
.def all_combinations(a):
if len(a) <= 1:
yield a
else:
head = ''
tail = list(a)
while len(tail) > 0:
head += tail.pop(0)
for s in all_combinations(tail):
yield [head] + s
def all_signs(n):
if n == 0:
yield ()
else:
for tail in all_signs(n-1):
for s in '+-':
yield (s,) + tail
def perform_operations(nums, signs):
nums = list(map(int, nums))
result = nums.pop(0)
n = 1
for s in signs:
if s == '+':
result += nums.pop(0)
if s == '-':
result -= nums.pop(0)
n += 1
return result
for numbers in all_combinations(tuple(map(str, range(1, 10)))):
#print(numbers)
for signs in all_signs(len(numbers) - 1):
#print(signs)
summ = perform_operations(numbers, signs)
if summ == 100:
print(
''.join(map(
lambda x: ''.join(x),
zip(numbers, signs)))
+ numbers[-1])
Три функции:
-
all_combinations
— итератор, который выдает все числа для операций (в терминах задачи: вставляет пустые места); -
all_signs
— выдаёт все возможные сочетания знаков + и -
заданной длинны (для единообразия, это тоже итератор с рекурсией); - perform_operations
— выполняет операции.Здесь просится решение, избавленное от if-ов и кодирования операций с помощью символов.
👉 Это не оптимальное решение. Пишите свое решение в комментариях👇
@python_job_interview
📌 Тестовое задание по python
Мы уже создавали матрицу спирали, теперь создадим полноценный проект.
Необходимо реализовать Python-библиотеку, которая осуществляет получение квадратной матрицы (NxN) с удалённого сервера и возвращает её пользователю в виде List[int]. Этот список должен содержать результат обхода полученной матрицы по спирали: против часовой стрелки, начиная с левого верхнего угла (см. test case ниже).
Пример исходной матрицы:
Матрица гарантированно содержит целые неотрицательные числа. Форматирование границ иными символами не предполагается.
Требования к выполнению и оформлению
Библиотека содержит функцию со следующим интерфейсом:
...
Функция единственным аргументом получает URL для загрузки матрицы с сервера по протоколу HTTP(S).
Функция возвращает список, содержащий результат обхода полученной матрицы по спирали: против часовой стрелки, начиная с левого верхнего угла.
Взаимодействие с сервером должно быть реализовано асинхронно - посредством aiohttp, httpx или другого компонента на asyncio.
Библиотека должна корректно обрабатывать ошибки сервера и сетевые ошибки (5xx, Connection Timeout, Connection Refused, ...).
В дальнейшем размерность матрицы может быть изменена с сохранением форматирования. Библиотека должна сохранить свою работоспособность на квадратных матрицах другой размерности.
Решение задачи необходимо разместить на одном из публичных git-хостингов (GitHub, GitLab, Bitbucket). Можно также выслать решение в виде архива (zip, tar). Загружать библиотеку в PyPi или другие репозитории не требуется.
Проверка решения
Для самостоятельной проверки можно использовать следующий test case:
Загружайте свои решения и отправляйте ссылки в комментарии👇
@python_job_interview
Мы уже создавали матрицу спирали, теперь создадим полноценный проект.
Необходимо реализовать Python-библиотеку, которая осуществляет получение квадратной матрицы (NxN) с удалённого сервера и возвращает её пользователю в виде List[int]. Этот список должен содержать результат обхода полученной матрицы по спирали: против часовой стрелки, начиная с левого верхнего угла (см. test case ниже).
Пример исходной матрицы:
+-----+-----+-----+-----+
| 10 | 20 | 30 | 40 |
+-----+-----+-----+-----+
| 50 | 60 | 70 | 80 |
+-----+-----+-----+-----+
| 90 | 100 | 110 | 120 |
+-----+-----+-----+-----+
| 130 | 140 | 150 | 160 |
+-----+-----+-----+-----+
Матрица гарантированно содержит целые неотрицательные числа. Форматирование границ иными символами не предполагается.
Требования к выполнению и оформлению
Библиотека содержит функцию со следующим интерфейсом:
async def get_matrix(url: str) -> List[int]:
...
Функция единственным аргументом получает URL для загрузки матрицы с сервера по протоколу HTTP(S).
Функция возвращает список, содержащий результат обхода полученной матрицы по спирали: против часовой стрелки, начиная с левого верхнего угла.
Взаимодействие с сервером должно быть реализовано асинхронно - посредством aiohttp, httpx или другого компонента на asyncio.
Библиотека должна корректно обрабатывать ошибки сервера и сетевые ошибки (5xx, Connection Timeout, Connection Refused, ...).
В дальнейшем размерность матрицы может быть изменена с сохранением форматирования. Библиотека должна сохранить свою работоспособность на квадратных матрицах другой размерности.
Решение задачи необходимо разместить на одном из публичных git-хостингов (GitHub, GitLab, Bitbucket). Можно также выслать решение в виде архива (zip, tar). Загружать библиотеку в PyPi или другие репозитории не требуется.
Проверка решения
Для самостоятельной проверки можно использовать следующий test case:
SOURCE_URL = 'https://raw.githubusercontent.com/avito-tech/python-trainee-assignment/main/matrix.txt'
TRAVERSAL = [
10, 50, 90, 130,
140, 150, 160, 120,
80, 40, 30, 20,
60, 100, 110, 70,
]
def test_get_matrix():
assert asyncio.run(get_matrix(SOURCE_URL)) == TRAVERSAL
Загружайте свои решения и отправляйте ссылки в комментарии👇
@python_job_interview