python_testit | Unsorted

Telegram-канал python_testit - Python tests

7399

Тесты и задания python разработчиков По всем вопросам- @notxxx1 @ai_machinelearning_big_data - машинное обучение @programming_books_it - бесплатные it книги @pythonl - 🐍 @ArtificialIntelligencedl - AI @datascienceiot -ds книги

Subscribe to a channel

Python tests

🔥 Python + AI без игрушечных демок. Курс для тех, кто хочет собирать рабочие системы.

Stepik: «Python современный AI для разработчика и автоматизации задач»

63 урока, 382 шага, практика с кодом и автопроверкой.

Внутри: RAG, tool calling, агенты, evals, MCP, Ollama, vLLM, pgvector + HNSW, безопасный text-to-SQL, prompt injection, кэш, очереди и sandbox для агентного кода.

Плюс реальные автоматизации: почта, отчёты, боты, вебхуки и браузерные сценарии.

Для тех, кто уже знает Python и хочет перейти к production AI.

⏳ 72 часа скидка 55%

https://stepik.org/a/295921

Читать полностью…

Python tests

🐍 Python Pop Quiz: что окажется внутри `silly_dict`?

Вопрос звучит просто, но тут ловушка в том, как Python работает с ключами словаря.

Варианты:

A) {"py": "amazing"}
B) {"py": 10}
C) {"py": "amazing", <__main__.MyClass object at ...>: 10}
D) None of the above

Суть в том, что ключи в dict сравниваются не по тому, как они выглядят в коде, а через __hash__ и __eq__.

Если объект пользовательского класса имеет такой же хеш, как строка "py", и при сравнении считается равным этой строке, то Python решит: это один и тот же ключ.

В таком случае новое значение просто перезапишет старое.

Ответ: B) `{"py": 10}`

Маленький пример, но отлично показывает важную вещь: в Python ключ словаря - это не “текстовое имя”, а объект с правилами хеширования и сравнения.

Читать полностью…

Python tests

Что выведет код ?

📲Max

Читать полностью…

Python tests

Что выведет код в Python 3?

Читать полностью…

Python tests

🧠 Python-задача с собеседования: найди ошибку

Код должен посчитать количество чисел больше среднего значения в списке.


def count_above_avg(nums, avg=sum(nums)/len(nums)):
count = 0
for n in nums:
if n > avg:
count += 1
return count

data1 = [1, 2, 3, 4, 5]
data2 = [10, 20, 30]

print(count_above_avg(data1))
print(count_above_avg(data2))


Проблема в этой строке:

```python
def count_above_avg(nums, avg=sum(nums)
/len(nums)):
```
Здесь используется значение по умолчанию, которое вычисляется один раз — в момент определения функции, а не при каждом её вызове.

Что происходит по шагам:

Когда Python читает определение функции, он сразу считает:

sum(nums)
/len(nums)
Но nums в этот момент - это первый переданный список, то есть data1.

Значение avg фиксируется и больше не меняется.

При вызове:

• count_above_avg(data2)
• среднее значение не пересчитывается, используется старое — от data1.

Поэтому логика ломается, функция работает с неверным средним.

📌 Это известная ловушка Python
Значения аргументов по умолчанию вычисляются один раз.
Это та же причина, почему списки и словари в дефолтных параметрах часто приводят к багам.

🛠 Правильное решение
Нужно вычислять среднее внутри функции, а не в параметрах:

```python
def count_above_avg(nums, avg=None):
if avg is None:
avg = sum(nums) / len(nums)
return sum(1 for n in nums if n > avg)
```

Теперь среднее будет считаться заново при каждом вызове.

💡 Главное правило
Никогда не используй вычисляемые или изменяемые объекты как значения по умолчанию:

❌ def f(x, lst=[])
❌ def f(x, avg=sum(x)
/len(x))

✅ Используй None и считай внутри функции.

Читать полностью…

Python tests

Безопасность, автоматизация, ИИ — всё в одном релизе

SourceCraft представил релиз, где каждая деталь продумана для командной эффективности.

