uk
Feedback

Не попадись на ботовода! Telemetrio знаходить і позначає такі канали мітками 👉 Хочеш бачити мітку, оформляй підписку

Программистика

Программистика

Закритий канал

Лучший канал про python Ссылка для друга: https://t.me/+Ai6ughKtf5g2ZmFi Купить рекламу: https://telega.in/c/+Ai6ughKtf5g2ZmFi Админ: @JeyRahol По рекламе: @ReivuManager

Показати більше
5 799
Підписники
+3224 години
+187 днів
-4030 днів
Архів дописів
🚫 5 ошибок новичков в Python (и как их не допускать) Каждый начинающий разработчик наступает на одни и те же грабли. Эти ошибки кажутся мелочами, но они могут стоить часов отладки. Вот список самых частых — и как их избежать. 1. Изменяемые объекты как аргументы по умолчанию ❌ Плохо:
def add_user(name, users=[]):
    users.append(name)
    return users

print(add_user("Алиса"))  # ['Алиса']
print(add_user("Боб"))    # ['Алиса', 'Боб'] — сюрприз!
✔️ Хорошо:
def add_user(name, users=None):
    if users is None:
        users = []
    users.append(name)
    return users
Почему: Аргумент по умолчанию создаётся один раз при определении функции, а не при каждом вызове. Список общий для всех вызовов. 2. `==` vs `is` — сравнение значений и идентичности ❌ Плохо:
if a is 5:   # работает, но не гарантировано
    print("Пять")
✔️ Хорошо:
if a == 5:   # сравниваем значения
    print("Пять")
Почему: is сравнивает идентичность объектов (адреса памяти), == — значения. Для чисел и строк Python иногда кэширует объекты, но полагаться на это нельзя. Используйте is только для None и констант. 3. Изменение списка во время итерации ❌ Плохо:
numbers = [1, 2, 3, 4, 5]
for x in numbers:
    if x % 2 == 0:
        numbers.remove(x)
print(numbers)  # [1, 3, 5] — не все чётные удалены
✔️ Хорошо:
numbers = [1, 2, 3, 4, 5]
numbers = [x for x in numbers if x % 2 != 0]
print(numbers)  # [1, 3, 5]
# Или итерация по копии:
for x in numbers[:]:
    if x % 2 == 0:
        numbers.remove(x)
Почему: При удалении элементов индексы сдвигаются, и итератор может пропускать элементы. --- 4. Конкатенация строк в цикле (`+` вместо `join`) ❌ Плохо:
result = ""
for word in ["A", "B", "C"]:
    result += word
✅ Хорошо:
result = "".join(["A", "B", "C"])
Почему: Строки неизменяемы. Каждая операция += создаёт новую строку, что приводит к квадратичному росту сложности. Для больших данных это ощутимо. 5. `range(len(...))` вместо `enumerate` ❌ Плохо:
items = ['a', 'b', 'c']
for i in range(len(items)):
    print(i, items[i])
✔️ Хорошо:
items = ['a', 'b', 'c']
for i, item in enumerate(items):
    print(i, item)
Почему: Код с enumerate читается лучше, он меньше подвержен ошибкам и работает с любыми итерируемыми объектами, а не только с индексируемыми. 💡 Запомни: 🔴 Избегай изменяемых объектов как аргументов по умолчанию. 🔴 == для значений, is для идентичности (особенно с None). 🔴 Не изменяй список во время итерации — используй копию или списковое включение. 🔴 Для сборки строк используй ''.join(). 🔴 В цикле с индексом и значением предпочти enumerate Программистика|| #doc

👩‍💻 Гайд по Python параллелизму: Async, Потоки, Процессы
📱 Первоисточник
Программистика|| #video

🧹 Лайфхак: `_` для игнорирования значений При распаковке часто попадаются ненужные элементы. Не придумывайте имена для мусора — используйте подчёркивание.
# Берём только первый и последний
first, *_, last = [10, 20, 30, 40, 50]
print(first, last)  # 10 50

# Игнорируем второй элемент
x, _, z = (1, 2, 3)
print(x, z)  # 1 3

# В циклах, если индекс не нужен
for _ in range(5):
    print("Привет")
🟢 Запомни: _ — обычная допустимая переменная, но по соглашению означает «значение не нужно». Экономит имена и показывает намерение. Программистика|| #tips

