Forwarded from Python для начинающих
Python — язык, который поощряет чистоту, читаемость и элегантность. И одно из самых мощных проявлений этих качеств — конструкции контекстного менеджмента. Возможно, ты уже встречал волшебное слово with, но не совсем понимал, что именно происходит под капотом. Давай разберёмся.
Представим себе файл. Мы его открываем, читаем, а потом… забываем закрыть. Вроде бы ничего страшного — но если таких забытых файлов десятки, появляются утечки ресурсов. Контекстные менеджеры помогают гарантировать, что нужные действия будут выполнены автоматически, даже если в процессе произойдёт ошибка.
Базовый пример:
with open('data.txt', 'r') as file:
content = file.read()
После выхода из блока with Python сам вызовет file.close(). Удобно и безопасно.
Но фокус в том, что можно писать свои контекстные менеджеры! Чтобы понять, как это работает, вспомним о двух магических методах:
- enter()
- exit()
Создадим простой таймер:
import time
class Timer:
def enter(self):
self.start = time.time()
return self
def exit(self, exctype, excval, exctb):
self.end = time.time()
print(f'Time elapsed: {self.end - self.start:.4f} seconds')
Теперь используем:
with Timer():
total = sum(i**2 for i in range(1000000))
Контекст открылся, засеклось время. После выхода — замер завершился, результат выведен.
Но писать собственные классы с enter и exit — не всегда удобно. Тут приходит модуль contextlib. Он предлагает простой способ создавать менеджеры контекста из функций.
Пример с contextlib.contextmanager:
from contextlib import contextmanager
@contextmanager
def changedirectory(path):
import os
prevdir = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(prevdir)
Вот такой элегантный способ временно сменить директорию:
with changedirectory('/tmp'):
print('We are here:', os.getcwd())
После выхода — возвращаемся туда, откуда пришли. Даже если внутри блока произойдёт исключение.
А теперь чуть более продвинутый трюк: подавление ошибок. Модуль contextlib помогает снова:
from contextlib import suppress
with suppress(ZeroDivisionError):
print(1 / 0) # Ошибка будет проигнорирована
Очень полезно, когда есть неважные операции, которые могут не сработать, и их не хочется оборачивать в try/except.
И наконец: если ты работаешь с ресурсами — файлами, соединениями, блокировками — знай, что многие библиотеки уже поддерживают контекстные менеджеры. Например, threading.Lock:
import threading
lock = threading.Lock()
with lock:
# безопасный доступ к ресурсу
dosomething()
Безопасность, лаконичность, надёжность — вот за что мы любим with. Он делает код чище и устойчивее к ошибкам. А знание, как писать свои менеджеры контекста, открывает путь к по-настоящему выразительному Python-коду.
Представим себе файл. Мы его открываем, читаем, а потом… забываем закрыть. Вроде бы ничего страшного — но если таких забытых файлов десятки, появляются утечки ресурсов. Контекстные менеджеры помогают гарантировать, что нужные действия будут выполнены автоматически, даже если в процессе произойдёт ошибка.
Базовый пример:
with open('data.txt', 'r') as file:
content = file.read()
После выхода из блока with Python сам вызовет file.close(). Удобно и безопасно.
Но фокус в том, что можно писать свои контекстные менеджеры! Чтобы понять, как это работает, вспомним о двух магических методах:
- enter()
- exit()
Создадим простой таймер:
import time
class Timer:
def enter(self):
self.start = time.time()
return self
def exit(self, exctype, excval, exctb):
self.end = time.time()
print(f'Time elapsed: {self.end - self.start:.4f} seconds')
Теперь используем:
with Timer():
total = sum(i**2 for i in range(1000000))
Контекст открылся, засеклось время. После выхода — замер завершился, результат выведен.
Но писать собственные классы с enter и exit — не всегда удобно. Тут приходит модуль contextlib. Он предлагает простой способ создавать менеджеры контекста из функций.
Пример с contextlib.contextmanager:
from contextlib import contextmanager
@contextmanager
def changedirectory(path):
import os
prevdir = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(prevdir)
Вот такой элегантный способ временно сменить директорию:
with changedirectory('/tmp'):
print('We are here:', os.getcwd())
После выхода — возвращаемся туда, откуда пришли. Даже если внутри блока произойдёт исключение.
А теперь чуть более продвинутый трюк: подавление ошибок. Модуль contextlib помогает снова:
from contextlib import suppress
with suppress(ZeroDivisionError):
print(1 / 0) # Ошибка будет проигнорирована
Очень полезно, когда есть неважные операции, которые могут не сработать, и их не хочется оборачивать в try/except.
И наконец: если ты работаешь с ресурсами — файлами, соединениями, блокировками — знай, что многие библиотеки уже поддерживают контекстные менеджеры. Например, threading.Lock:
import threading
lock = threading.Lock()
with lock:
# безопасный доступ к ресурсу
dosomething()
Безопасность, лаконичность, надёжность — вот за что мы любим with. Он делает код чище и устойчивее к ошибкам. А знание, как писать свои менеджеры контекста, открывает путь к по-настоящему выразительному Python-коду.
Forwarded from Python для начинающих
Как разрабатывать VPN-приложения на основе Python
VPN — это не просто модный термин из мира информационной безопасности. Это реальный рабочий механизм, который позволяет шифровать трафик, обходить блокировки и защищать соединение в публичных сетях. Интересно, что с помощью Python можно построить простое VPN-приложение буквально с нуля — и это совсем не магия, а знание и немного кода.
Основная идея VPN — создание защищённого туннеля между клиентом и сервером, внутри которого весь сетевой трафик проходит в зашифрованном виде. В Python мы можем реализовать подобную функциональность, используя стандартные библиотеки socket и ssl, а также сторонние — такие как pycryptodome для дополнительного шифрования.
Начнем с основы — создадим шифрованное TCP-соединение. Допустим, у нас есть клиент и сервер, которые общаются по TLS:
Пример серверной части:
Пример клиента:
Это уже зашифрованное соединение! На более высоком уровне мы можем добавить маршрут через этот туннель, используя iptables на Linux или прокси-настройки на других системах. Но стоит заметить: этот способ безопасен только внутри локального проекта, для полноценного VPN нужны туннелирование на уровне IP (например, средствами TUN/TAP).
Для работы с такими интерфейсами в Python можно использовать модуль pyroute2 (работает под Linux). Вот пример настройки туннеля:
Создав интерфейс, можно направлять трафик через него и обрабатывать поступающие IP-пакеты с помощью raw-сокетов. Например, чтобы захватить пакеты и переслать через защищённый TCP, мы можем использовать socket.socket с типом
Дополнительно, для шифрования полезной нагрузки можно подключить AES:
Таким образом, VPN-приложение на Python может включать в себя:
- шифрованный TCP-туннель (через ssl);
- работу с сетевыми интерфейсами (через pyroute2);
- обработку и маршрутизацию IP-пакетов (через raw-сокеты и TUN);
- шифрование всех данных (через pycryptodome).
Конечно, это всё требует продуманной архитектуры, обработки ошибок и аутентификации. Настоящий VPN — больше, чем просто код: это защита всего маршрута данных. Но начать проще, чем кажется. Python даёт достаточный инструментарий, чтобы понимать, как всё устроено на самом деле.
Звучит как вызов? Отлично. Потому что любой хороший девелопер любит разбираться в инфраструктуре, не только писать логику веб-приложений. VPN на Python — это именно тот случай, когда ты понимаешь, как работает интернет изнутри.
VPN — это не просто модный термин из мира информационной безопасности. Это реальный рабочий механизм, который позволяет шифровать трафик, обходить блокировки и защищать соединение в публичных сетях. Интересно, что с помощью Python можно построить простое VPN-приложение буквально с нуля — и это совсем не магия, а знание и немного кода.
Основная идея VPN — создание защищённого туннеля между клиентом и сервером, внутри которого весь сетевой трафик проходит в зашифрованном виде. В Python мы можем реализовать подобную функциональность, используя стандартные библиотеки socket и ssl, а также сторонние — такие как pycryptodome для дополнительного шифрования.
Начнем с основы — создадим шифрованное TCP-соединение. Допустим, у нас есть клиент и сервер, которые общаются по TLS:
Пример серверной части:
import socket
import ssl
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile='cert.pem', keyfile='key.pem')
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
bind_socket.bind(('0.0.0.0', 9000))
bind_socket.listen(5)
while True:
new_socket, addr = bind_socket.accept()
conn = context.wrap_socket(new_socket, server_side=True)
data = conn.recv(1024)
print(f"Received: {data}")
conn.sendall(b'Encrypted Hello from VPN Server!')
conn.close()
Пример клиента:
import socket
import ssl
context = ssl.create_default_context()
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname='localhost')
conn.connect(('localhost', 9000))
conn.sendall(b'Hello from Client')
print(f"Server says: {conn.recv(1024)}")
conn.close()
Это уже зашифрованное соединение! На более высоком уровне мы можем добавить маршрут через этот туннель, используя iptables на Linux или прокси-настройки на других системах. Но стоит заметить: этот способ безопасен только внутри локального проекта, для полноценного VPN нужны туннелирование на уровне IP (например, средствами TUN/TAP).
Для работы с такими интерфейсами в Python можно использовать модуль pyroute2 (работает под Linux). Вот пример настройки туннеля:
from pyroute2 import IPRoute
ip = IPRoute()
idx = ip.link_create(ifname='tun0', kind='tun')
ip.addr('add', index=idx, address='10.0.0.1', prefixlen=24)
ip.link('set', index=idx, state='up')
Создав интерфейс, можно направлять трафик через него и обрабатывать поступающие IP-пакеты с помощью raw-сокетов. Например, чтобы захватить пакеты и переслать через защищённый TCP, мы можем использовать socket.socket с типом
socket.SOCK_RAW
.Дополнительно, для шифрования полезной нагрузки можно подключить AES:
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
key = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_EAX)
data = b'Secret payload'
ciphertext, tag = cipher.encrypt_and_digest(data)
print(ciphertext)
Таким образом, VPN-приложение на Python может включать в себя:
- шифрованный TCP-туннель (через ssl);
- работу с сетевыми интерфейсами (через pyroute2);
- обработку и маршрутизацию IP-пакетов (через raw-сокеты и TUN);
- шифрование всех данных (через pycryptodome).
Конечно, это всё требует продуманной архитектуры, обработки ошибок и аутентификации. Настоящий VPN — больше, чем просто код: это защита всего маршрута данных. Но начать проще, чем кажется. Python даёт достаточный инструментарий, чтобы понимать, как всё устроено на самом деле.
Звучит как вызов? Отлично. Потому что любой хороший девелопер любит разбираться в инфраструктуре, не только писать логику веб-приложений. VPN на Python — это именно тот случай, когда ты понимаешь, как работает интернет изнутри.
Forwarded from Дмитрий Обучение Python
🚀 Друзья, если вы только начинаете осваивать Python или уже перешли к фреймворкам и сложным бибилотекам,
вам помогут авторские материалы многолетнего разработчика и преподавателя Python Дмитрия Читалова.
Уже размещены:
✅Основы Python
✅Алгоритмы и структуры данных
✅Паттерны проектирования на Python
❗️Сейчас еженедельно выкладываются новые материалы, разбираются вопросы с собеседований
Подписаться можно здесь.
вам помогут авторские материалы многолетнего разработчика и преподавателя Python Дмитрия Читалова.
Уже размещены:
✅Основы Python
✅Алгоритмы и структуры данных
✅Паттерны проектирования на Python
❗️Сейчас еженедельно выкладываются новые материалы, разбираются вопросы с собеседований
Подписаться можно здесь.
Forwarded from Python для начинающих
На этой неделе я решил затронуть тему, которая волнует многих начинающих разработчиков: создание собственной системы управления контентом (CMS) на Django. Часто при изучении фреймворка мы учимся делать блоги, страницы и формы. Но что, если попробовать сделать нечто большее — свою CMS? Управляемый контент, возможность редактирования без кода, гибкое расширение — звучит вдохновляюще? Тогда поехали.
С чего начать? Django уже практически готов для построения CMS. У него есть админка, модели, формы, авторизация, шаблоны — всё, что нужно новичку для уверенного старта.
Создадим базу: установим Django и создадим проект.
В core создаём первую модель — ContentPage:
Подключим её в админку:
Теперь, зайдя в admin-панель, можно добавлять страницы с уникальным slug и текстом. Но наша цель — чтобы эти страницы отдавались по соответствующему URL, не создавая вручную views под каждую.
Создаём "умный" view:
И URL-шаблон:
Всё. Теперь любой контент с определённым slug — например, "about" — будет доступен по адресу /about/. Но что, если хотим, чтобы администратор мог задавать не только текст, но и типы блоков? Представим блок "цитата", "изображение + текст", "галерея".
Решение: отдельные модели блоков.
Теперь страницы можно собирать как конструктор: добавлять разнообразные блоки, управлять их порядком. Через админку пользователь собирает страницу сам, без кода. В шаблоне просто итерируем blocks и отображаем нужный HTML под каждый тип:
Хочется вложений страниц, как у real CMS? Добавим parent-связь в ContentPage и дорисуем древовидную структуру — можно с помощью django-mptt.
Хотим редактор, вместо plain TextField? Подключаем django-ckeditor и получаем визуальную обработку контента.
В этой архитектуре вся мощь CMS оказывается в руках администратора: он создаёт новые страницы, меняет их, комбинирует блоки — без программирования. Мы же, как разработчики, создаём каркас и логику.
Таким образом, используя стандартный инструментарий Django, мы получаем лёгкую, настраиваемую и расширяемую CMS. Не надо ждать "идеальную" CMS от третьих лиц — можно построить свою. Понятную, минималистичную и под конкретные задачи. И это, по моему личному опыту, куда ценнее универсальных монстров.
С чего начать? Django уже практически готов для построения CMS. У него есть админка, модели, формы, авторизация, шаблоны — всё, что нужно новичку для уверенного старта.
Создадим базу: установим Django и создадим проект.
django-admin startproject cms_project
cd cms_project
python manage.py startapp core
В core создаём первую модель — ContentPage:
from django.db import models
class ContentPage(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Подключим её в админку:
from django.contrib import admin
from .models import ContentPage
admin.site.register(ContentPage)
Теперь, зайдя в admin-панель, можно добавлять страницы с уникальным slug и текстом. Но наша цель — чтобы эти страницы отдавались по соответствующему URL, не создавая вручную views под каждую.
Создаём "умный" view:
from django.shortcuts import get_object_or_404, render
from .models import ContentPage
def content_page_view(request, slug):
page = get_object_or_404(ContentPage, slug=slug)
return render(request, 'core/page.html', {'page': page})
И URL-шаблон:
from django.urls import path
from .views import content_page_view
urlpatterns = [
path('<slug:slug>/', content_page_view, name='content_page'),
]
Всё. Теперь любой контент с определённым slug — например, "about" — будет доступен по адресу /about/. Но что, если хотим, чтобы администратор мог задавать не только текст, но и типы блоков? Представим блок "цитата", "изображение + текст", "галерея".
Решение: отдельные модели блоков.
class PageBlock(models.Model):
page = models.ForeignKey(ContentPage, related_name='blocks', on_delete=models.CASCADE)
block_type = models.CharField(max_length=50, choices=[
('text', 'Text'),
('quote', 'Quote'),
('image', 'Image'),
])
content = models.TextField()
order = models.PositiveIntegerField(default=0)
class Meta:
ordering = ['order']
Теперь страницы можно собирать как конструктор: добавлять разнообразные блоки, управлять их порядком. Через админку пользователь собирает страницу сам, без кода. В шаблоне просто итерируем blocks и отображаем нужный HTML под каждый тип:
{% for block in page.blocks.all %}
{% if block.block_type == 'text' %}
<p>{{ block.content }}</p>
{% elif block.block_type == 'quote' %}
<blockquote>{{ block.content }}</blockquote>
{% elif block.block_type == 'image' %}
<img src="{{ block.content }}" alt="Image block">
{% endif %}
{% endfor %}
Хочется вложений страниц, как у real CMS? Добавим parent-связь в ContentPage и дорисуем древовидную структуру — можно с помощью django-mptt.
Хотим редактор, вместо plain TextField? Подключаем django-ckeditor и получаем визуальную обработку контента.
В этой архитектуре вся мощь CMS оказывается в руках администратора: он создаёт новые страницы, меняет их, комбинирует блоки — без программирования. Мы же, как разработчики, создаём каркас и логику.
Таким образом, используя стандартный инструментарий Django, мы получаем лёгкую, настраиваемую и расширяемую CMS. Не надо ждать "идеальную" CMS от третьих лиц — можно построить свою. Понятную, минималистичную и под конкретные задачи. И это, по моему личному опыту, куда ценнее универсальных монстров.
Forwarded from Python для начинающих
Привет, друзья! Сегодня нырнем в мир асинхронности и узнаем, как Python-тюлень превращается в сетевую торпеду благодаря библиотеке asyncio. Если вы когда-либо писали сетевые приложения и сталкивались с болью от блокирующего кода — добро пожаловать в будущее, где одна корутина может сделать больше, чем десять потоков на слабом ноутбуке.
Что же такое asyncio? Это современный подход к асинхронному программированию в Python. Он позволяет запускать несколько задач одновременно без реального многопоточия — за счёт кооперативной многозадачности. Это идеальный выбор для I/O-зависимых задач: работы с сетью, файлами, сокетами и базами данных.
Рассмотрим пример простого TCP-сервера, который обрабатывает клиентские соединения асинхронно:
import asyncio
async def handleclient(reader, writer):
addr = writer.getextrainfo('peername')
print(f"Connected: {addr}")
while True:
data = await reader.readline()
if not data:
break
message = data.decode().strip()
print(f"Received from {addr}: {message}")
response = f"Echo: {message}\n"
writer.write(response.encode())
await writer.drain()
print(f"Disconnected: {addr}")
writer.close()
await writer.waitclosed()
async def main():
server = await asyncio.startserver(handleclient, '127.0.0.1', 8888)
addr = server.sockets0.getsockname()
print(f"Serving on {addr}")
async with server:
await server.serveforever()
asyncio.run(main())
Этот код запускает асинхронный TCP-сервер на порту 8888. При подключении клиента создается новая корутина handleclient. Вместо блокирующих операций чтения/записи мы используем await reader.readline() и await writer.drain(), позволяя другим задачам выполняться между ожиданиями.
Чем это лучше, скажете вы? Ну, во-первых — экономия ресурсов. Вместо того чтобы спаунить потоки и платить за переключение контекста (и риск словить GIL), asyncio даёт нам лёгкие задачи внутри одного потока. Во-вторых — читаемость. Вместо колбэков и адской вложенности в стиле JavaScript времён динозавров, у нас есть async/await — лаконично и выразительно.
Допустим, вы хотите написать клиент, который периодически шлёт сообщения серверу:
async def tcpechoclient():
reader, writer = await asyncio.openconnection('127.0.0.1', 8888)
for i in range(5):
message = f"Hello {i}\n"
writer.write(message.encode())
await writer.drain()
response = await reader.readline()
print(f"Received: {response.decode().strip()}")
await asyncio.sleep(1)
writer.close()
await writer.waitclosed()
asyncio.run(tcpechoclient())
Это уже мини-болталка: клиент отправляет сообщения, сервер эхо-отвечает. Всё асинхронно и без блокировок! А если подключатся десятки клиентов? Никаких проблем — asyncio справится, пока вы не начнете жарить процессор тяжёлыми вычислениями. Тут уже стоит подумать об asyncio + multiprocessing или выносить нагрузку в отдельные сервисы.
А как быть с тайм-аутами, отменой задач и очередями? Тут тоже всё продумано: asyncio предоставляет объекты Future, Task и Queue, которые позволяют строить настоящие архитектуры. И, да, в реальных проектах часто используются такие фреймворки, как aiohttp (асинхронный HTTP-сервер и клиент) или websockets — они расширяют возможности asyncio, сохраняя модели async/await.
asyncio — это мощный инструмент, который делает написание сетевых приложений в Python одновременно простым, эффективным и масштабируемым. Если вы до сих пор пишете blocking-сокеты — самое время пересесть на асинхронный экспресс.
До встречи в следующих постах, где мы разберём, как с помощью aiohttp строить REST API, не теряя скорости даже под нагрузкой.
Что же такое asyncio? Это современный подход к асинхронному программированию в Python. Он позволяет запускать несколько задач одновременно без реального многопоточия — за счёт кооперативной многозадачности. Это идеальный выбор для I/O-зависимых задач: работы с сетью, файлами, сокетами и базами данных.
Рассмотрим пример простого TCP-сервера, который обрабатывает клиентские соединения асинхронно:
import asyncio
async def handleclient(reader, writer):
addr = writer.getextrainfo('peername')
print(f"Connected: {addr}")
while True:
data = await reader.readline()
if not data:
break
message = data.decode().strip()
print(f"Received from {addr}: {message}")
response = f"Echo: {message}\n"
writer.write(response.encode())
await writer.drain()
print(f"Disconnected: {addr}")
writer.close()
await writer.waitclosed()
async def main():
server = await asyncio.startserver(handleclient, '127.0.0.1', 8888)
addr = server.sockets0.getsockname()
print(f"Serving on {addr}")
async with server:
await server.serveforever()
asyncio.run(main())
Этот код запускает асинхронный TCP-сервер на порту 8888. При подключении клиента создается новая корутина handleclient. Вместо блокирующих операций чтения/записи мы используем await reader.readline() и await writer.drain(), позволяя другим задачам выполняться между ожиданиями.
Чем это лучше, скажете вы? Ну, во-первых — экономия ресурсов. Вместо того чтобы спаунить потоки и платить за переключение контекста (и риск словить GIL), asyncio даёт нам лёгкие задачи внутри одного потока. Во-вторых — читаемость. Вместо колбэков и адской вложенности в стиле JavaScript времён динозавров, у нас есть async/await — лаконично и выразительно.
Допустим, вы хотите написать клиент, который периодически шлёт сообщения серверу:
async def tcpechoclient():
reader, writer = await asyncio.openconnection('127.0.0.1', 8888)
for i in range(5):
message = f"Hello {i}\n"
writer.write(message.encode())
await writer.drain()
response = await reader.readline()
print(f"Received: {response.decode().strip()}")
await asyncio.sleep(1)
writer.close()
await writer.waitclosed()
asyncio.run(tcpechoclient())
Это уже мини-болталка: клиент отправляет сообщения, сервер эхо-отвечает. Всё асинхронно и без блокировок! А если подключатся десятки клиентов? Никаких проблем — asyncio справится, пока вы не начнете жарить процессор тяжёлыми вычислениями. Тут уже стоит подумать об asyncio + multiprocessing или выносить нагрузку в отдельные сервисы.
А как быть с тайм-аутами, отменой задач и очередями? Тут тоже всё продумано: asyncio предоставляет объекты Future, Task и Queue, которые позволяют строить настоящие архитектуры. И, да, в реальных проектах часто используются такие фреймворки, как aiohttp (асинхронный HTTP-сервер и клиент) или websockets — они расширяют возможности asyncio, сохраняя модели async/await.
asyncio — это мощный инструмент, который делает написание сетевых приложений в Python одновременно простым, эффективным и масштабируемым. Если вы до сих пор пишете blocking-сокеты — самое время пересесть на асинхронный экспресс.
До встречи в следующих постах, где мы разберём, как с помощью aiohttp строить REST API, не теряя скорости даже под нагрузкой.
Хотите,чтобы ваши цели исполнялись, а жизнь шла по выбранному вами пути?
Подписывайтесь:
https://t.me/consciousreal
Подписывайтесь:
https://t.me/consciousreal
Telegram
Осознанная реальность
Намерение, осознанность, саморазвитие
Forwarded from Python для начинающих
Вы когда-нибудь оказались в ситуации, когда нужно сгенерировать отчет с сотнями строк данных, а затем каждую неделю обновлять его вручную? Excel зависает, числа в глазах двоятся, а дедлайны дышат в затылок. В такой момент Python становится супергероем офисной автоматизации. Сегодня я покажу, как автоматизировать создание и обновление отчетов с помощью Python — быстро, просто и без боли.
На помощь приходят проверенные бойцы: pandas, openpyxl и matplotlib. Они помогут работать с данными, редактировать Excel-файлы и даже строить графики. Начнем с простого отчета: есть CSV-файл с продажами по регионам, нам нужно собрать сумму продаж, построить график и сохранить всё это в Excel-отчет.
Пример исходных данных в sales.csv:
region,date,sales
North,2024-05-01,1200
South,2024-05-01,950
North,2024-05-02,1340
... и так далее.
Сначала читаем и обрабатываем данные:
Хотим добавить график, чтобы отчет был не только полезный, но и красивый? Без проблем:
Теперь создаем Excel-файл с таблицей и вставляем туда наш график:
Что получилось: из CSV-файла мы автоматически получили сводную таблицу по регионам, построили визуализацию и сохранили все это в виде Excel-файла. Всё генерируется буквально за секунды. Можно запускать этот скрипт каждый день или неделю через планировщик задач — и больше не мучиться с отчетами вручную.
Если добавить немножко логики — например, проверку за какую дату данные, или отправку итогового файла по email через smtplib — автоматизация выходит на новый уровень.
Python не просто сокращает время, он освобождает его. Отчеты, которые раньше отнимали часы, можно теперь генерировать в одно касание. И вместо унылого копирования цифр — больше времени на анализ, развитие и создание чего-то действительно важного.
На помощь приходят проверенные бойцы: pandas, openpyxl и matplotlib. Они помогут работать с данными, редактировать Excel-файлы и даже строить графики. Начнем с простого отчета: есть CSV-файл с продажами по регионам, нам нужно собрать сумму продаж, построить график и сохранить всё это в Excel-отчет.
Пример исходных данных в sales.csv:
region,date,sales
North,2024-05-01,1200
South,2024-05-01,950
North,2024-05-02,1340
... и так далее.
Сначала читаем и обрабатываем данные:
import pandas as pd
data = pd.read_csv("sales.csv", parse_dates=["date"])
summary = data.groupby("region")["sales"].sum().reset_index()
Хотим добавить график, чтобы отчет был не только полезный, но и красивый? Без проблем:
import matplotlib.pyplot as plt
plt.figure(figsize=(6, 4))
plt.bar(summary["region"], summary["sales"], color="skyblue")
plt.title("Sales by Region")
plt.xlabel("Region")
plt.ylabel("Total Sales")
plt.tight_layout()
plt.savefig("sales_chart.png")
plt.close()
Теперь создаем Excel-файл с таблицей и вставляем туда наш график:
from openpyxl import Workbook
from openpyxl.drawing.image import Image
from openpyxl.utils.dataframe import dataframe_to_rows
wb = Workbook()
ws = wb.active
ws.title = "Sales Report"
# Вставляем таблицу
for row in dataframe_to_rows(summary, index=False, header=True):
ws.append(row)
# Вставляем картинку с графиком
img = Image("sales_chart.png")
img.anchor = "E2" # координаты вставки
ws.add_image(img)
wb.save("sales_report.xlsx")
Что получилось: из CSV-файла мы автоматически получили сводную таблицу по регионам, построили визуализацию и сохранили все это в виде Excel-файла. Всё генерируется буквально за секунды. Можно запускать этот скрипт каждый день или неделю через планировщик задач — и больше не мучиться с отчетами вручную.
Если добавить немножко логики — например, проверку за какую дату данные, или отправку итогового файла по email через smtplib — автоматизация выходит на новый уровень.
Python не просто сокращает время, он освобождает его. Отчеты, которые раньше отнимали часы, можно теперь генерировать в одно касание. И вместо унылого копирования цифр — больше времени на анализ, развитие и создание чего-то действительно важного.
Forwarded from Python для начинающих
Многоязычие в Django: как заставить ваше приложение "говорить" по-английски, по-русски и не только
Создаёте веб-приложение и хотите, чтобы им пользовались люди со всего мира? Добро пожаловать в мульти-языковой мир Django. Этот фреймворк предоставляет полноценные средства для локализации интерфейсов — от перевода текстов до управления пользовательскими языковыми настройками. Ниже — конкретно и без воды о том, как всё это настроить.
🔹 Шаг 1: Включим поддержку перевода
В
Параметр
🔹 Шаг 2: Готовим строки к переводу
Все строки, которые должны быть переведены, нужно пометить специальными функциями. Django предоставляет
Пример в шаблоне:
Пример в Python-коде:
🔹 Шаг 3: Собираем переводимые строки
После пометок — соберём все строки для перевода. Выполняем команду:
В результате появится файл
🔹 Шаг 4: Компилируем переводы
Чтобы Django мог использовать переведённые строки, необходимо скомпилировать
Теперь переводы готовы к использованию.
🔹 Шаг 5: Автоматическое определение языка
Добавьте
Этот middleware анализирует заголовки браузера или куки и подставляет нужный язык.
Хотите переключать язык вручную? Создайте URL:
Теперь URL-адрес будет содержать префикс языка (
🔹 Шаг 6: Динамическое переключение языка
Можно переключать язык прямо во время выполнения, например, через форму или селектор:
🎉 Готово!
Теперь ваше Django-приложение умеет "разговаривать" на нескольких языках. Это открывает дорогу к глобальному рынку и делает интерфейс дружелюбнее к пользователю.
Локализация в Django — это не просто nice-to-have. Это must-have, если вы хотите выйти за пределы одного языка. Делая ваш сайт многоязычным, вы делаете его доступным. А значит — полезным.
Создаёте веб-приложение и хотите, чтобы им пользовались люди со всего мира? Добро пожаловать в мульти-языковой мир Django. Этот фреймворк предоставляет полноценные средства для локализации интерфейсов — от перевода текстов до управления пользовательскими языковыми настройками. Ниже — конкретно и без воды о том, как всё это настроить.
🔹 Шаг 1: Включим поддержку перевода
В
settings.py
активируем интернационализацию:USE_I18N = True
USE_L10N = True
LANGUAGE_CODE = 'en'
LANGUAGES = [
('en', 'English'),
('ru', 'Russian'),
]
LOCALE_PATHS = [
BASE_DIR / 'locale',
]
Параметр
LANGUAGES
важен — это список поддерживаемых языков. Именно здесь вы определяете, на какие языки будет переведён ваш интерфейс.🔹 Шаг 2: Готовим строки к переводу
Все строки, которые должны быть переведены, нужно пометить специальными функциями. Django предоставляет
gettext()
и gettext_lazy()
(чаще используется ugettext_lazy
, но начиная с Django 4.0 используется просто gettext_lazy
).Пример в шаблоне:
<h1>{% trans "Welcome to my website!" %}</h1>
Пример в Python-коде:
from django.utils.translation import gettext_lazy as _
class Product(models.Model):
name = models.CharField(max_length=100, verbose_name=_("Product Name"))
🔹 Шаг 3: Собираем переводимые строки
После пометок — соберём все строки для перевода. Выполняем команду:
django-admin makemessages -l ru
В результате появится файл
locale/ru/LC_MESSAGES/django.po
. Именно в нём вы вписываете переводы:msgid "Welcome to my website!"
msgstr "Добро пожаловать на мой сайт!"
🔹 Шаг 4: Компилируем переводы
Чтобы Django мог использовать переведённые строки, необходимо скомпилировать
.po
в .mo
:django-admin compilemessages
Теперь переводы готовы к использованию.
🔹 Шаг 5: Автоматическое определение языка
Добавьте
LocaleMiddleware
в MIDDLEWARE
:MIDDLEWARE = [
# ...
'django.middleware.locale.LocaleMiddleware',
# ...
]
Этот middleware анализирует заголовки браузера или куки и подставляет нужный язык.
Хотите переключать язык вручную? Создайте URL:
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
path('products/', include('products.urls')),
)
Теперь URL-адрес будет содержать префикс языка (
/ru/products/
), а Django подстроится под локаль.🔹 Шаг 6: Динамическое переключение языка
Можно переключать язык прямо во время выполнения, например, через форму или селектор:
from django.utils import translation
def set_language_view(request):
user_language = 'ru'
translation.activate(user_language)
response = HttpResponse("Привет!")
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user_language)
return response
🎉 Готово!
Теперь ваше Django-приложение умеет "разговаривать" на нескольких языках. Это открывает дорогу к глобальному рынку и делает интерфейс дружелюбнее к пользователю.
Локализация в Django — это не просто nice-to-have. Это must-have, если вы хотите выйти за пределы одного языка. Делая ваш сайт многоязычным, вы делаете его доступным. А значит — полезным.
Forwarded from Python для начинающих
Когда Python встречает физику: симулятор с помощью NVIDIA PhysX
Что объединяет гоночные симуляторы, реалистичную анимацию разрушений и эффектное поведение объектов на сцене? Конечно, физика. А если быть конкретнее — движок PhysX, изначально разработанный Ageia, а позже поглощённый NVIDIA. Он лежит в основе механики многих игр и симуляторов. Но что, если мы хотим использовать его вместе с Python?
Благодаря проекту physx-python от NVIDIA, теперь это возможно. Интуитивный интерфейс Python позволяет собирать полноценные трёхмерные сцены с телами, гравитацией и столкновениями — и всё это с минимальной настройкой.
Что потребуется?
- Установленный Python 3.8+
- Установленный модуль
- Знание базовых концепций физики (масса, силы, импульсы)
Установка:
Сборка первой сцены
Создадим простую сцену: куб падает на плоскость под действием гравитации.
Теперь запустим симуляцию:
На выходе мы получим по кадрам, как куб падает и отскакивает — PhysX учитывает инерцию, массу, трение и отскок автоматически.
Почему PhysX и не, скажем, Pymunk или Box2D?
- PhysX — это полноценная 3D-физика. Большинство Python-движков оперируют 2D.
- Оптимизация. PhysX используется в AAA-проектах и оптимизирован под реальные нагрузки.
- Расширяемость. С PhysX можно моделировать не только твердые тела, но и жидкости, ткани, разрушения (через расширения).
Советы:
- Обрабатывайте столкновения через колбэки (наследуйте
- Используйте инерцию и силы, а не вручную перемещайте тела
- Не забывайте освобождать ресурсы (
PhysX с Python — это серьезный инструмент для тех, кто хочет симулировать реальные процессы: от гравитации и столкновений до сложного взаимодействия объектов. Создавайте симуляторы роботов, физические головоломки или тестируйте алгоритмы управления — теперь это возможно без написания ни строчки C++.
Следующий шаг? Визуализация. А значит, впереди ждёт интеграция с OpenGL, Pyglet или Panda3D. Физика оживает, а Python снова доказывает, что с ним возможны настоящие чудеса.
Что объединяет гоночные симуляторы, реалистичную анимацию разрушений и эффектное поведение объектов на сцене? Конечно, физика. А если быть конкретнее — движок PhysX, изначально разработанный Ageia, а позже поглощённый NVIDIA. Он лежит в основе механики многих игр и симуляторов. Но что, если мы хотим использовать его вместе с Python?
Благодаря проекту physx-python от NVIDIA, теперь это возможно. Интуитивный интерфейс Python позволяет собирать полноценные трёхмерные сцены с телами, гравитацией и столкновениями — и всё это с минимальной настройкой.
Что потребуется?
- Установленный Python 3.8+
- Установленный модуль
physx
(доступен через PyPI или GitHub)- Знание базовых концепций физики (масса, силы, импульсы)
Установка:
pip install physx
Сборка первой сцены
Создадим простую сцену: куб падает на плоскость под действием гравитации.
from physx import PxPhysics, PxSceneDesc, PxDefaultErrorCallback, PxDefaultAllocator, PxSimulationEventCallback
from physx import PxRigidStatic, PxRigidDynamic, PxShape, PxBoxGeometry, PxMaterial, PxTransform, PxVec3
physics = PxPhysics()
material = physics.create_material(0.5, 0.5, 0.6)
scene_desc = PxSceneDesc(gravity=PxVec3(0, -9.81, 0))
scene = physics.create_scene(scene_desc)
# Создаем землю (плоскость)
ground_shape = physics.create_shape(PxBoxGeometry(50, 1, 50), material)
ground_body = physics.create_rigid_static(transform=PxTransform(p=PxVec3(0, -1, 0)))
ground_body.attach_shape(ground_shape)
scene.add_actor(ground_body)
# Создаем динамический куб
box_shape = physics.create_shape(PxBoxGeometry(1, 1, 1), material)
box_body = physics.create_rigid_dynamic(transform=PxTransform(p=PxVec3(0, 5, 0)))
box_body.attach_shape(box_shape)
scene.add_actor(box_body)
Теперь запустим симуляцию:
time_step = 1.0 / 60.0 # 60 FPS
for step in range(120):
scene.simulate(time_step)
scene.fetch_results()
pos = box_body.get_global_pose().p
print(f"Step {step}: Box Y={pos.y:.2f}")
На выходе мы получим по кадрам, как куб падает и отскакивает — PhysX учитывает инерцию, массу, трение и отскок автоматически.
Почему PhysX и не, скажем, Pymunk или Box2D?
- PhysX — это полноценная 3D-физика. Большинство Python-движков оперируют 2D.
- Оптимизация. PhysX используется в AAA-проектах и оптимизирован под реальные нагрузки.
- Расширяемость. С PhysX можно моделировать не только твердые тела, но и жидкости, ткани, разрушения (через расширения).
Советы:
- Обрабатывайте столкновения через колбэки (наследуйте
PxSimulationEventCallback
)- Используйте инерцию и силы, а не вручную перемещайте тела
- Не забывайте освобождать ресурсы (
release()
)PhysX с Python — это серьезный инструмент для тех, кто хочет симулировать реальные процессы: от гравитации и столкновений до сложного взаимодействия объектов. Создавайте симуляторы роботов, физические головоломки или тестируйте алгоритмы управления — теперь это возможно без написания ни строчки C++.
Следующий шаг? Визуализация. А значит, впереди ждёт интеграция с OpenGL, Pyglet или Panda3D. Физика оживает, а Python снова доказывает, что с ним возможны настоящие чудеса.
Forwarded from Python для начинающих
Привет! Сегодня поговорим о том, как с помощью Python и библиотеки OpenCV сделать собственное приложение для черепичной сшивки изображений (image tiling & stitching). Эта задача особенно актуальна в сфере обработки спутниковых снимков, работы с изображениями высокой чёткости или при создании панорам.
Самое интересное — почти всё можно сделать на базе стандартных функций OpenCV. Да, да, без любой магии и глубокого машинного обучения. Просто рабочий пайплайн, немного математики и правильный подход.
—
Что такое черепичная сшивка?
Представьте, что у вас есть несколько перекрывающихся фрагментов одной и той же большой сцены, но снятых по частям. Ваша задача — склеить эти плитки (tiles) в одно большое изображение. Чтобы это сделать, нужно:
1. Найти ключевые точки (keypoints) в каждом изображении.
2. Сопоставить соответствующие точки между изображениями.
3. Посчитать матрицу преобразования (гомографию).
4. Трансформировать изображения и сшить в финальную панораму.
Теперь перейдем к коду.
Первым делом, необходимые модули:
Теперь загрузим два изображения:
Далее — извлечение ключевых точек и дескрипторов с помощью ORB:
Для поиска совпадений используем BFMatcher:
Отфильтруем и найдем гомографию:
И наконец — применим гомографию и объединим изображения:
—
Приложение, построенное на этом пайплайне, способно объединить десятки изображений в одну панораму. Конечно, для большого количества тайлов придётся реализовать логику автоматического выбора пар изображений, контроля перекрытия и конечной обрезки границ. Но фундамент уже есть.
Можно также использовать SIFT или AKAZE вместо ORB, повысить количество фич, настроить лучшее сопоставление по расстоянию — и ваша сшивка будет максимально качественной.
Бонус: если изображения GRID-подобные (например, каждая плитка — квадрат одной мозаики), можно автоматизировать позиции сшивки заранее, что даст прирост скорости. А если вы работаете с гигабайтными изображениями — добавьте Pillow или Dask для потоковой обработки.
С OpenCV и всего сотней строк кода на Python вы можете превратить десятки скучных фрагментов в полноценную мозаику мира.
Самое интересное — почти всё можно сделать на базе стандартных функций OpenCV. Да, да, без любой магии и глубокого машинного обучения. Просто рабочий пайплайн, немного математики и правильный подход.
—
Что такое черепичная сшивка?
Представьте, что у вас есть несколько перекрывающихся фрагментов одной и той же большой сцены, но снятых по частям. Ваша задача — склеить эти плитки (tiles) в одно большое изображение. Чтобы это сделать, нужно:
1. Найти ключевые точки (keypoints) в каждом изображении.
2. Сопоставить соответствующие точки между изображениями.
3. Посчитать матрицу преобразования (гомографию).
4. Трансформировать изображения и сшить в финальную панораму.
Теперь перейдем к коду.
Первым делом, необходимые модули:
import cv2
import numpy as np
Теперь загрузим два изображения:
image_1 = cv2.imread("tile_left.jpg")
image_2 = cv2.imread("tile_right.jpg")
Далее — извлечение ключевых точек и дескрипторов с помощью ORB:
orb = cv2.ORB_create(nfeatures=2000)
kp1, des1 = orb.detectAndCompute(image_1, None)
kp2, des2 = orb.detectAndCompute(image_2, None)
Для поиска совпадений используем BFMatcher:
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
Отфильтруем и найдем гомографию:
src_pts = np.float32([kp1[m.queryIdx].pt for m in matches[:50]]).reshape(-1,1,2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches[:50]]).reshape(-1,1,2)
H, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)
И наконец — применим гомографию и объединим изображения:
height, width = image_1.shape[:2]
image_2_warped = cv2.warpPerspective(image_2, H, (width * 2, height))
image_2_warped[0:height, 0:width] = image_1
cv2.imwrite("stitched_output.jpg", image_2_warped)
—
Приложение, построенное на этом пайплайне, способно объединить десятки изображений в одну панораму. Конечно, для большого количества тайлов придётся реализовать логику автоматического выбора пар изображений, контроля перекрытия и конечной обрезки границ. Но фундамент уже есть.
Можно также использовать SIFT или AKAZE вместо ORB, повысить количество фич, настроить лучшее сопоставление по расстоянию — и ваша сшивка будет максимально качественной.
Бонус: если изображения GRID-подобные (например, каждая плитка — квадрат одной мозаики), можно автоматизировать позиции сшивки заранее, что даст прирост скорости. А если вы работаете с гигабайтными изображениями — добавьте Pillow или Dask для потоковой обработки.
С OpenCV и всего сотней строк кода на Python вы можете превратить десятки скучных фрагментов в полноценную мозаику мира.
Forwarded from Python для начинающих
🏗 Введение в web scraping с использованием Scrapy и Selenium
Собирать данные с сайтов — это почти как добывать золото: кто вовремя начал, тот и нашёл сокровища. Web scraping позволяет автоматизировать сбор информации с сайтов, и в Python для этого есть мощные инструменты. Сегодня мы взглянем на два самых популярных — Scrapy и Selenium.
📌 Scrapy: паук, который знает, куда ползти
Если вам нужно быстро и масштабируемо собирать структурированные данные, Scrapy — идеальный выбор. Это асинхронный фреймворк, созданный специально для парсинга.
Установка:
Как выглядит простейший Scrapy-паук:
Запуск:
Scrapy быстро, удобно и экономно вытянет нужные данные из HTML — пока сайт не вставляет всё содержимое с помощью JavaScript. Тогда на сцену выходит Selenium.
🚘 Selenium: браузерный пилот-робот
Иногда сайты упрямо не отдают нужные данные, пока JavaScript не "догрузит" контент. Тогда у нас один выход — автоматизировать действия настоящего браузера.
Установка:
Пример: как с помощью Selenium вытащить цитаты со страницы с динамическим контентом:
🔥 Scrapy против Selenium
| Характеристика | Scrapy | Selenium |
|----------------------|-------------------------------|-------------------------|
| Скорость | Высокая (асинхронная) | Низкая (имитирует браузер) |
| Поддержка JS | Нет | Да |
| Использование памяти | Экономное | Тяжёлое |
| Удобство отладки | Лучше для парсинга | Лучше для автотестов и сложной логики |
🧩 Идеальный сценарий — совмещать: использовать Selenium для получения HTML со сложных JS-страниц, а дальнейший парсинг делать с помощью Scrapy или BeautifulSoup.
Если вы собираетесь парсить десятки тысяч страниц, стоит идти через Scrapy. Если же цель — парсинг интерактивных компонентов одной-двух страниц, Selenium подойдёт лучше. А иногда — сочетайте.
Следите за "золотыми правилами" scraping-а: соблюдайте robots.txt, не перегружайте сервер запросами, и, конечно, уважайте условия использования сайта.
В следующем посте мы разберём, как Scrapy можно расширять — добавим логин на сайт и парсинг нескольких уровней ссылок.
Собирать данные с сайтов — это почти как добывать золото: кто вовремя начал, тот и нашёл сокровища. Web scraping позволяет автоматизировать сбор информации с сайтов, и в Python для этого есть мощные инструменты. Сегодня мы взглянем на два самых популярных — Scrapy и Selenium.
📌 Scrapy: паук, который знает, куда ползти
Если вам нужно быстро и масштабируемо собирать структурированные данные, Scrapy — идеальный выбор. Это асинхронный фреймворк, созданный специально для парсинга.
Установка:
pip install scrapy
Как выглядит простейший Scrapy-паук:
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = ["http://quotes.toscrape.com/"]
def parse(self, response):
for quote in response.css("div.quote"):
yield {
"text": quote.css("span.text::text").get(),
"author": quote.css("small.author::text").get(),
}
Запуск:
scrapy runspider quotes_spider.py -o quotes.json
Scrapy быстро, удобно и экономно вытянет нужные данные из HTML — пока сайт не вставляет всё содержимое с помощью JavaScript. Тогда на сцену выходит Selenium.
🚘 Selenium: браузерный пилот-робот
Иногда сайты упрямо не отдают нужные данные, пока JavaScript не "догрузит" контент. Тогда у нас один выход — автоматизировать действия настоящего браузера.
Установка:
pip install selenium
Пример: как с помощью Selenium вытащить цитаты со страницы с динамическим контентом:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
options = Options()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
driver.get("http://quotes.toscrape.com/js/")
time.sleep(2) # подождём, пока JS подгрузит контент
quotes = driver.find_elements(By.CLASS_NAME, "quote")
for q in quotes:
text = q.find_element(By.CLASS_NAME, "text").text
author = q.find_element(By.CLASS_NAME, "author").text
print({"text": text, "author": author})
driver.quit()
🔥 Scrapy против Selenium
| Характеристика | Scrapy | Selenium |
|----------------------|-------------------------------|-------------------------|
| Скорость | Высокая (асинхронная) | Низкая (имитирует браузер) |
| Поддержка JS | Нет | Да |
| Использование памяти | Экономное | Тяжёлое |
| Удобство отладки | Лучше для парсинга | Лучше для автотестов и сложной логики |
🧩 Идеальный сценарий — совмещать: использовать Selenium для получения HTML со сложных JS-страниц, а дальнейший парсинг делать с помощью Scrapy или BeautifulSoup.
Если вы собираетесь парсить десятки тысяч страниц, стоит идти через Scrapy. Если же цель — парсинг интерактивных компонентов одной-двух страниц, Selenium подойдёт лучше. А иногда — сочетайте.
Следите за "золотыми правилами" scraping-а: соблюдайте robots.txt, не перегружайте сервер запросами, и, конечно, уважайте условия использования сайта.
В следующем посте мы разберём, как Scrapy можно расширять — добавим логин на сайт и парсинг нескольких уровней ссылок.
Forwarded from Python для начинающих
🔥 Как использовать библиотеки для автоматического тестирования веб-приложений
Сегодня поговорим о настоящем магическом арсенале Python — библиотеках для автоматизированного тестирования веб-приложений. Зачем вручную кликать по кнопкам и проверять, что форма отправляется, если можно поручить это роботу?
Да, автоматизация тестирования — это не только для корпораций с огромным QA-отделом. Даже если ты пишешь свой первый сайт на Flask — запускать тесты «по кнопке» и быть уверенным, что ничего не сломано после очередного коммита — бесценно.
Давайте рассмотрим две популярные библиотеки: Selenium и pytest, плюс кратко затронем requests и BeautifulSoup для API и контентных проверок.
🎯 Selenium — когда надо кликать мышкой и вводить текст
Selenium позволяет имитировать поведение пользователя в браузере: запустить сайт, заполнить поля, нажать кнопки и проверить, как всё работает. Вот простой пример с использованием Chrome WebDriver:
Этот код удобно запускать в рамках pytest или unittest. Selenium особенно полезен, когда нужно протестировать интерфейс, JavaScript и формы.
🤖 Pytest — быстрые и читаемые тесты
Pytest — это ядро для любого вида тестов. Оно прекрасно умеет работать с фикстурами и параметризацией, а код остаётся чистым и читаемым.
Пример интеграции с requests для проверки REST API:
Иногда этого достаточно — особенно если ты делаешь SPA с разделённым backend.
🍜 Bonus: BeautifulSoup для проверки содержимого
Допустим, приходит HTML, и хочется убедиться, что нужный блок отрисовался:
Не затыкай нос — HTML можно парсить, не страдая.
📦 Как собрать вместе?
Обычно автоматика выглядит так: ты пишешь тесты на pytest, которые используют библиотеки вроде requests для API и selenium для UI. Запуск происходит через команду:
Или, если хочется сборку в CI/CD — используется GitHub Actions или GitLab CI. Всё по-взрослому.
⚡ Итог
Автоматизированное тестирование — это не роскошь. Это важный инструмент, который экономит время и нервы. Python предоставляет для этого весь необходимый инструментарий: от selenium до requests и pytest. Начни с простого, а потом постепенно автоматизируй всё, что можно.
Тестируй умно — пиши код с уверенностью.
Сегодня поговорим о настоящем магическом арсенале Python — библиотеках для автоматизированного тестирования веб-приложений. Зачем вручную кликать по кнопкам и проверять, что форма отправляется, если можно поручить это роботу?
Да, автоматизация тестирования — это не только для корпораций с огромным QA-отделом. Даже если ты пишешь свой первый сайт на Flask — запускать тесты «по кнопке» и быть уверенным, что ничего не сломано после очередного коммита — бесценно.
Давайте рассмотрим две популярные библиотеки: Selenium и pytest, плюс кратко затронем requests и BeautifulSoup для API и контентных проверок.
🎯 Selenium — когда надо кликать мышкой и вводить текст
Selenium позволяет имитировать поведение пользователя в браузере: запустить сайт, заполнить поля, нажать кнопки и проверить, как всё работает. Вот простой пример с использованием Chrome WebDriver:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("https://example.com/login")
username_input = driver.find_element(By.NAME, "username")
password_input = driver.find_element(By.NAME, "password")
username_input.send_keys("test_user")
password_input.send_keys("secure_pass")
password_input.send_keys(Keys.RETURN)
assert "Dashboard" in driver.title
driver.quit()
Этот код удобно запускать в рамках pytest или unittest. Selenium особенно полезен, когда нужно протестировать интерфейс, JavaScript и формы.
🤖 Pytest — быстрые и читаемые тесты
Pytest — это ядро для любого вида тестов. Оно прекрасно умеет работать с фикстурами и параметризацией, а код остаётся чистым и читаемым.
Пример интеграции с requests для проверки REST API:
import requests
def test_api_status():
response = requests.get("https://api.example.com/status")
assert response.status_code == 200
def test_login_api():
data = {"username": "test_user", "password": "secure_pass"}
response = requests.post("https://api.example.com/login", json=data)
assert response.json().get("token") is not None
Иногда этого достаточно — особенно если ты делаешь SPA с разделённым backend.
🍜 Bonus: BeautifulSoup для проверки содержимого
Допустим, приходит HTML, и хочется убедиться, что нужный блок отрисовался:
from bs4 import BeautifulSoup
html = "<html><body><div id='welcome'>Hello, test_user!</div></body></html>"
soup = BeautifulSoup(html, "html.parser")
welcome_div = soup.find("div", id="welcome")
assert welcome_div.text == "Hello, test_user!"
Не затыкай нос — HTML можно парсить, не страдая.
📦 Как собрать вместе?
Обычно автоматика выглядит так: ты пишешь тесты на pytest, которые используют библиотеки вроде requests для API и selenium для UI. Запуск происходит через команду:
pytest tests/
Или, если хочется сборку в CI/CD — используется GitHub Actions или GitLab CI. Всё по-взрослому.
⚡ Итог
Автоматизированное тестирование — это не роскошь. Это важный инструмент, который экономит время и нервы. Python предоставляет для этого весь необходимый инструментарий: от selenium до requests и pytest. Начни с простого, а потом постепенно автоматизируй всё, что можно.
Тестируй умно — пиши код с уверенностью.
Forwarded from Python для начинающих
🚀 Быстрая обработка гигантских наборов данных с использованием библиотеки Vaex
Обработка миллионов строк данных за секунды — звучит как фантастика? Для pandas — возможно, но не факт. А вот для Vaex — это его стихия. В этом посте я расскажу о том, как справляться с большими объёмами данных с помощью библиотеки Vaex — легковесного и ультрабыстрого инструмента для анализа данных на Python.
🧠 Что такое Vaex?
Vaex — это библиотека для обработки больших табличных данных, созданная с фокусом на производительность. В отличие от pandas, она использует ленивые вычисления (lazy evaluation), memory-mapping и мультиядерные вычисления для обработки данных в десятки раз быстрее. Миллионы строк? Подумаешь. Даже миллиард — не предел.
Вот ключевые фишки Vaex:
- Обработка данных, которые не помещаются в оперативную память.
- Поддержка ленивых операций (т.е. ничего не считается до тех пор, пока не попросишь).
- Использование zero-copy memory access — данные читаются прямо с диска без загрузки в RAM.
- Интеграция с файловыми форматами Arrow, HDF5 и Parquet.
📦 Установка
Устанавливаем библиотеку:
🚀 Быстрый старт
Допустим, у нас есть CSV-файл с 50 миллионами строк. Попробуем прочитать его и посмотреть средние значения по колонке:
Метод
🧪 Где быстрее, чем в pandas?
Vaex особенно хорош для агрегаций и фильтраций. Сравним простую агрегацию:
Огромный набор категорий и десятки миллионов цен — Vaex справляется без напряжения.
🎯 Фильтрация на лету
Vaex не гонит весь датафрейм через фильтры. Он выполняет их лениво, максимально эффективно:
🔥 Визуализация огромных данных
Vaex умеет делать биннинг (разбиение по диапазонам), что особенно полезно при визуализации плотных scatter-плотов:
Да, прямо так. Интерактивное, быстрое, работает на миллионах точек.
📁 Разделение и экспорт
Вы можете экспортировать уже отфильтрованные или агрегированные данные обратно в Parquet или CSV:
🧩 Vaex против pandas
Время выполнения задачи агрегации в pandas: десятки секунд или даже минуты (и возможный MemoryError). В Vaex — доли секунды. И не нужно думать, достаточно ли у тебя оперативки.
📌 Используй тогда, когда:
- Твои данные занимают десятки или сотни ГБ
- pandas падает с ошибками памяти
- Требуется быстрая агрегация, фильтрация, группировка
- Нужно делать всё это без громоздких кластеров Spark/Dask
✨ Вывод
Vaex — отличный инструмент, когда речь идёт о больших объемах данных и важна скорость. Он не заменяет pandas как основной инструмент работы с данными, но для heavy-duty аналитики — просто must-have. Попробуй использовать его в своём следующем дата-проекте — и удивишься, насколько это быстро.
Обработка миллионов строк данных за секунды — звучит как фантастика? Для pandas — возможно, но не факт. А вот для Vaex — это его стихия. В этом посте я расскажу о том, как справляться с большими объёмами данных с помощью библиотеки Vaex — легковесного и ультрабыстрого инструмента для анализа данных на Python.
🧠 Что такое Vaex?
Vaex — это библиотека для обработки больших табличных данных, созданная с фокусом на производительность. В отличие от pandas, она использует ленивые вычисления (lazy evaluation), memory-mapping и мультиядерные вычисления для обработки данных в десятки раз быстрее. Миллионы строк? Подумаешь. Даже миллиард — не предел.
Вот ключевые фишки Vaex:
- Обработка данных, которые не помещаются в оперативную память.
- Поддержка ленивых операций (т.е. ничего не считается до тех пор, пока не попросишь).
- Использование zero-copy memory access — данные читаются прямо с диска без загрузки в RAM.
- Интеграция с файловыми форматами Arrow, HDF5 и Parquet.
📦 Установка
Устанавливаем библиотеку:
pip install vaex
🚀 Быстрый старт
Допустим, у нас есть CSV-файл с 50 миллионами строк. Попробуем прочитать его и посмотреть средние значения по колонке:
import vaex
# Быстрая загрузка большого файла
df = vaex.from_csv('big_data.csv', convert=True, chunk_size=5_000_000)
# Просмотр первых строк, как в pandas
print(df.head())
# Вычисление средней температуры, к примеру
mean_temp = df['temperature'].mean()
print(f"Mean temperature: {mean_temp}")
Метод
from_csv
с параметром convert=True
один раз конвертирует CSV в более быстрый бинарный формат Arrow/HDF5, чтобы в будущем грузиться мгновенно.🧪 Где быстрее, чем в pandas?
Vaex особенно хорош для агрегаций и фильтраций. Сравним простую агрегацию:
# Средняя цена по категориям
df.groupby('category', agg={'avg_price': vaex.agg.mean('price')})
Огромный набор категорий и десятки миллионов цен — Vaex справляется без напряжения.
🎯 Фильтрация на лету
Vaex не гонит весь датафрейм через фильтры. Он выполняет их лениво, максимально эффективно:
# Отфильтруем дорогие продукты
df_filtered = df[df.price > 1000]
# Считаем средний рейтинг у дорогих товаров
print(df_filtered['rating'].mean())
🔥 Визуализация огромных данных
Vaex умеет делать биннинг (разбиение по диапазонам), что особенно полезно при визуализации плотных scatter-плотов:
df.plot(df.x, df.y, f='log1p', shape=512)
Да, прямо так. Интерактивное, быстрое, работает на миллионах точек.
📁 Разделение и экспорт
Вы можете экспортировать уже отфильтрованные или агрегированные данные обратно в Parquet или CSV:
df_filtered.export_parquet('filtered_data.parquet')
🧩 Vaex против pandas
Время выполнения задачи агрегации в pandas: десятки секунд или даже минуты (и возможный MemoryError). В Vaex — доли секунды. И не нужно думать, достаточно ли у тебя оперативки.
📌 Используй тогда, когда:
- Твои данные занимают десятки или сотни ГБ
- pandas падает с ошибками памяти
- Требуется быстрая агрегация, фильтрация, группировка
- Нужно делать всё это без громоздких кластеров Spark/Dask
✨ Вывод
Vaex — отличный инструмент, когда речь идёт о больших объемах данных и важна скорость. Он не заменяет pandas как основной инструмент работы с данными, но для heavy-duty аналитики — просто must-have. Попробуй использовать его в своём следующем дата-проекте — и удивишься, насколько это быстро.
Forwarded from Python для начинающих
🎨 Простейшие графические редакторы с использованием библиотеки tkinter
Каждому программисту когда-то хочется превратить консольную рутину во что-то более… зрелищное. Если вы только начинаете осваивать Python – отличной отправной точкой может стать создание собственного графического редактора с помощью tkinter, стандартной библиотеки GUI в Python.
Да-да, самый настоящий Paint в несколько десятков строк!
tkinter поставляется в комплекте с Python, так что ничего дополнительно устанавливать не нужно. Запускаем редактор – и рисуем прямо мышкой. Прекрасная демонстрация того, как события и интерактивность работают в Python.
Разберем базовую версию редактора — с возможностью рисования линий мышкой.
Вот простой пример:
Что здесь происходит:
- Мы создаем окно и холст (canvas), на котором можно рисовать.
- Событие
-
Теперь добавим выбор цвета — немного разнообразия:
Добавим в класс:
Хотите очистить холст? Пожалуйста:
В результате — у нас простенький редактор с выбором цвета и кнопкой очистки. Интересно? На основе такой базы можно реализовать:
- выбор толщины линии;
- сохранение в PNG (с помощью PIL);
- разные инструменты (овал, прямоугольник, ластик — да, просто белая линия!);
- undo/redo с помощью хранения команд;
- и даже распознавание фигур, если вы фанат ML.
tkinter — отличный способ перейти из мира print('Hello') в более наглядный и живой Python. Начните с мини-графредактора, а дальше — рамки только в вашем воображении.
Каждому программисту когда-то хочется превратить консольную рутину во что-то более… зрелищное. Если вы только начинаете осваивать Python – отличной отправной точкой может стать создание собственного графического редактора с помощью tkinter, стандартной библиотеки GUI в Python.
Да-да, самый настоящий Paint в несколько десятков строк!
tkinter поставляется в комплекте с Python, так что ничего дополнительно устанавливать не нужно. Запускаем редактор – и рисуем прямо мышкой. Прекрасная демонстрация того, как события и интерактивность работают в Python.
Разберем базовую версию редактора — с возможностью рисования линий мышкой.
Вот простой пример:
import tkinter as tk
class SimplePaint:
def __init__(self, root):
self.root = root
self.root.title("Mini Paint")
self.canvas = tk.Canvas(root, bg="white", width=600, height=400)
self.canvas.pack(fill=tk.BOTH, expand=True)
self.last_x, self.last_y = None, None
self.canvas.bind("<Button-1>", self.start_draw)
self.canvas.bind("<B1-Motion>", self.draw_line)
def start_draw(self, event):
self.last_x, self.last_y = event.x, event.y
def draw_line(self, event):
x, y = event.x, event.y
self.canvas.create_line(self.last_x, self.last_y, x, y, fill="black", width=2)
self.last_x, self.last_y = x, y
root = tk.Tk()
app = SimplePaint(root)
root.mainloop()
Что здесь происходит:
- Мы создаем окно и холст (canvas), на котором можно рисовать.
- Событие
<Button-1>
(нажатие левой кнопки мыши) отслеживает начало рисования.-
<B1-Motion>
ловит перемещения мыши при нажатой кнопке и соединяет координаты линиями.Теперь добавим выбор цвета — немного разнообразия:
from tkinter.colorchooser import askcolor
def choose_color():
color = askcolor()[1]
if color:
app.current_color = color
color_btn = tk.Button(root, text="Color", command=choose_color)
color_btn.pack()
Добавим в класс:
self.current_color = "black"
...
self.canvas.create_line(self.last_x, self.last_y, x, y, fill=self.current_color, width=2)
Хотите очистить холст? Пожалуйста:
def clear_canvas():
app.canvas.delete("all")
clear_btn = tk.Button(root, text="Clear", command=clear_canvas)
clear_btn.pack()
В результате — у нас простенький редактор с выбором цвета и кнопкой очистки. Интересно? На основе такой базы можно реализовать:
- выбор толщины линии;
- сохранение в PNG (с помощью PIL);
- разные инструменты (овал, прямоугольник, ластик — да, просто белая линия!);
- undo/redo с помощью хранения команд;
- и даже распознавание фигур, если вы фанат ML.
tkinter — отличный способ перейти из мира print('Hello') в более наглядный и живой Python. Начните с мини-графредактора, а дальше — рамки только в вашем воображении.
Forwarded from Python для начинающих
🎨 Работа с сериями изображений в Python с помощью scikit-image
Python — незаменимый инструмент для обработки изображений. Когда дело доходит до работы с несколькими изображениями — будь то слайд-шоу, кадры с камеры или серия снимков для ML-проекта — нам нужно что-то мощное и удобное. И тут на сцену выходит scikit-image.
Scikit-image — это библиотека на базе NumPy, предназначенная для обработки изображений. Она умеет всё: от базовой фильтрации до сложного анализа форм и объектов. А ещё — она умеет работать с сериями изображений.
📦 Установка:
Если вы ещё не установили библиотеку:
🔍 Загрузка серии изображений
Допустим, у вас есть папка с изображениями
Теперь
🛠️ Обработка серии
Допустим, вы хотите перевести все кадры в оттенки серого. Можно использовать
Хотите применить фильтр Гаусса ко всем изображениям?
📊 Построим гистограммы яркости
Иногда нужно проанализировать распределение яркости в серии. Используем
🎞️ Построение таймлапса
Допустим, вы обработали серию и теперь хотите сохранить новую последовательность:
🧠 Идеи для практики:
- Сделайте маску объектов на каждом кадре с помощью
- Выделите контуры с
- Сравните движение объектов между изображениями.
Scikit-image — настоящий швейцарский нож в мире изображений. Он понятен, лаконичен и отлично дружит с NumPy. Работать с сериями изображений с его помощью — одно удовольствие, а возможности практически безграничны.
Python — незаменимый инструмент для обработки изображений. Когда дело доходит до работы с несколькими изображениями — будь то слайд-шоу, кадры с камеры или серия снимков для ML-проекта — нам нужно что-то мощное и удобное. И тут на сцену выходит scikit-image.
Scikit-image — это библиотека на базе NumPy, предназначенная для обработки изображений. Она умеет всё: от базовой фильтрации до сложного анализа форм и объектов. А ещё — она умеет работать с сериями изображений.
📦 Установка:
Если вы ещё не установили библиотеку:
pip install scikit-image
🔍 Загрузка серии изображений
Допустим, у вас есть папка с изображениями
.png
или .jpg
. Вместо того чтобы грузить каждое вручную, используем skimage.io.imread_collection
.from skimage.io import imread_collection
images = imread_collection('images/*.png') # Загружаем все .png из папки images
Теперь
images
— это коллекция, с которой можно обращаться как со списком. Например, images[0]
— первое изображение, а len(images)
— общее количество.🛠️ Обработка серии
Допустим, вы хотите перевести все кадры в оттенки серого. Можно использовать
skimage.color.rgb2gray
:from skimage.color import rgb2gray
gray_images = [rgb2gray(img) for img in images]
Хотите применить фильтр Гаусса ко всем изображениям?
from skimage.filters import gaussian
blurred = [gaussian(img, sigma=1) for img in gray_images]
📊 Построим гистограммы яркости
Иногда нужно проанализировать распределение яркости в серии. Используем
skimage.exposure.histogram
:from skimage.exposure import histogram
import matplotlib.pyplot as plt
for i, img in enumerate(gray_images[:3]):
hist, hist_centers = histogram(img)
plt.plot(hist_centers, hist, label=f'Image {i}')
plt.legend()
plt.title("Brightness histograms")
plt.show()
🎞️ Построение таймлапса
Допустим, вы обработали серию и теперь хотите сохранить новую последовательность:
from skimage.io import imsave
import os
output_dir = 'processed'
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for i, img in enumerate(blurred):
imsave(f'{output_dir}/frame_{i:03d}.png', img)
🧠 Идеи для практики:
- Сделайте маску объектов на каждом кадре с помощью
skimage.filters.threshold_otsu
.- Выделите контуры с
skimage.feature.canny
.- Сравните движение объектов между изображениями.
Scikit-image — настоящий швейцарский нож в мире изображений. Он понятен, лаконичен и отлично дружит с NumPy. Работать с сериями изображений с его помощью — одно удовольствие, а возможности практически безграничны.
Если бы админ этого канала снова начал вести курс по Python для начинающих (по цене 7000 рублей за месячный курс из 14 уроков), вы бы хотели его пройти?
Anonymous Poll
25%
Да, я готов учиться, 7000 не так уж много за качественные знания по Python
75%
Нет
Forwarded from Python для начинающих
🔥 Как асинхронное программирование улучшает производительность сетевых приложений?
Если вы уже писали на Python сетевые приложения — например, телеграм-бота, простенький HTTP-сервер или парсер сайтов — вы, скорее всего, сталкивались с тем, что программа "зависает", когда ждет ответа от сервера. В этот момент Python… просто сидит и ждет. Чай себе заваривает. А вы — греете процессор на холостом ходу.
Но можно по-другому. Асинхронно. И вот в тот момент, когда вы впервые запускаете свой async-код и видите, как он в разы быстрее перебирает запросы, возникает ощущение магии. На самом деле, никакой магии — просто асинхронность.
🧠 Что происходит в обычной программе?
Вот пример кода, написанного "по старинке":
Каждый запрос “зависает” на 2 секунды (сайт задерживает выдачу ответа). Всего уходит около 10 секунд. Никакой многозадачности — каждая следующая итерация ждет завершения предыдущей.
📈 А теперь асинхронный подход:
Вся пятерка запросов отрабатывает… параллельно!
⏱ Результат? Вместо 10 секунд — примерно 2 секунды. Гениально просто.
⚙️ Почему это работает?
Асинхронная модель основана на событийном цикле. Когда вы делаете операцию ввода-вывода — например, ждете данные из интернета — интерпретатор Python освобождает поток и занимается другими задачами. Этот подход отлично работает, когда операций ввода-вывода много, а процессор почти не загружен — типичная ситуация для сетевых приложений.
Монолитный
💥 Где использовать асинхронность?
- Боты и чат-приложения (async-сервер получает и отправляет сообщения без задержек)
- Web API-клиенты (одновременно дергаем десятки API)
- Парсеры сайтов (асинхронный скачиватель страниц)
- Веб-серверы (FastAPI и aiohttp прекрасно работают в async-режиме)
☝️ Важно понимать: асинхронность — это не многопоточность. Она не ускорит вашу математику или генерацию изображений. Но она незаменима там, где приложение тратит время на ожидание.
🎯 Вывод
Асинхронное программирование в Python — это не роскошь, а инструмент оптимизации. Особенно в сетевых задачах, где каждый миллисекундный выигрыш ускоряет приложение многократно.
Python дает вам отличные async-инструменты прямо из коробки:
Если вы уже писали на Python сетевые приложения — например, телеграм-бота, простенький HTTP-сервер или парсер сайтов — вы, скорее всего, сталкивались с тем, что программа "зависает", когда ждет ответа от сервера. В этот момент Python… просто сидит и ждет. Чай себе заваривает. А вы — греете процессор на холостом ходу.
Но можно по-другому. Асинхронно. И вот в тот момент, когда вы впервые запускаете свой async-код и видите, как он в разы быстрее перебирает запросы, возникает ощущение магии. На самом деле, никакой магии — просто асинхронность.
🧠 Что происходит в обычной программе?
Вот пример кода, написанного "по старинке":
import requests
def fetch_data():
response = requests.get('https://httpbin.org/delay/2')
return response.text
for _ in range(5):
print(fetch_data())
Каждый запрос “зависает” на 2 секунды (сайт задерживает выдачу ответа). Всего уходит около 10 секунд. Никакой многозадачности — каждая следующая итерация ждет завершения предыдущей.
📈 А теперь асинхронный подход:
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, 'https://httpbin.org/delay/2') for _ in range(5)]
results = await asyncio.gather(*tasks)
for r in results:
print(r)
asyncio.run(main())
Вся пятерка запросов отрабатывает… параллельно!
aiohttp
и asyncio
позволяют не простаивать в ожидании ответа, а запускать другие задачи.⏱ Результат? Вместо 10 секунд — примерно 2 секунды. Гениально просто.
⚙️ Почему это работает?
Асинхронная модель основана на событийном цикле. Когда вы делаете операцию ввода-вывода — например, ждете данные из интернета — интерпретатор Python освобождает поток и занимается другими задачами. Этот подход отлично работает, когда операций ввода-вывода много, а процессор почти не загружен — типичная ситуация для сетевых приложений.
Монолитный
requests
и другие синхронные библиотеки всегда блокируют выполнение, пока не получат результат. Async дает экономию времени, когда у вас десятки, сотни запросов, и каждый из них можно запускать одновременно.💥 Где использовать асинхронность?
- Боты и чат-приложения (async-сервер получает и отправляет сообщения без задержек)
- Web API-клиенты (одновременно дергаем десятки API)
- Парсеры сайтов (асинхронный скачиватель страниц)
- Веб-серверы (FastAPI и aiohttp прекрасно работают в async-режиме)
☝️ Важно понимать: асинхронность — это не многопоточность. Она не ускорит вашу математику или генерацию изображений. Но она незаменима там, где приложение тратит время на ожидание.
🎯 Вывод
Асинхронное программирование в Python — это не роскошь, а инструмент оптимизации. Особенно в сетевых задачах, где каждый миллисекундный выигрыш ускоряет приложение многократно.
Python дает вам отличные async-инструменты прямо из коробки:
asyncio
, aiohttp
, FastAPI
, httpx
и другие. Освоив их однажды, вы больше никогда не захотите возвращаться к бесконечным “зависаниям”.