• ИИ-обновления:
улучшенный поиск уязвимостей, внутренняя система для проверки безопасности кода и генерация описаний к изменениям.
• Совместная работа: поддержка Gitlab CI/CD YAML, удобная работа с релизами и web-решение конфликтов в PR.
• Безопасный кодинг: дэшборд уязвимостей по всем репозиториям, страница Code Scanning (SAST), rescan и список библиотек с уязвимостями в SCA, а еще SourceCraft прошёл оценку соответствия требованиям ФЗ-152, PCI DSS, ГОСТ 57580.

✨ Обновился интерфейс CI/CD и появились уведомления о сборках через Telegram.

Расскажем в подробностях и ответим на вопросы в канале

Читать полностью…

Python tests

🐍 Хитрая ловушка в Python, на которую попадаются даже опытные


matrix = [[0] * 3] * 3

matrix[0][0] = 1
matrix[1].append(9)

print(matrix)
print(len(matrix))
print(len(matrix[0]))


Интуитивно кажется, что это создаёт независимые строки матрицы.
Но на самом деле Python копирует ссылки - все три строки указывают на один и тот же список.

🔍 Поэтому изменение matrix[0][0] или append() влияет сразу на все строки.

🧠 Вывод программы:

[[1, 0, 0, 9],
[1, 0, 0, 9],
[1, 0, 0, 9]]
3
4


✔️ Как правильно создавать матрицу с независимыми строками:

matrix = [[0] * 3 for _ in range(3)]


Теперь каждая строка - отдельный список, и изменения не “протекают” по всей матрице.

Читать полностью…

Python tests

Вопрос с собеседования

Что выведет этот код и почему?


a = [1, 2, 3]
b = a

a += [4, 5]

print(a)
print(b)

a = (1, 2, 3)
b = a

a += (4, 5)

print(a)
print(b)


Попробуй сначала сам ответить, а потом смотри разбор.


Часть 1. Списки
a = [1, 2, 3]
b = a

a += [4, 5]

print(a)
print(b)


Что происходит по шагам:

a = [1, 2, 3]


Переменная a ссылается на список [1, 2, 3].

b = a
Теперь b ссылается на тот же самый список, что и a.
Не копия, а один и тот же объект в памяти.

a += [4, 5]
Важно: для списков += работает как изменение объекта на месте:
это примерно то же самое, что:

a.extend([4, 5])


То есть в существующий список, на который ссылаются и a, и b, добавляются элементы 4 и 5.

Поэтому:

print(a) # [1, 2, 3, 4, 5]
print(b) # [1, 2, 3, 4, 5]


Оба указывают на один изменённый список.

Часть 2. Кортежи
a = (1, 2, 3)
b = a

a += (4, 5)

print(a)
print(b)


Кортежи неизменяемы, и здесь начинается магия.

a = (1, 2, 3)
a ссылается на кортеж (1, 2, 3).

b = a
b ссылается на тот же кортеж (1, 2, 3).

a += (4, 5)
Для кортежей += уже не может менять объект на месте (они immutable).
Поэтому Python делает так:

a = a + (4, 5)


То есть создаётся новый кортеж (1, 2, 3, 4, 5) и переменная a переназначается на него.

b при этом остаётся смотреть на старый кортеж (1, 2, 3).

Поэтому:

print(a) # (1, 2, 3, 4, 5)
print(b) # (1, 2, 3)

В чём хитрость

Для списка a += [4, 5] мутирует объект на месте, и это видно через все переменные, которые на него ссылаются.

Для кортежа a += (4, 5) создаёт новый объект и переназначает только a.

Итого:


# Часть со списком:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

# Часть с кортежем:
(1, 2, 3, 4, 5)
(1, 2, 3)


Если хочешь, могу ещё один хитрый вопрос разобрать - про изменяемые значения по умолчанию в аргументах функции или про циклы и замыкания.

Читать полностью…

Python tests

👩‍💻 Что выведет этот код и почему?

@python_job_interview

Читать полностью…

Python tests

🔍 Открытое собеседование на Python-бекендера с разработчиком из Avito и Яндекс в четверг

