Программистика
关闭频道
Лучший канал про python Ссылка для друга: https://t.me/+Ai6ughKtf5g2ZmFi Купить рекламу: https://telega.in/c/+Ai6ughKtf5g2ZmFi Админ: @JeyRahol По рекламе: @ReivuManager
显示更多5 579
订阅者
-524 小时
-437 天
-10430 天
帖子存档
5 579
Python для геймеров: программирование на игровых примерах
Для кого этот курс:
Для новичков, которые хотят изучить программирование с нуля. Для школьников и студентов, мечтающих создавать свои игры. Для тех, кто хочет изучать Python без зубрёжки. Для всех, кто хочет попрактиковаться в решении интересных задач!!!!!!!!
🌐 СсылкаПрограммистика || #Course
5 579
Python для геймеров: программирование на игровых примерах
Для кого этот курс
Для новичков, которые хотят изучить программирование с нуля. Для школьников и студентов, мечтающих создавать свои игры. Для тех, кто хочет изучать Python без зубрёжки. Для всех, кто хочет попрактиковаться в решении интересных задач!
5 579
Здравствуйте, папищики!
Наверное, уже многие заметили, что телеграм в РФ начали замедлять.
Поэтому мы сделали, вой впн сервис, который помогает обойти все блокировки
Заходите: @PocketVPNtg_bot
5 дней бесплатно
5 579
🚀 Typer: Создавай CLI-приложения как бог (и забудь про argparse)
Устал писать сотни строк с
argparse, мучиться с позиционными аргументами и флагами? Каждый раз одно и то же: add_argument, проверка типов, помощь пользователю. Пора автоматизировать эту рутину.
Typer — это библиотека для создания CLI-приложений, которая использует аннотации типов Python. Она построена поверх click, но работает в разы проще: ты просто пишешь функции, а Typer сам превращает их в команды.
❌ Было (муки с argparse):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("name", help="Имя пользователя")
parser.add_argument("--age", type=int, help="Возраст")
parser.add_argument("--admin", action="store_true", help="Админ?")
args = parser.parse_args()
print(f"Привет, {args.name}")
if args.age:
print(f"Тебе {args.age} лет")
if args.admin:
print("Ты админ!")
✔️ Стало (элегантный Typer):
import typer
app = typer.Typer()
@app.command()
def greet(name: str, age: int = None, admin: bool = False):
"""Приветствие пользователя"""
print(f"Привет, {name}")
if age:
print(f"Тебе {age} лет")
if admin:
print("Ты админ!")
if __name__ == "__main__":
app()
Запуск:
python script.py Гвидо --age 65 --admin
# Автоматически получаешь help: python script.py --help
➕ Почему Typer — это любовь:
🟢 Минимум кода: Аннотации типов = валидация, подсказки, документация.
🟢 Авто‑help: --help генерируется из докстрингов и типов.
🟢 Поддержка сложных типов: Enum, Path, datetime, вложенные команды.
🟢 Цветной вывод: Красивые ошибки и подсказки прямо из коробки.
➖ Особенности:
➖ Ещё одна зависимость (но лёгкая).
➖ Для совсем простых скриптов может быть избыточен.
🧪 Продвинутый пример:
import typer
from enum import Enum
class Color(str, Enum):
red = "red"
green = "green"
blue = "blue"
app = typer.Typer()
@app.command()
def paint(color: Color = Color.blue,
size: float = typer.Option(1.0, help="Размер кисти"),
background: bool = False):
"""Рисуем фигуру"""
typer.echo(f"🎨 Рисую цветом {color.value}, размер {size}")
if background:
typer.echo(" с фоном")
@app.command()
def clean():
"""Очистить холст"""
typer.echo("🧹 Холст очищен")
if __name__ == "__main__":
app()
Установка:
pip install typer
# Для цветного вывода и прогресс-баров: pip install "typer[all]"
🐱 Ссылка на репозиторий
Программистика|| #Library5 579
📸 Image Downloader: Скрипт для массового скачивания картинок с любой страницы
Нашёл классную подборку обоев или мемов? Хочешь сохранить все картинки с сайта, но не кликать по каждой правой кнопкой мыши? Этот скрипт сделает всё за тебя: найдёт все изображения на странице и скачает их в отдельную папку.
👉 Скрипт `image_downloader.py`:
#!/usr/bin/env python3
"""
Скрипт для скачивания всех картинок с веб-страницы.
Использование: python image_downloader.py https://example.com
"""
import os
import sys
import requests
from urllib.parse import urljoin, urlparse
from bs4 import BeautifulSoup
from pathlib import Path
def download_images(url, folder='downloaded_images'):
# Создаём папку для сохранения
Path(folder).mkdir(exist_ok=True)
# Загружаем страницу
headers = {'User-Agent': 'Mozilla/5.0'}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
except Exception as e:
print(f"❌ Ошибка загрузки страницы: {e}")
return
soup = BeautifulSoup(response.text, 'html.parser')
# Находим все теги img
img_tags = soup.find_all('img')
print(f"🔍 Найдено изображений: {len(img_tags)}")
# Фильтруем и скачиваем
downloaded = 0
for img in img_tags:
img_url = img.get('src')
if not img_url:
continue
# Превращаем относительный URL в абсолютный
img_url = urljoin(url, img_url)
# Пропускаем data: и другие не-http схемы
if not img_url.startswith(('http://', 'https://')):
continue
# Получаем имя файла
parsed = urlparse(img_url)
filename = os.path.basename(parsed.path)
if not filename or '.' not in filename:
filename = f"image_{downloaded}.jpg"
# Защита от дурака: убираем query-параметры
filename = filename.split('?')[0]
save_path = Path(folder) / filename
# Скачиваем
try:
img_data = requests.get(img_url, headers=headers, timeout=10)
img_data.raise_for_status()
with open(save_path, 'wb') as f:
f.write(img_data.content)
print(f"✅ {filename}")
downloaded += 1
except Exception as e:
print(f"❌ Не удалось скачать {img_url}: {e}")
print(f"\n📊 Готово! Скачано {downloaded} изображений в папку {folder}")
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Использование: python image_downloader.py <URL>")
sys.exit(1)
url = sys.argv[1]
download_images(url)
🛠 Установка зависимостей:
pip install requests beautifulsoup4
🚀 Запуск:
python image_downloader.py https://example.com/gallery
➕ Фишки скрипта:
🟢 Автоматически создаёт папку downloaded_images
🟢 Превращает относительные ссылки в абсолютные
🟢 Пропускает data:URI и другие некорректные схемы
🟢 Обрабатывает ошибки при скачивании
🟢 Игнорирует URL с параметрами (обрезает ?...)
💡 Что можно улучшить:
🟢 Добавить поддержку srcset для выбора лучшего качества
🟢 Фильтровать по минимальному размеру
🟢 Сохранять исходную структуру подпапок
🟢 Распараллелить скачивание (threading)
Программистика || #scripts5 579
👩💻 Я заменил Python на PyPy и получил +400% скорости — не меняя код!
🎥 ПервоисточникПрограммистика|| #video
5 579
СРОЧНЫЙ ИНСАЙД❗️
Российский кодер в третий раз обошёл защиту ChatGPTАйтишник за пару часов нашёл промт, который обходит фильтры, а OpenAI спешно закрывает дыру. 😡 На канале «Мама, я в IT!» сливает свежие промты: –> Бесплатный доступ к Veo 3 и видео-генераторам –> 18+ фото без цензуры в Midjourney –> Разблокировка Gemini, GPT и Perplexity за 0₽ Сохрани, пока не заблокировали: https://t.me/+WHOPn_pf4JVlNWYy
5 579
🔧 Pre-commit: Автоматическая проверка кода перед каждым коммитом
Забываешь запускать линтеры перед коммитом? Получаешь замечания на CI за кривое форматирование? Тратишь время на правки в пул-реквестах из-за опечаток? Пора автоматизировать контроль качества до того, как код попадёт в репозиторий.
Pre-commit — это фреймворк для управления git-хуками. Он запускает указанные проверки перед каждым коммитом и не даёт сделать коммит, если что-то пошло не так.
❌ Было (ручная боль):
# Делаешь коммит, пушишь, создаёшь PR...
git commit -m "fix: баг"
git push origin feature
# А через 10 минут CI падает с ошибкой:
# "black: файл не отформатирован"
# "ruff: неиспользуемый импорт"
# "mypy: несоответствие типов"
# Приходится править, делать новый коммит, ждать снова...
✔️ Стало (автоматический контроль):
# Пытаешься сделать коммит
git commit -m "fix: баг"
# Pre-commit автоматически запускает:
# - black → форматирует код
# - ruff → проверяет ошибки
# - mypy → проверяет типы
# Если что-то не так — коммит отклоняется с описанием проблемы.
# Если всё ок — коммит проходит.
# В CI теперь только критичные проверки, код уже чистый.
📌 Как это работает:
Pre-commit использует конфигурационный файл .pre-commit-config.yaml, в котором перечисляются все хуки (проверки). Хуки запускаются в изолированном окружении, поэтому не засоряют ваш проект.
Пример конфига для Python-проекта:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.11
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies: [types-requests]
➕ Преимущества, которые оценит каждый:
🟢 Автоматизация: Забудь о ручном запуске линтеров — они сами срабатывают при коммите
🟢 Скорость: Хуки кэшируют окружения, повторные запуски быстрые
🟢 Гибкость: Можно подключать любые инструменты (black, ruff, mypy, isort, даже свои скрипты)
🟢 Командная работа: Единый стандарт для всех разработчиков — конфликт "а у меня работает" исчезает
🟢 Интеграция с CI: В CI можно запускать только pre-commit run --all-files, что гарантирует идентичность проверок
➖ Особенности:
🔴 Нужно учить новый инструмент: Поначалу конфиг кажется сложным
🔴 Может тормозить первый запуск: Хуки скачиваются и устанавливаются
🔴 Не все хуки идеальны: Иногда приходится подбирать версии
🛠 Установка и первый запуск:
# Установка через pip
pip install pre-commit
# Или через brew (macOS)
brew install pre-commit
# В корне проекта создаём конфиг (пример выше)
# Устанавливаем хуки в git
pre-commit install
# Теперь хуки будут запускаться при каждом git commit
Проверить все файлы вручную:
pre-commit run --all-files
Один раз настроил — и забыл. А код сам становится лучше.
🐱 Ссылка на репозиторий
Программистика ||#Library5 579
⚡️Слита База из 1000+ топовых курсов и материалов для айтишников
Отсортировали их для вашего удобства и выложили в телеграм-каналы по категориям:
🖥 Python — 1558+ материалов
👩💻 Frontend — 1241+ материалов
👩💻 Backend — 1095+ материалов
🤖 Нейросети – 855+ материалов
⚙️ Программы — 978+ материалов
📚 Книги по IT — 779+ материалов
Всё лучшее про IT бесплатно — уже на Базе 🚀
5 579
😒 Подборка каналов по информационной безопасности
Проверенные каналы по безопасности, которые реально помогают расти.
👍 ZeroDay — Уроки, эксплуатация уязвимостей с нуля
👍 Белый Хакер — Свежие новости из мира ИБ
😎 Бункер Хакера — Статьи, книги, шпаргалки и хакинг
👨💻 Серверная Админа — Настройка и уроки по компьютерным сетям
📂 Подписывайся
5 579
👩💻 Планировщик задач внутри Python-процесса: пишем персонального ассистента
В повседневной рутине разработчика легко забыть о дейли-митинге, вовремя запустить бэкап или просто переключить контекст. Полагаться на память ненадёжно, а сторонние планировщики часто избыточны или требуют постоянного переключения между окнами.
Гораздо элегантнее, когда напоминалки и фоновые задачи живут прямо в коде. В этом туториале автор показывает, как собрать легковесный фоновый сервис на чистом Python. Разбираем связку
schedule (для гибкого расписания) и plyer (для нативных системных уведомлений) — и всё это без висящего окна терминала.
🧱 Почему не `time.sleep()`?
Наивный подход с бесконечным циклом и sleep() имеет два фатальных недостатка:
🟢 Блокировка потока — пока программа спит, она не реагирует ни на что.
🟢 Временной дрейф — время выполнения кода плюсуется к паузе, и график уплывает.
Библиотека schedule решает это элегантно, предоставляя чистый декларативный синтаксис и event loop без блокировки.
🛠 Базовый скелет планировщика
import time
import schedule
from plyer import notification
def send_notification(title, message):
"""Универсальная функция для нативных уведомлений"""
try:
notification.notify(
title=title,
message=message,
app_name='Task Manager',
timeout=10
)
except Exception as e:
print(f"Ошибка уведомления: {e}")
# Задачи
def daily_standup():
send_notification("Daily Meeting", "Подключайся к Zoom!")
def check_services():
send_notification("System Monitor", "Локальные сервисы ОК")
print("[LOG] Проверка выполнена") # Для отладки
# Расписание
schedule.every().day.at("10:00").do(daily_standup)
schedule.every(2).hours.do(check_services)
schedule.every().friday.at("18:00").do(
send_notification,
title="Конец недели",
message="Закоммить изменения и хороших выходных!"
)
# Event loop
if __name__ == "__main__":
send_notification("Task Manager", "Планировщик запущен")
while True:
schedule.run_pending()
time.sleep(1) # Разгрузка CPU, а не интервал задач
📌 Важные нюансы из статьи:
1. Plyer — кроссплатформенная обёртка для системных уведомлений (Windows, Linux, macOS). На Linux может потребоваться sudo apt-get install libnotify-bin.
2. Обработка ошибок внутри send_notification критична: если уведомление упадёт, скрипт не должен схлопнуться.
3. Запуск в фоне:
- На Windows переименуйте .py → .pyw — тогда скрипт выполнится через pythonw.exe без окна консоли.
- Для автозагрузки создайте ярлык на pythonw.exe из виртуального окружения с указанием пути к вашему .pyw.
4. Логирование в stdout (print) оставлено специально — при отладке видно, что процесс жив, а в продакшене (в режиме .pyw) эти выводы просто игнорируются.
👉 Читать полный туториал на Хабре
Программистика ||#article5 579
⚡️ Айтишник из «VISION» скупил курсы айти школ и выложил гигабайты материалов к себе
Каждый найдет что-то по душе:
1202 ГБ — Python
1811 ГБ — Frontend
1100 ГБ — C / C++ / C#
804 ГБ — Java
411 ГБ — SQL & БД
309 ГБ — DevOps
998 ГБ — ИБ & Хакинг
773 ГБ — Kotlin / Swift
189 ГБ — PHP
201 ГБ — GoLang
170 ГБ — Rust
167 ГБ — QA / Тестирование
310 ГБ — 1C + Лицензии
495 ГБ — Машинное обучение
704 ГБ — Аналитика Данных
991 ГБ — Дизайн
Материалы в закрепе, постоянно пополняются👆🏻
5 579
👩💻
`__slots__` 🆚 `__dict__`: Когда экономия памяти оправдана, а когда — лишняя сложность
Каждый экземпляр класса в Python носит с собой __dict__ — тяжёлый рюкзак для хранения атрибутов. Удобно: можно добавлять поля на лету. Но если у вас миллион объектов, этот рюкзак превращается в контейнер с цементом. __slots__ говорит Python: «Не выделяй словарь, я сам знаю свои атрибуты». Разбираемся, где это реально нужно, а где — преждевременная оптимизация.
🧱 Когда `__slots__` — это хорошо (и значительно ускоряет код):
1️⃣. Миллионы однотипных объектов (датасеты, игровые сущности, логи):
class Point:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
# Без __slots__ каждый Point занимает ~56 байт + __dict__ (56+56=112)
# С __slots__ ~48 байт на объект — экономия 2+ раз!
2️⃣. Иммутабельные структуры, где не нужна динамика:
class Color:
__slots__ = ('r', 'g', 'b')
def __init__(self, r, g, b):
self.r = r
self.g = g
self.b = b
def __repr__(self):
return f"Color({self.r},{self.g},{self.b})"
3️⃣. Классы-обёртки для C-расширений / API:
class DeviceHandle:
__slots__ = ('_handle', '_closed')
# Запрещаем добавлять левые атрибуты, которые сломают низкоуровневый вызов
📊 Замер памяти (убедись сам):
import sys
from pympler import asizeof
class WithDict:
def __init__(self, x, y):
self.x = x
self.y = y
class WithSlots:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
d_obj = WithDict(1, 2)
s_obj = WithSlots(1, 2)
print(sys.getsizeof(d_obj)) # 56 (сам объект) + вес __dict__ (~56) ≈ 112
print(sys.getsizeof(s_obj)) # 48 (нет __dict__)
# Более честный замер с pympler:
print(asizeof.asizeof(d_obj)) # ~184 байта (со всеми накладными)
print(asizeof.asizeof(s_obj)) # ~80 байт
🧱 Когда `__slots__` — это ПЛОХО (антипаттерны и подводные камни):
1. Динамическое добавление атрибутов (сломается):
class User:
__slots__ = ('name', 'email')
user = User()
user.age = 25 # ❌ AttributeError: 'User' object has no attribute 'age'
2. Наследование и множественное наследование — требует внимания:
class Base:
__slots__ = ('id',)
class Child(Base):
# Если не указать __slots__, у Child появится __dict__!
pass
child = Child()
child.id = 1
child.extra = 2 # ✅ Работает! __dict__ создан неявно
# Чтобы сохранить экономию, надо явно повторить:
class Child(Base):
__slots__ = () # или добавить свои поля
3. Слабые ссылки (weakref) перестают работать по умолчанию:
class Node:
__slots__ = ('value',)
node = Node()
ref = weakref.ref(node) # ❌ TypeError: cannot create weak reference to 'Node' object
# Фикс: добавить '__weakref__' в __slots__
class Node:
__slots__ = ('value', '__weakref__')
4. Код становится менее читаемым для новичков:
Команда может не понять, почему нельзя добавить атрибут «на лету» в тестах или прототипах.
🧪 Когда `__slots__` НЕ НУЖНЫ (и даже вредны):
1. Прототипирование и быстрое изменение кода:
# На этапе экспериментов __dict__ — друг, __slots__ — враг
2. Классы с несколькими экземплярами (десятки, сотни):
Экономия 100 байт × 100 = 10 КБ — незаметно на фоне остальной памяти.
3. Библиотеки для широкого использования:
Вы не знаете, как пользователь захочет расширить ваш класс. __slots__ может заблокировать monkey-patching и тестирование.
4. Если нужна аннотация типов + dataclass:
Современные dataclass со slots=True (Python 3.10+) — элегантный компромисс:
from dataclasses import dataclass
@dataclass(slots=True)
class Point:
x: float
y: float
p = Point(1, 2)
p.z = 3 # ❌ Ошибка, как и с ручными __slots__
🔗 Подробнее в документации
Программистика ||#article5 579
В IT хватает тех, кто пересказывает чужие статьи.
Но есть те, кто пишет изнутри системы.
NeuroNinja 🥷🏻 - авторский канал инженера СберТехнологий, который показывает, что происходит по ту сторону интерфейса.
В канале вы найдете:
🟢 Разборы реальных кейсов из практики
🟢 Гайды по нейросетям без воды
🟢 Полезные инструменты и лайфхаки
🟢 Честные мысли о трендах в IT
Живые обсуждения для тех, кто не просто читает про ИИ, а строит его будущее🚀.
👉 Подписаться: https://t.me/+p7moTkYaAQo1MTEy
5 579
🔐 Шифруем данные в Python: просто о сложном
Хранить пароли, ключи, приватные переписки в открытом виде - это дебильно. Давайте научимся защищать данные.
Так делать нельзя (шифрование своими руками)
def my_encrypt(text, key):
result = ""
for char in text:
result += chr(ord(char) ^ key)
return result
Проблема:
Самопальное XOR-шифрование - это хрень. Оно легко ломается, нет аутентификации, соли, криптостойкого генератора случайных чисел.
✔️ Правильно (используем проверенные библиотеки)
from cryptography.fernet import Fernet
# Генерируем ключ
key = Fernet.generate_key()
cipher = Fernet(key)
# Шифруем
text = b"My secret message"
encrypted_text = cipher.encrypt(text)
print(encrypted_text) # b'gAAAAABn...'
# Расшифровываем
decrypted_text = cipher.decrypt(encrypted_text)
print(decrypted_text) # b'My secret message'
Как это работает:
Fernet использует симметричное шифрование (AES) и гарантирует целостность данных (HMAC). Ключ безопасно генерируется.
🔐Шифруем пароли правильно (хэширование)
import bcrypt
password = b"super_secure_pass"
# Создаём соль и хэш
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(password, salt)
print(hashed) # b'$2b$12$...'
# Проверяем пароль
if bcrypt.checkpw(password, hashed):
print("Password matches!")
Хэширование - односторонняя улица. Пароль нельзя расшифровать, можно только сведить хэш.
Асимметричное шифрование (публичный/приватный ключ)
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
# Генерация пары ключей
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# Шифруем публичным ключом
message = b"Confidential"
ciphertext = public_key.encrypt(
message,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# Расшифровываем приватным
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print(plaintext) # b'Confidential'
Важно:
Не изобретайте велосипед. Используйте cryptography, bcrypt, pycryptodome. Храните ключи в секрете и используйте надёжные алгоритмы.
Программистика ||#article
现已上线!2025 年 Telegram 研究 — 年度关键洞察 