🖥 Cookiecutter — это кроссплатформенный инструмент командной строки для быстрого создания проектов на основе шаблонов! Он ис
🖥 Cookiecutter — это кроссплатформенный инструмент командной строки для быстрого создания проектов на основе шаблонов!
Он используется для генерации проектов в различных языках программирования, включая Python, C и другие, упрощая настройку стандартных структур каталогов и файлов. 💡 Cookiecutter позволяет создавать проекты, используя как удалённые шаблоны (например, из GitHub), так и локальные, без необходимости знаний Python. Инструмент поддерживает пользовательские параметры, расширяемость, работу с любым форматом файлов, а также интеграцию с pipx для удобной установки.
Программистика|| #Репозиторий

Решать технические задачи — самая простая часть работы в IT. Сложности начинаются там, где нужно договариваться со смежниками
Решать технические задачи — самая простая часть работы в IT. Сложности начинаются там, где нужно договариваться со смежниками, выстраивать процессы в хаосе и осознанно управлять карьерой. В канале @ulshinblog Никита (руководитель разработки в Highload, 10+ лет в IT) разбирает эти темы через понятную логику и личный опыт: 📍 Как пройти секцию System Design? Пошаговый чек-лист от интервьюера; 📍 Как находить внутренние сайд-проекты, которые принесут пользу и бизнесу, и вашему карьерному росту; 📍 Защита от плохой обратной связи: как вежливо поставить на место коллегу с неконструктивным фидбеком; 📍 Инженерный конвейер самообучения: как перестать читать книги для галочки и внедрять знания в жизнь и карьеру; 📚 База 50+ авторских обзоров IT-литературы для сильного инженера: разработка, управление, архитектура, мышление. 👉 Присоединяйтесь

🧩 Распаковка (unpacking) по-взрослому: `*`, `` и всё, что вы могли пропустить** Все знают a, b = 1, 2. Но распаковка в Python гораздо глубже. Это мощный инструмент, который позволяет писать лаконичный и выразительный код без лишних индексов и временных переменных. Разбираем продвинутые приёмы. 📦 Распаковка с `*` (звёздочка) — остаток последовательности Звёздочка забирает «всё остальное» в список.
first, *middle, last = [1, 2, 3, 4, 5]
print(first)   # 1
print(middle)  # [2, 3, 4]
print(last)    # 5
Можно использовать в любом месте, но только один раз.
*_, last = [1, 2, 3]  # игнорируем всё, кроме последнего
print(last)  # 3
📦 Распаковка итераторов (не только списков) Звёздочка работает с любым итерируемым объектом.
def gen():
    yield 1
    yield 2
    yield 3

first, *rest = gen()
print(first, rest)  # 1 [2, 3]
📦 Распаковка в вызовах функций: `func(*args)` Передаём элементы списка как отдельные аргументы.
def add(a, b, c):
    return a + b + c

nums = [10, 20, 30]
print(add(*nums))  # 60
Особенно полезно для print:
items = ['a', 'b', 'c']
print(*items, sep=', ')  # a, b, c
📦 Распаковка словарей: `**kwargs` Две звёздочки — для словарей. Передаёт пары ключ-значение как именованные аргументы.
def user_info(name, age):
    print(f"{name}, {age} лет")

data = {'name': 'Алиса', 'age': 30}
user_info(**data)  # Алиса, 30 лет
💡 Запомни: - * — распаковывает последовательности (списки, кортежи, строки, генераторы). - ** — распаковывает словари (в именованные аргументы или слияние). - Можно комбинировать в одном выражении. - Не злоупотребляй сложной вложенной распаковкой — читаемость важнее. Программистика|| #doc

👩‍💻 fastapi-injectable — расширение для FastAPI, которое улучшает систему внедрения зависимостей, делая её доступной за пре
👩‍💻 fastapi-injectable — расширение для FastAPI, которое улучшает систему внедрения зависимостей, делая её доступной за пределами HTTP-маршрутов!
Это особенно полезно для случаев, когда нужно использовать зависимости в контекстах, таких как фоновые задачи, команды CLI, или другие сценарии, не связанные с обработкой HTTP-запросов. Библиотека предоставляет возможность применения декоратора Depends для внедрения зависимостей в различных частях приложения, что упрощает повторное использование кода и делает архитектуру более гибкой.
Программистика|| #Репозиторий