14 августа (уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Python-разработчика.

Как это будет:
📂 Савва Демиденко, ТехЛид с опытом в Яндексе и Авито, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Савва будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Савве

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Python-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_py_bot

Реклама.
О рекламодателе.

Читать полностью…

Python tests

🖥 Что выведет код ниже?


def append_to_list(val, my_list=[]):
my_list.append(val)
return my_list

print(append_to_list(1))
print(append_to_list(2))
print(append_to_list(3))


🤯 Подвох
Многие думают, что каждый вызов append_to_list() создаёт новый список, и ожидают вывод:


[1]
[2]
[3]

Но на самом деле Python выведет:


[1]
[1, 2]
[1, 2, 3]

🧠 Почему так происходит?
В Python значения аргументов по умолчанию вычисляются один раз — при определении функции, а не при каждом вызове.

Значение my_list=[] создаётся один раз и сохраняется между вызовами. Это работает как статическая переменная внутри функции.

✅ Как это исправить?
Используй None как значение по умолчанию:


def append_to_list(val, my_list=None):
if my_list is None:
my_list = []
my_list.append(val)
return my_list

print(append_to_list(1)) # [1]
print(append_to_list(2)) # [2]
print(append_to_list(3)) # [3]

💡 Вывод
Не используйте изменяемые объекты (например, list, dict, set) как значения по умолчанию для аргументов функций в Python.


@pythonl

Читать полностью…

Python tests

⚙️ Подменяй любые импорты в Python “на лету” — без изменения кода

Если ты хочешь протестировать модуль, подменить зависимость, замокать внешний сервис или обмануть импорт — не обязательно редактировать исходники. Python позволяет перехватывать импорты прямо во время выполнения, через sys.modules.

Вот минимальный приём, который делает это прозрачно:


import sys
import types

# Создаём фейковый модуль
fake = types.SimpleNamespace()
fake.get_data = lambda: "подмена работает"

# Подменяем импорт
sys.modules['external_service'] = fake

# Теперь даже import будет работать
import external_service
print(external_service.get_data()) # → "подмена работает"

Читать полностью…

Python tests

🐍 Python-задача: что выведет этот код и почему?


def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list

print(append_to_list(1))
print(append_to_list(2))
print(append_to_list(3))


🔍 Варианты:
• a) [1], [2], [3]
• b) [1], [1, 2], [1, 2, 3]
• c) Ошибка исполнения
• d) [1], [2], [3] — но в разных объектах

💡 Разбор:

Аргумент my_list=[] — изменяемый объект, созданный один раз при компиляции функции, а не каждый раз при вызове. Поэтому:

- Первый вызов:
my_list = [] → добавили 1 → [1]
- Второй вызов: та же
my_list, теперь [1] → добавили 2 → [1, 2]
- Третий: тот же список →
[1, 2, 3]

✅ Правильный ответ: b) `[1]`, `[1, 2]`, `[1, 2, 3]`

🧠 Вывод: никогда не используй изменяемые значения (`list`,
dict, `set`) в аргументах по умолчанию. Это одна из самых частых ловушек в Python.

🛠️ Правильный способ:



def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list


📌 Теперь каждый вызов будет работать с новым списком.

Читать полностью…

Python tests

Что выведет код?

class B:
def __init__(self) :
print ('В', end='')
super().__init__()
class C:
def __init__(self):
print('C', end='')
super().__init__ ()
class D(B, C):
def __init__(self):
print('D', end='')
B.__init__(self)
C.__init__(self)
X = D()

Читать полностью…

Python tests

⚡️Легкий способ получать свежие обновления и следить за трендами в разработке на вашем языке. Находите свой стек и подписывайтесь:

Python: t.me/pythonl
Linux: t.me/linuxacademiya
Собеседования DS: t.me/machinelearning_interview
Нерйросети t.me/ai_machinelearning_big_data
C++ t.me/cpluspluc
Docker: t.me/DevopsDocker
Хакинг: t.me/linuxkalii
Devops: t.me/DevOPSitsec
Data Science: t.me/data_analysis_ml
Javascript: t.me/javascriptv
C#: t.me/csharp_ci
Java: t.me/javatg
Базы данных: t.me/sqlhub
Python собеседования: t.me/python_job_interview
Мобильная разработка: t.me/mobdevelop
Golang: t.me/Golang_google
React: t.me/react_tg
Rust: t.me/rust_code
ИИ: t.me/vistehno
PHP: t.me/phpshka
Android: t.me/android_its
Frontend: t.me/front
Big Data: t.me/bigdatai
МАТЕМАТИКА: t.me/data_math
Kubernets: t.me/kubernetc
Разработка игр: /channel/gamedev
Haskell: t.me/haskell_tg
Физика: t.me/fizmat

