Когда слышишь «3D-графика на Python», первое, что приходит в голову — это что-то громоздкое и сложное, с кучей зависимостей и километрами кода. Однако библиотека Pyglet ломает этот стереотип: она позволяет создавать 3D-сцены прямо в Python без плясок с бубном и внешних движков.
Pyglet — это чистая библиотека на Python для создания мультимедийных приложений, таких как игры и визуализации. Она предоставляет доступ к OpenGL напрямую, что делает её отличным инструментом для работы с 3D.
Начнем с самого простого — создадим окно и отрисуем внутри него 3D-объект. Для этого нам понадобится pyglet и немного OpenGL-магии, которая прячется внутри модуля pyglet.gl.
Пример создания окна и вращающегося куба:
Запуская этот код, вы увидите вращающийся во все стороны цветной куб. Секрет прост: pyglet предоставляет окно и событийный цикл, OpenGL отвечает за математику и отрисовку граней.
Важно: Pyglet не делает абстракций уровнем выше, как это делают движки — если хочешь тени, освещение, текстуры или камеры — всё ты делаешь своими руками. Это и плюс, и вызов: ты лучше понимаешь, что происходит «под капотом», но должен быть готов разобраться с OpenGL-терминами вроде матриц и вершин.
Pyglet также хорош тем, что позволяет подключать шрифты, музыку, текстуры и многое другое буквально одной строкой. Хочешь навесить текстуру на куб? Просто подгрузи изображение через pyglet.image и добавь его при рендере.
Итог. Pyglet — удобная песочница для 3D-экспериментов, особенно если ты хочешь изучить основы OpenGL, не вылезая из Python. Не самый быстрый путь к полноценной игре, но отличный шаг к пониманию графики изнутри.
Pyglet — это чистая библиотека на Python для создания мультимедийных приложений, таких как игры и визуализации. Она предоставляет доступ к OpenGL напрямую, что делает её отличным инструментом для работы с 3D.
Начнем с самого простого — создадим окно и отрисуем внутри него 3D-объект. Для этого нам понадобится pyglet и немного OpenGL-магии, которая прячется внутри модуля pyglet.gl.
Пример создания окна и вращающегося куба:
import pyglet
from pyglet.gl import *
import math
window = pyglet.window.Window(800, 600, "3D Cube with Pyglet", resizable=True)
rotation = 0
@window.event
def on_draw():
global rotation
window.clear()
# Настройка 3D-проекции
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(65, window.width / window.height, 0.1, 100)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -5)
glRotatef(rotation, 1, 1, 0)
draw_cube()
def draw_cube():
glBegin(GL_QUADS)
# Front face (red)
glColor3f(1, 0, 0)
glVertex3f(-1, -1, 1)
glVertex3f( 1, -1, 1)
glVertex3f( 1, 1, 1)
glVertex3f(-1, 1, 1)
# Back face (green)
glColor3f(0, 1, 0)
glVertex3f(-1, -1, -1)
glVertex3f(-1, 1, -1)
glVertex3f( 1, 1, -1)
glVertex3f( 1, -1, -1)
# Top face (blue)
glColor3f(0, 0, 1)
glVertex3f(-1, 1, -1)
glVertex3f(-1, 1, 1)
glVertex3f( 1, 1, 1)
glVertex3f( 1, 1, -1)
# Bottom face (yellow)
glColor3f(1, 1, 0)
glVertex3f(-1, -1, -1)
glVertex3f( 1, -1, -1)
glVertex3f( 1, -1, 1)
glVertex3f(-1, -1, 1)
# Right face (cyan)
glColor3f(0, 1, 1)
glVertex3f( 1, -1, -1)
glVertex3f( 1, 1, -1)
glVertex3f( 1, 1, 1)
glVertex3f( 1, -1, 1)
# Left face (magenta)
glColor3f(1, 0, 1)
glVertex3f(-1, -1, -1)
glVertex3f(-1, -1, 1)
glVertex3f(-1, 1, 1)
glVertex3f(-1, 1, -1)
glEnd()
def update(dt):
global rotation
rotation += 50 * dt
pyglet.clock.schedule(update)
pyglet.app.run()
Запуская этот код, вы увидите вращающийся во все стороны цветной куб. Секрет прост: pyglet предоставляет окно и событийный цикл, OpenGL отвечает за математику и отрисовку граней.
Важно: Pyglet не делает абстракций уровнем выше, как это делают движки — если хочешь тени, освещение, текстуры или камеры — всё ты делаешь своими руками. Это и плюс, и вызов: ты лучше понимаешь, что происходит «под капотом», но должен быть готов разобраться с OpenGL-терминами вроде матриц и вершин.
Pyglet также хорош тем, что позволяет подключать шрифты, музыку, текстуры и многое другое буквально одной строкой. Хочешь навесить текстуру на куб? Просто подгрузи изображение через pyglet.image и добавь его при рендере.
Итог. Pyglet — удобная песочница для 3D-экспериментов, особенно если ты хочешь изучить основы OpenGL, не вылезая из Python. Не самый быстрый путь к полноценной игре, но отличный шаг к пониманию графики изнутри.
🔥2👍1🥰1
Когда вы пишете веб-приложение на Python, рано или поздно возникает вопрос: «А как всё это запускать в продакшене?». Просто сказать
Что такое Gunicorn?
Gunicorn (Green Unicorn) — это предварительно форкающий WSGI-сервер. Простыми словами, он запускает основное приложение и создаёт дочерние процессы (воркеры), что обеспечивает параллельную обработку запросов. Это даёт выигрыш в производительности и отказоустойчивости.
Начнём с установки:
Допустим, у вас простой Flask-приложение:
Чтобы запустить это приложение через Gunicorn:
Здесь
По умолчанию Gunicorn запускает 1 воркер. Можно указать больше:
На сколько воркеров стоит ориентироваться?
Рекомендуется: количество ядер × 2 + 1. Например, если у вас 2 ядра, оптимально использовать 5 воркеров. Это обеспечит хорошую параллельность.
Gunicorn поддерживает разные типы воркеров. Например,
Добавим логирование (чтобы понимать, что происходит при сбоях и нагрузке):
Для надёжной работы в продакшене Gunicorn лучше не запускать как самостоятельный процесс, а обернуть его в процесс-менеджер. Например,
Конфигурировать Gunicorn можно двумя способами:
1. Через аргументы командной строки (как выше);
2. Через Python-конфигурационный файл:
А запустить всё так:
Если у вас Django-проект, запуск чуть другой:
Итого: Gunicorn — это ключевой компонент деплоя Python-приложения. Он лёгкий, быстрый, гибкий и замечательно работает с современными фреймворками. Настроив его один раз, можно забыть о приставке “dev server” и перейти на серьёзный уровень — стабильный, отказоустойчивый, боевой.
python my_app.py
— недостаточно. Нужен настоящий сервер, способный обрабатывать множество запросов, управлять процессами и не «падать» при первом чихе. Тут на сцену выходит Gunicorn — подходящий инструмент для развёртывания серверных приложений на Python, особенно тех, что используют WSGI (например, Flask или Django).Что такое Gunicorn?
Gunicorn (Green Unicorn) — это предварительно форкающий WSGI-сервер. Простыми словами, он запускает основное приложение и создаёт дочерние процессы (воркеры), что обеспечивает параллельную обработку запросов. Это даёт выигрыш в производительности и отказоустойчивости.
Начнём с установки:
pip install gunicorn
Допустим, у вас простой Flask-приложение:
# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "Hello from Gunicorn!"
Чтобы запустить это приложение через Gunicorn:
gunicorn app:app
Здесь
app:app
означает: импортируй из модуля app
переменную app
, которая представляет собой Flask-приложение.По умолчанию Gunicorn запускает 1 воркер. Можно указать больше:
gunicorn app:app --workers 4
На сколько воркеров стоит ориентироваться?
Рекомендуется: количество ядер × 2 + 1. Например, если у вас 2 ядра, оптимально использовать 5 воркеров. Это обеспечит хорошую параллельность.
Gunicorn поддерживает разные типы воркеров. Например,
sync
— по умолчанию, gevent
— для асинхронных задач:gunicorn app:app -k gevent --workers 4
Добавим логирование (чтобы понимать, что происходит при сбоях и нагрузке):
gunicorn app:app --access-logfile access.log --error-logfile error.log
Для надёжной работы в продакшене Gunicorn лучше не запускать как самостоятельный процесс, а обернуть его в процесс-менеджер. Например,
systemd
(если речь идёт о Linux-сервере), или вы можете использовать supervisor
.Конфигурировать Gunicorn можно двумя способами:
1. Через аргументы командной строки (как выше);
2. Через Python-конфигурационный файл:
# gunicorn_config.py
bind = "0.0.0.0:8000"
workers = 4
accesslog = "access.log"
errorlog = "error.log"
А запустить всё так:
gunicorn app:app -c gunicorn_config.py
Если у вас Django-проект, запуск чуть другой:
gunicorn myproject.wsgi:application
Итого: Gunicorn — это ключевой компонент деплоя Python-приложения. Он лёгкий, быстрый, гибкий и замечательно работает с современными фреймворками. Настроив его один раз, можно забыть о приставке “dev server” и перейти на серьёзный уровень — стабильный, отказоустойчивый, боевой.
Контейнеризация с Docker: как Python-проекты обретают суперсилу
Если вы когда-либо разворачивали Python-проект "голыми руками" — на сыром сервере, с настройкой окружения, системными пакетами, разрушающими зависимости, и мистическими багами, которые возникают только в "бою", то Docker для вас — как спасательный круг для утопающего.
Контейнеризация — это не просто модный термин, а реальное решение извечных проблем с "у меня работает". И для Python-проектов она особенно ценна.
Представим типичную ситуацию: у команды есть несколько микросервисов на Python — один парсит веб-сайты, второй обрабатывает данные, третий отдает API. Каждый использует разные версии библиотек, системных зависимостей, переменных окружения. Проблема номер один — воспроизводимость. Без Docker попытка развернуть всё это на сервере превращается в танцы с бубном.
С Docker каждый микросервис получает своё изолированное окружение. У вас есть Dockerfile — рецепт, по которому собирается образ: нужная версия Python, точные зависимости из requirements.txt, переменные, команды запуска. Команда docker build — и у вас готовый артефакт, который будет одинаково работать на разработке, в CI/CD или на проде.
Пример:
// Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD "python", "main.py"
Это — вся магия запуска Python-приложения в изоляции. Никакого "где искать libxml2", никаких конфликтов версий pip или глобального Python.
Ещё одна суперспособность Docker — масштабирование. Например, для обработки миллионов задач вы запускаете несколько контейнеров с celery worker'ами. Они берут задачи из Redis, обрабатывают в параллели, и масштабируются по нагрузке. Не нужен отдельный сервер, просто запускаете больше контейнеров — и всё.
Также Docker незаменим в CI/CD. При пуше в Git ваш пайплайн может собрать Docker-образ, прогнать тесты в контейнере, и задеплоить его на сервер или в Kubernetes. Весь путь — от кода до продакшена — автоматизирован и стабилен.
А как насчет разработки? Docker позволяет создать docker-compose.yml, где в одном файле описываются все сервисы: база данных, бекенд, очереди, фронт — всё запускается одной командой docker-compose up. Нужно PostgreSQL для разработки? Просто добавьте:
services:
db:
image: postgres:14
environment:
POSTGRESUSER: user
POSTGRESPASSWORD: pass
И вы работаете с полноценной базой в пару кликов.
Контейнеры решают задачи не только инфраструктуры, но и тестирования. Вы можете запускать юнит-тесты в izолированном контейнере, чтобы быть уверенным: никакие артефакты системы не влияют на поведение кода.
И наконец, контейнеризация — это комфорт и уверенность. Ваш Python-код живёт в предсказуемом, управляемом окружении. Вы точно знаете, как он будет работать, и можете легко обновлять, переносить и масштабировать свой проект.
Docker стал неотъемлемой частью современного Python-стека. Он не делает код лучше, но делает работу с кодом — быстрее, стабильнее и безопаснее. А это уже немалый шаг к зрелой разработке.
Если вы когда-либо разворачивали Python-проект "голыми руками" — на сыром сервере, с настройкой окружения, системными пакетами, разрушающими зависимости, и мистическими багами, которые возникают только в "бою", то Docker для вас — как спасательный круг для утопающего.
Контейнеризация — это не просто модный термин, а реальное решение извечных проблем с "у меня работает". И для Python-проектов она особенно ценна.
Представим типичную ситуацию: у команды есть несколько микросервисов на Python — один парсит веб-сайты, второй обрабатывает данные, третий отдает API. Каждый использует разные версии библиотек, системных зависимостей, переменных окружения. Проблема номер один — воспроизводимость. Без Docker попытка развернуть всё это на сервере превращается в танцы с бубном.
С Docker каждый микросервис получает своё изолированное окружение. У вас есть Dockerfile — рецепт, по которому собирается образ: нужная версия Python, точные зависимости из requirements.txt, переменные, команды запуска. Команда docker build — и у вас готовый артефакт, который будет одинаково работать на разработке, в CI/CD или на проде.
Пример:
// Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD "python", "main.py"
Это — вся магия запуска Python-приложения в изоляции. Никакого "где искать libxml2", никаких конфликтов версий pip или глобального Python.
Ещё одна суперспособность Docker — масштабирование. Например, для обработки миллионов задач вы запускаете несколько контейнеров с celery worker'ами. Они берут задачи из Redis, обрабатывают в параллели, и масштабируются по нагрузке. Не нужен отдельный сервер, просто запускаете больше контейнеров — и всё.
Также Docker незаменим в CI/CD. При пуше в Git ваш пайплайн может собрать Docker-образ, прогнать тесты в контейнере, и задеплоить его на сервер или в Kubernetes. Весь путь — от кода до продакшена — автоматизирован и стабилен.
А как насчет разработки? Docker позволяет создать docker-compose.yml, где в одном файле описываются все сервисы: база данных, бекенд, очереди, фронт — всё запускается одной командой docker-compose up. Нужно PostgreSQL для разработки? Просто добавьте:
services:
db:
image: postgres:14
environment:
POSTGRESUSER: user
POSTGRESPASSWORD: pass
И вы работаете с полноценной базой в пару кликов.
Контейнеры решают задачи не только инфраструктуры, но и тестирования. Вы можете запускать юнит-тесты в izолированном контейнере, чтобы быть уверенным: никакие артефакты системы не влияют на поведение кода.
И наконец, контейнеризация — это комфорт и уверенность. Ваш Python-код живёт в предсказуемом, управляемом окружении. Вы точно знаете, как он будет работать, и можете легко обновлять, переносить и масштабировать свой проект.
Docker стал неотъемлемой частью современного Python-стека. Он не делает код лучше, но делает работу с кодом — быстрее, стабильнее и безопаснее. А это уже немалый шаг к зрелой разработке.
Иногда меньше — это больше. Особенно, когда речь заходит о матрицах, в которых абсолютное большинство элементов равны нулю. Такие матрицы называются разреженными (sparse), и если хранить их как обычные двумерные массивы в NumPy, то можно легко потратить кучу памяти впустую. Вот тут на сцену выходит библиотека SciPy с модулем scipy.sparse — быстрым, компактным и удобным инструментом для работы с разреженными матрицами.
Разреженные матрицы часто встречаются в машинном обучении, при обработке графов, работе с текстами в виде "мешка слов" и моделировании физических процессов. В SciPy есть несколько форматов хранения разреженных матриц. Рассмотрим самые ходовые.
Начнем с Compressed Sparse Row (CSR) — формат, удобный для быстрого умножения матриц и извлечения строк.
Пример:
Вывод:
Для сравнения, обычная матрица размером 10000x10000 потребляет почти 800 МБ памяти. А если в ней всего 0.01% ненулевых элементов, то разреженное представление на тех же данных использует минимум ресурсов.
Следующий формат — Compressed Sparse Column (CSC), оптимален для извлечения по столбцам. Создать такую матрицу можно просто вызвав
Еще один полезный тип — LIL (List of Lists). Он хорош для пошагового добавления элементов:
После наполнения её удобно конвертировать в CSR или CSC для дальнейших операций:
Хотите работать с матрицами как с NumPy? Легко. Многие операции поддерживаются напрямую: сложение, умножение, транспонирование, извлечение подматриц. Но важно помнить: несмотря на общее API, sparse-матрицы — это не обычные ndarray. Прямой доступ к элементам может быть менее производителен, а вызовы типа
Узнать плотность матрицы просто:
Если результат меньше 0.01 — вы точно всё делаете правильно.
SciPy позволяет даже решать системы линейных уравнений и выполнять разложение sparse-матриц. Например:
Зачем использовать SciPy для редких данных? Потому что компактность, эффективность и удобство — это ключ к хорошей производительности. Когда ваш датасет вмещается целиком в кэш процессора, даже самые тяжёлые задачи идут налегке.
Так что если ваши матрицы — это в основном нули, не спешите забивать ими память. SciPy.sparse превращает недостаток в преимущество.
Разреженные матрицы часто встречаются в машинном обучении, при обработке графов, работе с текстами в виде "мешка слов" и моделировании физических процессов. В SciPy есть несколько форматов хранения разреженных матриц. Рассмотрим самые ходовые.
Начнем с Compressed Sparse Row (CSR) — формат, удобный для быстрого умножения матриц и извлечения строк.
Пример:
from scipy.sparse import csr_matrix
data = [1, 2, 3]
rows = [0, 1, 2]
cols = [2, 0, 1]
sparse_matrix = csr_matrix((data, (rows, cols)), shape=(3, 3))
print(sparse_matrix)
Вывод:
(0, 2) 1
(1, 0) 2
(2, 1) 3
Для сравнения, обычная матрица размером 10000x10000 потребляет почти 800 МБ памяти. А если в ней всего 0.01% ненулевых элементов, то разреженное представление на тех же данных использует минимум ресурсов.
Следующий формат — Compressed Sparse Column (CSC), оптимален для извлечения по столбцам. Создать такую матрицу можно просто вызвав
.tocsc()
у CSR:csc_example = sparse_matrix.tocsc()
Еще один полезный тип — LIL (List of Lists). Он хорош для пошагового добавления элементов:
from scipy.sparse import lil_matrix
matrix_lil = lil_matrix((3, 3))
matrix_lil[0, 1] = 5
matrix_lil[1, 2] = 8
print(matrix_lil)
После наполнения её удобно конвертировать в CSR или CSC для дальнейших операций:
matrix_final = matrix_lil.tocsr()
Хотите работать с матрицами как с NumPy? Легко. Многие операции поддерживаются напрямую: сложение, умножение, транспонирование, извлечение подматриц. Но важно помнить: несмотря на общее API, sparse-матрицы — это не обычные ndarray. Прямой доступ к элементам может быть менее производителен, а вызовы типа
.toarray()
тянут действительную матрицу в память — осторожно с большими массивами!Узнать плотность матрицы просто:
density = sparse_matrix.count_nonzero() / (sparse_matrix.shape[0] * sparse_matrix.shape[1])
print(f"Density: {density:.6f}")
Если результат меньше 0.01 — вы точно всё делаете правильно.
SciPy позволяет даже решать системы линейных уравнений и выполнять разложение sparse-матриц. Например:
from scipy.sparse.linalg import spsolve
A = csr_matrix([[3, 0, 1], [0, 4, 0], [1, 0, 2]])
b = [5, 8, 5]
x = spsolve(A, b)
print(x)
Зачем использовать SciPy для редких данных? Потому что компактность, эффективность и удобство — это ключ к хорошей производительности. Когда ваш датасет вмещается целиком в кэш процессора, даже самые тяжёлые задачи идут налегке.
Так что если ваши матрицы — это в основном нули, не спешите забивать ими память. SciPy.sparse превращает недостаток в преимущество.
Когда речь заходит об анализе временных рядов в Python, вездесущий pandas вызывает заслуженное уважение. Базовые возможности, такие как преобразование даты формата строки в datetime, или ресемплирование данных — уже почти рефлекс у каждого начинающего аналитика. Но сегодня я хочу показать вам кое-что посерьезнее. Pandas умеет гораздо больше, и это может по-настоящему сократить вам время и расширить горизонт возможностей.
Допустим, у нас есть DataFrame с погодными данными:
Первое, на что стоит обратить внимание — это метод
Но зачастую данные нужно агрегировать. Вот тут вступает
Вроде бы ничего нового. Но вы знали, что можно использовать нестандартные правила частоты? Например,
А теперь магия: скользящие окна. Метод
Обратите внимание: начиная с pandas 1.2 можно задавать окно в формате времени, не только в числах. Это даёт гибкость: окно “7 дней назад” будет учитывать фактические интервалы, а не просто 7 строк.
Идём глубже. Предположим, вы анализируете временной ряд с пропущенными значениями. В pandas есть умные способы заполнения:
Интерполяция по времени — гораздо лучше "затыкания дыр" средним. Она учитывает временные интервалы, что важно для равномерности.
А теперь маленький шедевр: работа с временными “offsets”. Например, мы хотим сдвинуть данные на два месяца вперёд:
Не просто сдвинуть по индексам — а сместить даты! Это особенно удобно при сравнении "текущих" и "прошлогодних" метрик.
Финальный штрих —
и
Эти методы облегчат задачу, когда нужно быстро вытащить записи только за рабочие часы или точно в полдень.
Pandas — не просто инструмент для таблиц. Это полноценный движок анализа данных по времени, скрывающий под капотом куда больше, чем кажется. Настройка частот, смещения, агрегирования, скользящие окна — всё это можно комбинировать для создания точных и наглядных аналитических инструментов. И в этом кроется сила.
Допустим, у нас есть DataFrame с погодными данными:
import pandas as pd
df = pd.read_csv('weather.csv', parse_dates=['timestamp'], index_col='timestamp')
Первое, на что стоит обратить внимание — это метод
.asfreq()
для смены частоты без усреднения. Например, если у нас почасовые данные, а мы хотим просто увидеть дневные “срезы”:daily_df = df.asfreq('D')
Но зачастую данные нужно агрегировать. Вот тут вступает
.resample()
— он похож на .groupby()
, но для времени:mean_temp_per_day = df['temperature'].resample('D').mean()
Вроде бы ничего нового. Но вы знали, что можно использовать нестандартные правила частоты? Например,
'W-MON'
даст недельную агрегацию с понедельника:weekly_data = df.resample('W-MON').agg({'temperature': 'max', 'humidity': 'mean'})
А теперь магия: скользящие окна. Метод
.rolling()
— это ваш билет в мир сглаживания и анализа трендов:df['temp_7d_avg'] = df['temperature'].rolling(window='7D').mean()
Обратите внимание: начиная с pandas 1.2 можно задавать окно в формате времени, не только в числах. Это даёт гибкость: окно “7 дней назад” будет учитывать фактические интервалы, а не просто 7 строк.
Идём глубже. Предположим, вы анализируете временной ряд с пропущенными значениями. В pandas есть умные способы заполнения:
df['temperature'] = df['temperature'].interpolate(method='time')
Интерполяция по времени — гораздо лучше "затыкания дыр" средним. Она учитывает временные интервалы, что важно для равномерности.
А теперь маленький шедевр: работа с временными “offsets”. Например, мы хотим сдвинуть данные на два месяца вперёд:
df_shifted = df.shift(periods=2, freq='M')
Не просто сдвинуть по индексам — а сместить даты! Это особенно удобно при сравнении "текущих" и "прошлогодних" метрик.
Финальный штрих —
.between_time()
и .at_time()
. Когда вы работаете с данными по минутам или часам и хотите анализировать, например, только дневное время активности:daytime_df = df.between_time('09:00', '18:00')
и
df_at_noon = df.at_time('12:00')
Эти методы облегчат задачу, когда нужно быстро вытащить записи только за рабочие часы или точно в полдень.
Pandas — не просто инструмент для таблиц. Это полноценный движок анализа данных по времени, скрывающий под капотом куда больше, чем кажется. Настройка частот, смещения, агрегирования, скользящие окна — всё это можно комбинировать для создания точных и наглядных аналитических инструментов. И в этом кроется сила.
Привет! Сегодня мы с вами разберем, как с помощью Python и мощного сетевого инструмента Scapy создать простое, но функциональное приложение для мониторинга сети. Этот инструмент стоит того, чтобы познакомиться с ним поближе: он позволяет захватывать, анализировать и даже генерировать сетевые пакеты. А главное — делать это в пару строк кода.
Что такое Scapy? Это библиотека, написанная на Python, которая дает полный контроль над сетевыми пакетами. Она позволяет легко писать собственные снифферы, сканеры и даже фреймы для тестирования безопасности. Нам же сегодня нужен сниффер — простой монитор сетевого трафика.
Устанавливается Scapy командой:
pip install scapy
Теперь перейдем к делу. Представим, что нам нужно создать программу, которая будет "слушать" наш сетевой интерфейс и выводить информацию о каждом проходящем TCP-пакете. Вот базовый пример:
from scapy.all import sniff, IP, TCP
def processpacket(packet):
if packet.haslayer(IP) and packet.haslayer(TCP):
ipsrc = packetIP.src
ipdst = packet[IP].dst
portsrc = packetTCP.sport
portdst = packet[TCP].dport
print(f"TCP Packet: {ipsrc}:{portsrc} -> {ipdst}:{portdst}")
sniff(filter="tcp", prn=processpacket, store=0)
Что здесь происходит:
- sniff — основная функция для захвата пакетов.
- filter="tcp" — захватываем только TCP-пакеты (можно задавать любой pcap-фильтр: например, "udp", "icmp", "port 80").
- prn=processpacket — указываем функцию, которая будет вызываться для каждого пакета.
- store=0 — не сохраняем пакеты в память, чтобы избежать утечек при длительной работе.
Функция processpacket проверяет, содержит ли пакет уровни IP и TCP, и если да — выводит адреса отправителя и получателя, а также порты.
А теперь немного улучшений. Допустим, мы хотим видеть только трафик HTTP. Вспомним, что стандартный порт HTTP — 80. Добавим проверку на это:
def processpacket(packet):
if packet.haslayer(IP) and packet.haslayer(TCP):
portdst = packetTCP.dport
if portdst == 80:
ipsrc = packetIP.src
ipdst = packet[IP].dst
print(f"HTTP request from {ipsrc} to {ipdst}")
Хотим ещё круче? Добавим логгирование в файл, чтобы потом можно было проанализировать происходящее:
import logging
logging.basicConfig(filename="netmon.log", level=logging.INFO)
def processpacket(packet):
if packet.haslayer(IP) and packet.haslayer(TCP):
ipsrc = packet[IP].src
ipdst = packetIP.dst
portsrc = packet[TCP].sport
portdst = packetTCP.dport
logentry = f"{ipsrc}:{portsrc} -> {ipdst}:{portdst}"
logging.info(logentry)
Так мы получаем файл netmon.log, в котором накапливается информация обо всех TCP-соединениях.
Scapy дает гораздо больше, чем просто мониторинг. Можно парсить DNS-запросы, определять операционные системы, делать ARP-сканы, захватывать пароли — всё это в пределах одной библиотеки.
Наш мониторинг пока базовый, но даёт отличную основу для развития: вы можете строить систему оповещений, графики активности или даже мини firewall. Главное — не забывайте, что захват трафика на чужих сетях без разрешения незаконен! Используйте Scapy с умом и по назначению.
На этом всё — до встречи в следующем посте!
Что такое Scapy? Это библиотека, написанная на Python, которая дает полный контроль над сетевыми пакетами. Она позволяет легко писать собственные снифферы, сканеры и даже фреймы для тестирования безопасности. Нам же сегодня нужен сниффер — простой монитор сетевого трафика.
Устанавливается Scapy командой:
pip install scapy
Теперь перейдем к делу. Представим, что нам нужно создать программу, которая будет "слушать" наш сетевой интерфейс и выводить информацию о каждом проходящем TCP-пакете. Вот базовый пример:
from scapy.all import sniff, IP, TCP
def processpacket(packet):
if packet.haslayer(IP) and packet.haslayer(TCP):
ipsrc = packetIP.src
ipdst = packet[IP].dst
portsrc = packetTCP.sport
portdst = packet[TCP].dport
print(f"TCP Packet: {ipsrc}:{portsrc} -> {ipdst}:{portdst}")
sniff(filter="tcp", prn=processpacket, store=0)
Что здесь происходит:
- sniff — основная функция для захвата пакетов.
- filter="tcp" — захватываем только TCP-пакеты (можно задавать любой pcap-фильтр: например, "udp", "icmp", "port 80").
- prn=processpacket — указываем функцию, которая будет вызываться для каждого пакета.
- store=0 — не сохраняем пакеты в память, чтобы избежать утечек при длительной работе.
Функция processpacket проверяет, содержит ли пакет уровни IP и TCP, и если да — выводит адреса отправителя и получателя, а также порты.
А теперь немного улучшений. Допустим, мы хотим видеть только трафик HTTP. Вспомним, что стандартный порт HTTP — 80. Добавим проверку на это:
def processpacket(packet):
if packet.haslayer(IP) and packet.haslayer(TCP):
portdst = packetTCP.dport
if portdst == 80:
ipsrc = packetIP.src
ipdst = packet[IP].dst
print(f"HTTP request from {ipsrc} to {ipdst}")
Хотим ещё круче? Добавим логгирование в файл, чтобы потом можно было проанализировать происходящее:
import logging
logging.basicConfig(filename="netmon.log", level=logging.INFO)
def processpacket(packet):
if packet.haslayer(IP) and packet.haslayer(TCP):
ipsrc = packet[IP].src
ipdst = packetIP.dst
portsrc = packet[TCP].sport
portdst = packetTCP.dport
logentry = f"{ipsrc}:{portsrc} -> {ipdst}:{portdst}"
logging.info(logentry)
Так мы получаем файл netmon.log, в котором накапливается информация обо всех TCP-соединениях.
Scapy дает гораздо больше, чем просто мониторинг. Можно парсить DNS-запросы, определять операционные системы, делать ARP-сканы, захватывать пароли — всё это в пределах одной библиотеки.
Наш мониторинг пока базовый, но даёт отличную основу для развития: вы можете строить систему оповещений, графики активности или даже мини firewall. Главное — не забывайте, что захват трафика на чужих сетях без разрешения незаконен! Используйте Scapy с умом и по назначению.
На этом всё — до встречи в следующем посте!
👍1
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-коду.
Вы когда-нибудь задумывались, зачем использовать язык R, если у вас уже есть Python? Или наоборот? Казалось бы, оба отлично справляются с анализом данных. Но вот в чём соль: Python — это универсальный инструмент, бог с ним, швейцарский нож программиста. А R — это математика на стероидах. Его богатые статистические возможности делают его настоящим кладом для сложного анализа. В этом посте я расскажу, как объединить оба языка, чтобы выжать максимум из каждого.
🐍 + 📊 = ❤️
Для интеграции Python и R существует несколько способов, но самые удобные и популярные — это использование библиотек rpy2 и Jupyter с R-клетками через ipython-magic. Начнём с rpy2.
📦 Установка:
Убедитесь, что R установлен в вашей системе, затем:
pip install rpy2
Теперь магия:
from rpy2 import robjects
robjects.r('x <- rnorm(100)')
robjects.r('meanx <- mean(x)')
meanx = robjects.r('meanx')[0]
print("Mean from R:", meanx)
Здесь мы генерируем данные в стиле R, вычисляем среднее и забираем его обратно в Python. Очень удобно, когда у вас есть мощные R-пакеты вроде 'caret', 'forecast' или 'ggplot2', но вы хотите оборачивать их в пайтоновских скриптах.
Хочется смешивать код без лишнего бойлера? Тогда пришло время познакомиться с IPython magic-командой %%R. Установите R-кернел:
R
> install.packages("IRkernel")
> IRkernel::installspec()
Теперь в Jupyter:
%loadext rpy2.ipython
А в самой ячейке:
%%R
x <- rnorm(100)
print(summary(x))
Да-да, просто пишете R-код в Python-ноутбуке. Удобство в чистом виде.
🔁 Передача переменных
Обмен данными между языками возможен. Из Python в R:
import numpy as np
from rpy2.robjects import numpy2ri
numpy2ri.activate()
data = np.random.normal(size=100)
robjects.globalenv['x'] = data
robjects.r('summary(x)')
И обратно:
meanr = robjects.r('mean(x)')0
print(meanr)
📊 Дополнительный бонус — визуализация. Например, используйте ggplot2:
robjects.r('''
library(ggplot2)
df <- data.frame(x=rnorm(100), y=rnorm(100))
p <- ggplot(df, aes(x=x, y=y)) + geompoint()
print(p)
''')
Такой подход отлично подходит, если вы уже строите пайплайны в Python, а кто-то в команде держится за проверенные R-инструменты. Или вы просто хотите построить точный статистический анализ без костылей.
Итог: интеграция Python и R — это не борьба за первенство, а мощный симбиоз. Используйте Python для автоматизации и потоков, а R — для глубоких аналитических выкопок. Вместе они могут гораздо больше.
🐍 + 📊 = ❤️
Для интеграции Python и R существует несколько способов, но самые удобные и популярные — это использование библиотек rpy2 и Jupyter с R-клетками через ipython-magic. Начнём с rpy2.
📦 Установка:
Убедитесь, что R установлен в вашей системе, затем:
pip install rpy2
Теперь магия:
from rpy2 import robjects
robjects.r('x <- rnorm(100)')
robjects.r('meanx <- mean(x)')
meanx = robjects.r('meanx')[0]
print("Mean from R:", meanx)
Здесь мы генерируем данные в стиле R, вычисляем среднее и забираем его обратно в Python. Очень удобно, когда у вас есть мощные R-пакеты вроде 'caret', 'forecast' или 'ggplot2', но вы хотите оборачивать их в пайтоновских скриптах.
Хочется смешивать код без лишнего бойлера? Тогда пришло время познакомиться с IPython magic-командой %%R. Установите R-кернел:
R
> install.packages("IRkernel")
> IRkernel::installspec()
Теперь в Jupyter:
%loadext rpy2.ipython
А в самой ячейке:
%%R
x <- rnorm(100)
print(summary(x))
Да-да, просто пишете R-код в Python-ноутбуке. Удобство в чистом виде.
🔁 Передача переменных
Обмен данными между языками возможен. Из Python в R:
import numpy as np
from rpy2.robjects import numpy2ri
numpy2ri.activate()
data = np.random.normal(size=100)
robjects.globalenv['x'] = data
robjects.r('summary(x)')
И обратно:
meanr = robjects.r('mean(x)')0
print(meanr)
📊 Дополнительный бонус — визуализация. Например, используйте ggplot2:
robjects.r('''
library(ggplot2)
df <- data.frame(x=rnorm(100), y=rnorm(100))
p <- ggplot(df, aes(x=x, y=y)) + geompoint()
print(p)
''')
Такой подход отлично подходит, если вы уже строите пайплайны в Python, а кто-то в команде держится за проверенные R-инструменты. Или вы просто хотите построить точный статистический анализ без костылей.
Итог: интеграция Python и R — это не борьба за первенство, а мощный симбиоз. Используйте Python для автоматизации и потоков, а R — для глубоких аналитических выкопок. Вместе они могут гораздо больше.