🧠 Загадка на ночь: что выведет этот код?
print(any([]))
print(all([]))
Варианты: 1. False и False 2. True и True 3. False и True 4. True и False Пиши свой вариант в комментарии! Программистика || #quiz

🔥 Логируй как профи: что не так с print() и как писать логи правильно Логирование — это как чёрный ящик самолёта: пока всё работает, про него не думаешь. Но когда что-то ломается, без него — катастрофа. И да, print() — это не логирование, даже если вы очень его любите. 🧱 Почему не print()?
🟢 print() не умеет разделять уровни сообщений (ошибка или просто инфо) 🟢 Его нельзя легко перенаправить в файл или на удалённый сервер 🟢 В продакшене вы не сможете отследить проблему, если логи разбросаны по консоли
📌 Базовое логирование
import logging

logging.basicConfig(level=logging.INFO)
logging.info("Приложение запущено")
📎 basicConfig быстро включит логирование, но на продакшене лучше задавать формат и место хранения. 🎯 Уровни логов
🟢 DEBUG — детальная отладка 🟢INFO — обычная информация 🟢 WARNING — что-то подозрительное 🟢ERROR — ошибка, но система ещё жива 🟢CRITICAL — всё очень плохо
📦 Логи в файл
logging.basicConfig(
    filename='app.log',
    level=logging.INFO,
    format='%(asctime)s — %(levelname)s — %(message)s'
)
Теперь логи сохраняются в app.log с временем и уровнем. 🔄 Ротация логов Чтобы файл логов не вырос до гигабайтов:
from logging.handlers import RotatingFileHandler