💼 Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: /channel/addlist/2Ls-snqEeytkMDgy
Папка FRONTEND: /channel/addlist/mzMMG3RPZhY2M2Iy

😆ИТ-Мемы: t.me/memes_prog
🇬🇧Английский: t.me/english_forprogrammers
🧠ИИ: t.me/vistehno

🎓954ГБ ОПЕНСОРС КУРСОВ: @courses
📕Ит-книги бесплатно: /channel/addlist/BkskQciUW_FhNjEy

Читать полностью…

Python tests

🖥 На stepik обновили курс Python в 2026 - рабочий инструмент для автоматизации, ботов, парсинга, API, данных и разработки с ИИ.

Проблема новичков в том, что они учат Python кусками: синтаксис, пару задач, немного теории - и потом не понимают, как собрать из этого реальный проект.

Этот курс закрывает именно этот разрыв. Здесь вы не просто смотрите уроки, а учитесь писать код, разбирать ошибки и собирать рабочие решения на практике.

Внутри:

- Python с нуля
- много практики без сухой теории
- реальные задачи и проекты
- автоматизация рутины
- работа с файлами, данными и API
- понятная логика программирования
- современная разработка с ИИ
- отдельный блок по вайбкодингу

Вайбкодинг это нормальный навык 2026 года и вас научат- правильно ставить задачу, проверять код, понимать результат и быстрее доводить проект до рабочего состояния.

48 часов скидка 60%: https://stepik.org/course/288218/

Читать полностью…

Python tests

🚀 Ты всё ещё называешь обёртку над ChatGPT «AI-продуктом»?

Пока ты пишешь промпты - рынок уже ушёл дальше.

Сейчас выигрывают не те, кто умеет красиво формулировать запросы, а те, кто строит агентные системы:
- принимают решения сами
- ходят в API
- работают с Postgres и Redis
- управляют браузером через Playwright
- доводят задачи до результата без человека

И вот правда, о которой мало говорят:

90% таких систем умирают между ноутбуком и продом.

Работает локально. Ломается в реальности.
Нет архитектуры. Нет устойчивости. Нет деплоя.

AI Agents Engineering - курс со Stepik, который закрывает этот разрыв.

- LangGraph, AutoGen, Computer Use
- архитектура агентов, а не «скрипты на коленке»
- LLMOps, логирование, стабильность
- деплой в Docker и работа в проде

8 модулей, 120+ шагов, всё через практику.

На выходе не «сертификат ради галочки», а:
- рабочий production-агент
- понимание, как строить такие системы с нуля
- навыки, за которые уже платят

Сейчас самое окно входа.
Через полгода это станет базой, а не преимуществом.

Скидка 55% действует ещё 48 часов: https://stepik.org/a/276971/

Читать полностью…

Python tests

Python-баг, который выглядит безобидно… но ломает логику 👇


fruits = ["apple", "lime", "orange",
"pineapple", "orange"]

for f in fruits:
if f == "orange":
fruits.remove(f)

print(fruits)


Ожидание: оба orange удалятся.

Реальность: один orange остаётся.

Почему так происходит?

Ты изменяешь список во время итерации.
После удаления элементы сдвигаются, и цикл пропускает следующий элемент.

Это классический сценарий продакшн-багов:

• код выглядит правильно
• тесты могут пройти
• но данные обрабатываются неправильно

Правильный вариант:

fruits = [f for f in fruits if f != "orange"]


Мораль:
Изменяешь коллекцию во время обхода -Deploy first. Pray later.

#junior #python

@pythonl

Читать полностью…

Python tests

🖥 Большинство “парсеров” умирают через 2 дня.
Ты научишься делать те, которые живут в проде.

Это не про BeautifulSoup ради галочки.
Это про системы сбора данных, которые:

• не падают от мелких правок на сайте
• собирают данные в разы быстрее
• обновляют всё сами по расписанию
• обходят ограничения и баны
• выглядят как сервис, а не хаос из файлов

Ты начнёшь видеть сайты не как страницы, а как источники данных, к которым можно подключиться.

В итоге ты сможешь:

• забирать данные для своих проектов
• автоматизировать чужую рутину
• делать инструменты для аналитики
• брать коммерческие заказы на сбор данных

Это навык, который напрямую превращается в деньги.
Не “знаю Python”, а умею добывать данные из интернета профессионально.

🎁 48 часов скидка 50% на Stepik: https://stepik.org/a/269942/

Читать полностью…

Python tests

🖥 На Stepik вышел курс, который учит работать с Docker на реальных проектах.

Владение Docker - навык, который отличает новичка от профи

Сегодня почти всё разворачивается в контейнерах.

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

Этот курс покажет:

• разобраны все возможные ошибки при работе c Docker
• как упаковывать проекты в контейнеры
• как поднимать целые системы за минуты
• как избегать типичных ошибок в продакшене
• как делать стабильные и повторяемые окружения

Только практика и реальные кейсы - с нуля до уверенного уровня.

🎁 40 процентов скидка действует 48 часов в честь нового года


👉 Записывайся и сделай Docker своим настоящим рабочим инструментом.

Читать полностью…

Python tests

Что выведет код ?

Пишите ответ в комментариях

Читать полностью…

Python tests

✔️ Как организовать архитектуру большого Python-проекта?

Главная цель - чтобы через полгода было не стыдно открывать код: понятно где что лежит, как это тестировать и куда встраивать новые фичи.

Основные принципы:
- Разделяй по ответственности, а не по типу файла
- Минимизируй связь между слоями
- Явно отделяй ядро домена от инфраструктуры (БД, HTTP, очереди)

Пример базовой структуры:
- app/
- api/ - HTTP handlers, REST, gRPC, CLI
- services/ - бизнес-логика, сценарии use case
- domain/ - сущности, модели, value objects
- repositories/ - работа с БД, кэшами, внешними сервисами
- config/ - настройки, env, схемы конфигурации
- utils/ - вспомогательные функции, которые не завязаны на домен
- tests/ - тесты по тем же модулям, что и в app/
- scripts/ - миграции, разовые утилиты, maintenance