handler = RotatingFileHandler('app.log', maxBytes=2_000_000, backupCount=5)
logging.basicConfig(
    handlers=[handler],
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
📎 При достижении 2MB файл заменяется, и хранится 5 последних копий. 🧪 Логируем ошибки с трассировкой
try:
    1 / 0
except ZeroDivisionError:
    logging.exception("Ошибка деления на ноль")
➡️logging.exception() автоматически добавляет traceback в лог. 💡 Запомни:
🟢 Не логируй пароли и токены 🟢 Разделяй уровни — не пиши error там, где warning 🟢 Настрой логи под продакшен заранее, а не когда уже горит
Программистика || #Статья

⚡️ Tyro — это инструмент для генерации CLI-интерфейсов из аннотированного по типам кода Python. В отличие от устаревшего argp
⚡️ Tyro — это инструмент для генерации CLI-интерфейсов из аннотированного по типам кода Python. В отличие от устаревшего argparse, он позволяет определять аргументы стандартными аннотациями типов, значениями по умолчанию и строками документации (docstrings). Всё, что вам нужно — это определить функцию или датакласс и передать его в tyro.cli(). Инструмент отлично распознаётся IDE и статическими анализаторами (mypy, Pyright), поддерживает вложенные структуры, подкоманды и генерацию удобного текста помощи. Это лучший выбор для создания типобезопасных и хорошо документированных CLI-утилит. 🐱 Ссылка на GitHub Программистика || #Репозиторий

Айтишник, который не умеет использовать командную строку bash – так себе специалист. Если посетить несколько собеседований уровня от миддл, то можно убедиться, что вопросы про опыт работы в консоли появляются довольно часто. Сходу научиться всем командам bash нереально – их очень много. К счастью, появился канал BashMaster, в котором каждый день можно узнавать по одной небольшой связке команд и сразу же внедрять их в свою работу. Подпишись, освоишь bash на изи 👍

⌨️ Регистрация нажатий клавиш в Python — библиотека keyboard Библиотека keyboard — мощный инструмент для работы с клавиатурны
⌨️ Регистрация нажатий клавиш в Python — библиотека keyboard Библиотека keyboard — мощный инструмент для работы с клавиатурным вводом. Позволяет регистрировать нажатия/отпускания клавиш, создавать хоткеи и выполнять действия по комбинациям. Установка: pip install keyboard Пример кода:
import keyboard

# Регистрация горячей клавиши
keyboard.add_hotkey('ctrl+shift+a', lambda: print('Нажали комбинацию!'))

# Запись всех нажатий до esc
keyboard.record(until='esc')

# Блокировка ввода на 5 секунд
keyboard.block_key('a')  # Блокируем конкретную клавишу
⚠️ Важно: на Linux для работы с keyboard требуются права администратора (из-за доступа к устройствам ввода). Программистика

😒 Подборка каналов по информационной безопасности Проверенные каналы по безопасности, которые реально помогают расти. 👍 Zer
😒 Подборка каналов по информационной безопасности Проверенные каналы по безопасности, которые реально помогают расти. 👍 ZeroDay — Уроки, эксплуатация уязвимостей с нуля 👍 Белый Хакер — Свежие новости из мира ИБ 😎 Бункер Хакера — Статьи, книги, шпаргалки и хакинг 👨‍💻 Серверная Админа — Настройка и уроки по компьютерным сетям 📂 Подписывайся

📦 Контекстные менеджеры: от `open` до своих классов (и почему `with` — это не магия) Вы каждый день пишете with open('file.txt') as f, но задумывались ли вы, как это работает? Контекстные менеджеры — это не встроенная магия, а обычный протокол с двумя методами: __enter__ и __exit__. Их можно написать для любого ресурса: файлы, соединения с БД, блокировки, временные изменения настроек. Разбираемся, как это устроено и когда писать свой менеджер. 🧱 Что делает `with` под капотом Когда вы пишете:
with open('file.txt', 'r') as f:
    data = f.read()
Python делает следующее: 1. Вызывает open('file.txt', 'r') — получает объект, у которого есть методы __enter__ и __exit__. 2. Вызывает __enter__() — его результат присваивается переменной f. 3. Выполняет тело блока (data = f.read()). 4. Даже если в блоке произошла ошибка, вызывает __exit__() для гарантированного закрытия ресурса. Самый простой контекстный менеджер:
class ManagedFile:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()
        # Если вернуть True, исключение будет подавлено

with ManagedFile('hello.txt', 'w') as f:
    f.write('Hello, world!')
🧪 `__exit__` и обработка исключений Метод __exit__ получает три аргумента с информацией об исключении (если оно было). Если метод возвращает True, исключение не пробрасывается дальше — его как бы «проглотили». Это полезно для подавления ожидаемых ошибок.
class SuppressError:
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is ValueError:
            print(f"Подавили ошибку: {exc_val}")
            return True  # исключение не выйдет наружу

with SuppressError():
    raise ValueError("Ой, что-то пошло не так")
print("Программа продолжается")
Программистика || #Статья

🕷 Crawl4AI — это открытый веб-краулер и парсер, который преобразует любые сайты в чистый Markdown и готовые для LLM данные.
🕷 Crawl4AI — это открытый веб-краулер и парсер, который преобразует любые сайты в чистый Markdown и готовые для LLM данные. Он отлично подходит для создания корпоративных баз знаний, RAG-систем и AI-пайплайнов, автоматически обрабатывая динамический контент через Playwright и интегрируясь с основными моделями.
🐱 Ссылка на GitHub Программистика || #Репозиторий

🧠 Отгадка: что выведет этот код?
funcs = []
for i in range(3):
    funcs.append(lambda: i)
print([f() for f in funcs])
✅ Правильный ответ: 2. `[2, 2, 2]` 📖 Почему так происходит? Это классическая ловушка с поздним связыванием (late binding) в Python. Внутри цикла создаются три лямбда-функции, которые не запоминают текущее значение i, а захватывают ссылку на переменную `i` из внешней области видимости (замыкание). К моменту вызова этих функций (после завершения цикла) переменная i уже равна 2. Поэтому все три функции возвращают 2.
# Что здесь происходит:
# 1. Цикл for i in range(3) меняет i от 0 до 2.
# 2. На каждой итерации создаётся лямбда lambda: i, которая "видит" текущее i, но не копирует его значение.
# 3. После выхода из цикла i = 2.
# 4. Когда мы вызываем f() для каждой функции, все они обращаются к этой одной переменной i и получают 2.
Как исправить? Нужно зафиксировать текущее значение i с помощью аргумента по умолчанию:
funcs = [lambda i=i: i for i in range(3)]
print([f() for f in funcs])  # [0, 1, 2]
В этом варианте i=i создаёт локальную переменную внутри лямбды со значением, которое было на момент создания. Ставьте 🔥, если было полезно! Программистика || #quiz