Рекомендации:
- Один входной файл (main.py или cli.py), вся логика - в app/*
- Конфигурацию не хардкодить, а прокидывать через env и config-объекты
- Внутри services работать с абстрактными интерфейсами репозиториев, а не с конкретным ORM
- С самого начала заводить тесты, пусть даже простые, и поддерживать схему tests/ в том же дереве, что и код
- Любой новый модуль должен отвечать на вопрос: к какому слою относится и от кого ему можно зависеть

Если проект растет, не бойся дробить:
- крупный модуль на подмодули
- общие зависимости в отдельный layer (shared, common)
- разные bounded context в отдельные пакеты внутри app/

Архитектура большого проекта - это не про идеальный паттерн, а про понятные границы и минимальный хаос.

https://uproger.com/kak-organizovat-arhitekturu-bolshogo-python-proekta/

Видео: https://www.youtube.com/watch?v=Dk7A8ElHcKE

Читать полностью…

Python tests

❌Python: Никогда не делай так!!!

НИКОГДА НЕ ИСПОЛЬЗУЙ МУТАБЕЛЬНЫЕ ДЕФОЛТЫ: не используй изменяемые объекты (например, списки или словари) как значения по умолчанию в аргументах функции.
Каждый вызов функции будет делить один и тот же объект, и ты получишь «призрачные» данные, которые появляются из ниоткуда. Это одна из самых коварных ловушек Python.

Всегда используй None и создавай новый объект внутри функции. Подписывайся, больше фишек каждый день !


Плохо — список живёт между вызовами
def add_item(item, bucket=[]):
bucket.append(item)
return bucket

print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] — неожиданно!

# Правильно
def add_item(item, bucket=None):
if bucket is None:
bucket = []
bucket.append(item)
return bucket

print(add_item(1)) # [1]
print(add_item(2)) # [2]

Читать полностью…

Python tests

👩‍💻 Что выведет этот код и почему?

Читать полностью…

Python tests

🖥 ЗАДАЧА С СОБЕСЕДОВАНИЯ: что выведет код?

Что выведет следующий код — и почему?


a = 256
b = 256
print(a is b)

x = 257
y = 257
print(x is y)


❓Ожидаешь True в обоих случаях? Не всё так просто.

📌 В Python целые числа от -5 до 256 кешируются.
То есть a и b указывают на один и тот же объект → a is b → True

Но x и y — это уже разные объекты, потому что 257 не кешируется → x is y → False

⚠️ is сравнивает объекты, а не значения.
Если хочешь сравнить значения — используй ==

💡 Вывод: даже базовые типы могут вести себя неожиданно, если сравнивать их через is.

Читать полностью…

Python tests

🧠 Хитрая задача по Python — что не так с set и списками?

Задача:
Вы хотите получить уникальные элементы из вложенных списков:


items = [[1, 2], [3, 4], [1, 2]]

unique = set(items)
print(unique)


Что произойдёт?

Варианты ответа:
1. Выведется: {[1, 2], [3, 4]}
2. Выведется: [[1, 2], [3, 4]]
3. Произойдёт ошибка
4. Все вложенные списки преобразуются в кортежи и выведутся без дубликатов

Правильный ответ: 3. Произойдёт ошибка

💥 TypeError: unhashable type: 'list'

🔍 Разбор

В Python элементы set должны быть хешируемыми. А списки — изменяемый тип данных, следовательно, не хешируемы.

То есть:


set([[1, 2], [3, 4]])
# ❌ вызовет ошибку


✅ Как сделать правильно?

Если вы хотите получить уникальные вложенные списки, можно преобразовать их в кортежи:


items = [[1, 2], [3, 4], [1, 2]]
unique = set(tuple(x) for x in items)
print(unique) # {(1, 2), (3, 4)}


А если хочется вернуть результат обратно в список списков:


result = [list(x) for x in unique]
print(result) # [[1, 2], [3, 4]] (порядок не гарантирован)


⚠️ Вывод

- list нельзя положить в set, dict как ключ — они unhashable
- Используйте tuple для таких случаев
- Уникальность вложенных списков — частый источник багов при работе с JSON, DataFrame, API

📌 Такие мелочи легко упустить, но они выстреливают в самых неожиданных местах. Подписывайся, чтобы не наступать на грабли в одиночку.

Читать полностью…

Python tests

🐍 Python-задача: что выведет этот код с вложенными генераторами?


gen = (x for x in range(3))

def wrap(g):
return (x * 2 for x in g)

gen2 = wrap(gen)

print(list(gen))
print(list(gen2))


🔍 Варианты:
• a) [0, 1, 2], [0, 2, 4]
• b) [0, 1, 2], []
• c) [], [0, 2, 4]
• d) [0, 1, 2], Ошибка

💡 Разбор:

- `gen = (x for x in range(3))` — генератор 0, 1, 2
- `wrap(gen)` — создаёт **новый генератор**, который берёт значения из `gen` и умножает на 2

Но генераторы **исчерпаемы**: после первого полного прохода `list(gen)` → `gen` становится пустым

Значит:

- `list(gen)` → `[0, 1, 2]`
- `gen2 = wrap(gen)` теперь ссылается на **пустой** `gen`
- `list(gen2)` → `[]`

✅ **Правильный ответ: b) `[0, 1, 2]`, `[]`**

🧠 **Вывод:** если оборачиваешь генератор — не "прожигай" его до передачи дальше. Генераторы нельзя перезапустить или "перемотать".

🛠️ Совет: если данные нужны повторно — сохрани их в список:

```
python
data = list(gen)
```

или используй itertools.tee для разветвления итератора.

@pythonl

Читать полностью…

Python tests

🧠 Хитрая Python-задача: «Генератор, который взламывает итераторы»
Уровень: 💥 продвинутый (Python 3.12+)

Представьте, что у вас есть ленивый генератор, перебирающий огромный набор данных. Нужно «клонировать» итератор — создать копию, продолжающую работу с того же места, хотя обычные генераторы так не умеют.

🎯 Цель
Напишите cloneable(generator), которая:

● Принимает любую функцию-генератор или итерируемый объект
● Возвращает объект с методом clone(), создающим независимую копию текущего состояния
● Позволяет параллельно вызывать next() у оригинала и всех клонов


gen = cloneable(range(100))
it1 = gen.clone()
it2 = gen.clone()

next(it1) # 0
next(it1) # 1
next(it2) # 0 ← независимая позиция


💡 Ограничения
● Нельзя полностью буферизовать всю последовательность
● Память O(k), где k — число активных клонов
● Только стандартная библиотека; асинхронность не требуется

🔍 Идея решения
● Храним значения в collections.deque по мере чтения из исходного итератора
● Для каждого клона ведём текущий индекс в буфере
● После сдвига всех клонов дальше минимальной позиции — удаляем хвост буфера

✅ Скелет реализации

from collections import deque

class CloneableIterator:
def __init__(self, iterable):
self._source = iter(iterable)
self._buffer = deque()
self._positions = []

def clone(self):
pos = 0
self._positions.append(pos)
idx = len(self._positions) - 1

def _iter():
nonlocal pos
while True:
if pos < len(self._buffer):
yield self._buffer[pos]
else:
try:
val = next(self._source)
except StopIteration:
return
self._buffer.append(val)
yield val
pos += 1
self._positions[idx] = pos
self._shrink()

return _iter()

def _shrink(self):
if not self._positions:
return
min_pos = min(self._positions)
for _ in range(min_pos):
self._buffer.popleft()
self._positions = [p - min_pos for p in self._positions]

def cloneable(iterable):
return CloneableIterator(iterable)


📌 Пример использования


gen = cloneable(i**2 for i in range(5))
a = gen.clone()
b = gen.clone()

print(next(a)) # 0
print(next(a)) # 1
print(next(b)) # 0
print(next(b)) # 1
print(next(b)) # 4


Попробуйте улучшить решение:
● Добавьте защиту от «зомби-клонов»
● Реализуйте __length_hint__()
● Или сделайте асинхронную версию acloneable() на базе async for

Читать полностью…

Python tests

🐍 Хитрая задача на Python с подвохом

📌 Задача:
Ты пишешь функцию track, которая возвращает список всех значений, которые в неё передавали. Пример поведения:


print(track(1)) # [1]
print(track(2)) # [1, 2]
print(track(3)) # [1, 2, 3]


Реализуй эту функцию.

🎯 Подвох:
- Решение работает без глобальных переменных
- Используется поведение изменяемых аргументов по умолчанию
- Это поведение часто становится причиной багов у новичков — но здесь оно работает на нас

---

✅ Ожидаемый результат:


def track(value, cache=[]):
cache.append(value)
return cache

# Проверка:
print(track(1)) # [1]
print(track(2)) # [1, 2]
print(track(3)) # [1, 2, 3]


🧠 Объяснение подвоха:

- Аргумент
cache=[] вычисляется один раз, при первом вызове функции
- Все последующие вызовы используют один и тот же список
- Обычно это считается "ловушкой", но в задачах на замыкание состояния — это полезный трюк

⚠️ Не путай: если внутри функции ты напишешь
cache = [], то всё сломается — потому что создастся новый список каждый раз

Читать полностью…

Python tests

Что выведет этот код при запуске на Python 3.10+ (например, 3.11)?


📌 Подсказка: Подумайте о порядке проверок, о том, какие атрибуты попадают в others, и об использовании __match_args__.

Ответ:

Automatic mode
Mode manual, other keys: ['threshold', 'debug']
Low threshold 0
Краткое пояснение:

Для первого объекта (mode="auto", threshold=10) срабатывает первый case Config(mode="auto") → Automatic mode.

Для второго (mode="manual", threshold=5, debug=True) первый не совпадает, второй с threshold<5 не проходит (5 < 5 → False), зато третий case Config(mode=mode, **others) — биндинг mode='manual', остальные ключи (threshold и debug) попадают в others → Mode manual, other keys: ['threshold', 'debug'].

Для третьего (threshold=0) первый и третий не подходят (нет mode), а второй — case Config(threshold=threshold) if threshold<5 — срабатывает (0<5) → Low threshold 0.

Читать полностью…
Subscribe to a channel