Если вы когда-либо хотели дать своим пользователям доступ к сервисам вроде Google, GitHub или Facebook, не заставляя их вбивать пароли — добро пожаловать в мир OAuth.
OAuth (Open Authorization) — это стандарт авторизации, который позволяет получать ограниченный доступ к защищённым ресурсам без передачи логина и пароля. Звучит круто? Ещё бы. И сегодня мы посмотрим, как реализовать OAuth-аутентификацию на Python, используя библиотеку Authlib — одна из самых простых и эффективных для этой задачи.
📦 Установка библиотек:
Мы будем строить небольшой Flask-сервер, через который пользователь сможет авторизоваться через, например, GitHub.
⚙️ Базовая настройка Flask и OAuth-клиента
Вам нужно будет взять значения
🌐 Маршруты Flask:
🔐 Что происходит:
1. Пользователь заходит на
2. Перебрасывается на страницу авторизации GitHub.
3. После логина возвращается на
4. Приложение получает access token и может запрашивать данные.
Теперь, не зная паролей пользователей, мы получаем информацию о них. Максимально безопасно. А если access token протухнет — можно запросить новый, не беспокоя пользователя.
🧠 Полезный совет:
Храните
🔄 А если нужен другой провайдер? Просто поменяйте ссылки и scopes. Authlib поддерживает Google, Facebook, Twitter и даже кастомные OAuth-провайдеры.
В целом, настройка OAuth через Authlib не такая уж и страшная, как может показаться на первый взгляд. Зато какой уровень удобства и безопасности! Если ваше приложение хоть как-то связано с пользователями — OAuth точно стоит освоить.
OAuth (Open Authorization) — это стандарт авторизации, который позволяет получать ограниченный доступ к защищённым ресурсам без передачи логина и пароля. Звучит круто? Ещё бы. И сегодня мы посмотрим, как реализовать OAuth-аутентификацию на Python, используя библиотеку Authlib — одна из самых простых и эффективных для этой задачи.
📦 Установка библиотек:
pip install Authlib Flask
Мы будем строить небольшой Flask-сервер, через который пользователь сможет авторизоваться через, например, GitHub.
⚙️ Базовая настройка Flask и OAuth-клиента
from flask import Flask, redirect, url_for, session
from authlib.integrations.flask_client import OAuth
app = Flask(__name__)
app.secret_key = 'your-secret-key'
oauth = OAuth(app)
github = oauth.register(
name='github',
client_id='GITHUB_CLIENT_ID',
client_secret='GITHUB_CLIENT_SECRET',
access_token_url='https://github.com/login/oauth/access_token',
authorize_url='https://github.com/login/oauth/authorize',
api_base_url='https://api.github.com/',
client_kwargs={'scope': 'user:email'},
)
Вам нужно будет взять значения
client_id
и client_secret
в настройках своего GitHub OAuth-приложения.🌐 Маршруты Flask:
@app.route('/')
def homepage():
return '<a href="/login">Login with GitHub</a>'
@app.route('/login')
def login():
redirect_uri = url_for('authorize', _external=True)
return github.authorize_redirect(redirect_uri)
@app.route('/authorize')
def authorize():
token = github.authorize_access_token()
resp = github.get('user', token=token)
user_info = resp.json()
session['user'] = user_info
return f"Hello, {user_info['login']}!"
🔐 Что происходит:
1. Пользователь заходит на
/login
.2. Перебрасывается на страницу авторизации GitHub.
3. После логина возвращается на
/authorize
.4. Приложение получает access token и может запрашивать данные.
Теперь, не зная паролей пользователей, мы получаем информацию о них. Максимально безопасно. А если access token протухнет — можно запросить новый, не беспокоя пользователя.
🧠 Полезный совет:
Храните
client_id
и client_secret
не в коде, а в переменных окружения:import os
client_id = os.getenv('GITHUB_CLIENT_ID')
client_secret = os.getenv('GITHUB_CLIENT_SECRET')
🔄 А если нужен другой провайдер? Просто поменяйте ссылки и scopes. Authlib поддерживает Google, Facebook, Twitter и даже кастомные OAuth-провайдеры.
В целом, настройка OAuth через Authlib не такая уж и страшная, как может показаться на первый взгляд. Зато какой уровень удобства и безопасности! Если ваше приложение хоть как-то связано с пользователями — OAuth точно стоит освоить.
🎨 Простейшие графические редакторы с использованием библиотеки 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. Начните с мини-графредактора, а дальше — рамки только в вашем воображении.
🎨 Создание собственных графических эффектов для веб-приложений с помощью Python
Python и графика — казалось бы, редкое сочетание, особенно когда речь идёт о вебе. Но всё меняется, когда на сцену выходит библиотека Pillow и генерация изображений на лету. Сегодня мы разберёмся, как с помощью Python можно создавать крутые графические эффекты и динамически генерировать изображения для веба — от градиентов и шумов до генеративного дизайна.
Начнём с основ: Pillow — это форк знаменитой библиотеки PIL (Python Imaging Library). Она позволяет создавать и редактировать изображения прямо на сервере. Например, вы можете генерировать карточки товаров, баннеры, визуальные паттерны, аватары или фоновые текстуры прямо в момент запроса.
Установка:
Теперь представим, что вы хотите создать динамический градиентный фон с шумом для веб-обложки. Вот простой пример:
Результат — красивый градиент с шумом, который отлично подойдёт для стильного фона на лендинге или карточке товара. И, что важно, он уникален при каждом запуске.
Теперь представим, что вы хотите добавить эффект текста с тенью:
Вы можете встроить это изображение прямо в ваше веб-приложение на Flask:
Этот эндпоинт отдаёт сгенерированное изображение при каждом запросе. Можно играться с параметрами URL (например, передавать текст или цвет) и получать кастомизированные баннеры под каждого пользователя. Даже SVG или фильтры постобработки можно внедрять — хотя они больше подойдут для frontend'а, но и на сервере через библиотеки Cairo или Wand (обёртка ImageMagick) можно зажечь любую искру фантазии.
Создание графических эффектов на Python — это не просто утилита, это целое направление, открывающее двери к генеративному дизайну, динамической персонализации и неожиданному креативу прямо со стороны бэкенда. И, что немаловажно, всё работает быстро, просто и контролируемо.
Такой подход идеально подойдёт для тех, кто хочет поднять визуальный уровень своего веб-приложения без тяжёлой артиллерии вроде Photoshop или Canvas API. А ведь это только начало.
Python и графика — казалось бы, редкое сочетание, особенно когда речь идёт о вебе. Но всё меняется, когда на сцену выходит библиотека Pillow и генерация изображений на лету. Сегодня мы разберёмся, как с помощью Python можно создавать крутые графические эффекты и динамически генерировать изображения для веба — от градиентов и шумов до генеративного дизайна.
Начнём с основ: Pillow — это форк знаменитой библиотеки PIL (Python Imaging Library). Она позволяет создавать и редактировать изображения прямо на сервере. Например, вы можете генерировать карточки товаров, баннеры, визуальные паттерны, аватары или фоновые текстуры прямо в момент запроса.
Установка:
pip install pillow
Теперь представим, что вы хотите создать динамический градиентный фон с шумом для веб-обложки. Вот простой пример:
from PIL import Image, ImageDraw
import random
width, height = 800, 400
image = Image.new("RGB", (width, height))
draw = ImageDraw.Draw(image)
for y in range(height):
color = (int(255 * (y / height)), 100, 200)
draw.line([(0, y), (width, y)], fill=color)
for _ in range(10000):
x = random.randint(0, width - 1)
y = random.randint(0, height - 1)
noise_color = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
image.putpixel((x, y), noise_color)
image.save("gradient_noise.png")
Результат — красивый градиент с шумом, который отлично подойдёт для стильного фона на лендинге или карточке товара. И, что важно, он уникален при каждом запуске.
Теперь представим, что вы хотите добавить эффект текста с тенью:
from PIL import ImageFont
font = ImageFont.truetype("arial.ttf", 48)
text = "Hello, Web!"
draw.text((52, 152), text, font=font, fill=(0,0,0)) # Shadow
draw.text((50, 150), text, font=font, fill=(255,255,255)) # Main text
Вы можете встроить это изображение прямо в ваше веб-приложение на Flask:
from flask import Flask, send_file
import io
app = Flask(__name__)
@app.route("/banner")
def banner():
img = Image.new("RGB", (600, 200), color=(30, 30, 30))
draw = ImageDraw.Draw(img)
draw.text((50, 80), "Welcome!", fill=(255, 255, 255))
buf = io.BytesIO()
img.save(buf, format="PNG")
buf.seek(0)
return send_file(buf, mimetype='image/png')
Этот эндпоинт отдаёт сгенерированное изображение при каждом запросе. Можно играться с параметрами URL (например, передавать текст или цвет) и получать кастомизированные баннеры под каждого пользователя. Даже SVG или фильтры постобработки можно внедрять — хотя они больше подойдут для frontend'а, но и на сервере через библиотеки Cairo или Wand (обёртка ImageMagick) можно зажечь любую искру фантазии.
Создание графических эффектов на Python — это не просто утилита, это целое направление, открывающее двери к генеративному дизайну, динамической персонализации и неожиданному креативу прямо со стороны бэкенда. И, что немаловажно, всё работает быстро, просто и контролируемо.
Такой подход идеально подойдёт для тех, кто хочет поднять визуальный уровень своего веб-приложения без тяжёлой артиллерии вроде Photoshop или Canvas API. А ведь это только начало.
👍1
Если вы работаете с данными, то, скорее всего, не раз сталкивались с необходимостью обрабатывать большие объемы информации: забирать файлы из хранилищ, преобразовывать их, фильтровать, грузить в базу данных. Весь этот процесс называется ETL — Extract, Transform, Load. И если делать его вручную — это скучно, ошибкоопасно и просто не масштабируется. А вот автоматизация… вот здесь всё действительно интересно.
Сегодня расскажу, как совместить мощную визуальную платформу Apache Nifi и Python-скрипты, чтобы создать эффективный, гибкий и надёжный ETL-пайплайн. Да, можно обойтись одним Python, но Nifi значительно упрощает потоковую обработку данных, а Python добавляет нужной гибкости.
🔧 Что такое Apache Nifi?
Это open-source инструмент от Apache для автоматической передачи и обработки данных в режиме реального времени. Работает через веб-интерфейс: «нажал, соединил, запустил». Поддерживает более 300 встроенных процессоров (загрузка FTP, HTTP, базы данных, фильтрация, устранение дубликатов и т.д.)
Теперь представьте: у вас есть CSV-файлы с данными, ежедневно падающие на удалённый сервер, и вам нужно:
- Скачивать их
- Преобразовывать
- Загружать в PostgreSQL
Разберём, как это сделать с помощью Apache Nifi и Python.
🛠 Пример пайплайна с Python-скриптом в Nifi
1. Используем процессор GetFile или ListFTP + FetchFile, чтобы забирать CSV.
2. Далее применим ExecuteScript — здесь встроим Python-обработчик CSV.
3. Последний шаг — PutDatabaseRecord для загрузки данных в базу.
💡 Пример Python-обработки CSV в ExecuteScript:
⚠️ Важно: ExecuteScript использует Jython, где модулей вроде pandas нет, но для базовых трансформаций его хватает. Для более сложных случаев можно использовать ExecuteStreamCommand, передав управление вашему внешнему Python 3 скрипту.
🎯 Заключение
Apache Nifi позволяет «рисовать» ETL-пайплайны — быстро, надёжно, наглядно. Python, в свою очередь, расширяет возможности и точечно применим там, где встроенных средств Nifi не хватает. Вместе эти инструменты дают почти безграничную мощность в обработке данных. В следующем посте покажу, как подключить мониторинг и логирование пайплайна, чтобы спать спокойно.
Сегодня расскажу, как совместить мощную визуальную платформу Apache Nifi и Python-скрипты, чтобы создать эффективный, гибкий и надёжный ETL-пайплайн. Да, можно обойтись одним Python, но Nifi значительно упрощает потоковую обработку данных, а Python добавляет нужной гибкости.
🔧 Что такое Apache Nifi?
Это open-source инструмент от Apache для автоматической передачи и обработки данных в режиме реального времени. Работает через веб-интерфейс: «нажал, соединил, запустил». Поддерживает более 300 встроенных процессоров (загрузка FTP, HTTP, базы данных, фильтрация, устранение дубликатов и т.д.)
Теперь представьте: у вас есть CSV-файлы с данными, ежедневно падающие на удалённый сервер, и вам нужно:
- Скачивать их
- Преобразовывать
- Загружать в PostgreSQL
Разберём, как это сделать с помощью Apache Nifi и Python.
🛠 Пример пайплайна с Python-скриптом в Nifi
1. Используем процессор GetFile или ListFTP + FetchFile, чтобы забирать CSV.
2. Далее применим ExecuteScript — здесь встроим Python-обработчик CSV.
3. Последний шаг — PutDatabaseRecord для загрузки данных в базу.
💡 Пример Python-обработки CSV в ExecuteScript:
# Используется Jython (Python 2.7), встроенный в Nifi
import csv
import io
from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
flow_file = session.get()
if flow_file is not None:
try:
content = IOUtils.toString(session.read(flow_file), StandardCharsets.UTF_8)
reader = csv.DictReader(io.StringIO(content))
transformed = []
for row in reader:
row['full_name'] = f"{row['first_name']} {row['last_name']}"
row['age'] = int(row['age'])
transformed.append(row)
output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=transformed[0].keys())
writer.writeheader()
writer.writerows(transformed)
flow_file = session.write(flow_file, lambda out: out.write(output.getvalue().encode('utf-8')))
session.transfer(flow_file, REL_SUCCESS)
except Exception as e:
session.transfer(flow_file, REL_FAILURE)
⚠️ Важно: ExecuteScript использует Jython, где модулей вроде pandas нет, но для базовых трансформаций его хватает. Для более сложных случаев можно использовать ExecuteStreamCommand, передав управление вашему внешнему Python 3 скрипту.
🎯 Заключение
Apache Nifi позволяет «рисовать» ETL-пайплайны — быстро, надёжно, наглядно. Python, в свою очередь, расширяет возможности и точечно применим там, где встроенных средств Nifi не хватает. Вместе эти инструменты дают почти безграничную мощность в обработке данных. В следующем посте покажу, как подключить мониторинг и логирование пайплайна, чтобы спать спокойно.
Когда программисты слышат «машинное обучение» и «мобильные приложения» в одном предложении, у многих в голове сразу возникает вопрос: «А как это вообще возможно с Python?» Ведь Python — язык высокоуровневый, не самый быстрый, а приложения должны быть легкими и быстрыми! Но — спешу вас удивить — Python отлично подходит для подготовки и даже частичной интеграции моделей машинного обучения в мобильные приложения. Главное — грамотно подключить инструменты.
Сегодня разберём, как внедрить ML-модели, написанные на Python, в мобильное приложение: от обучения до запуска на смартфоне.
📦 Подготовка модели в Python
Нам понадобится
Итак, модель обучена и сохранена. Но
🔧 Конвертация модели для мобильного применения
В случае с TensorFlow используем
Теперь у нас есть файл
📱 Внедрение в Android-приложение
Если вы используете Android (например, пишете UI на Kotlin), то подключаете TensorFlow Lite через зависимость
А что если хочется Python'а и на уровне мобильного приложения? Есть выход — Kivy.
🐍 Kivy — Python на мобильных
Kivy позволяет создавать кроссплатформенные мобильные приложения на Python. С ML-моделями он тоже дружит, но есть нюанс: модели должны быть в легковесном формате, желательно
Пример сопровождения модели в Kivy:
Запустить такой код можно на Android, если собрать приложение используя
🎯 Итог
Python отлично подходит для подготовки и оптимизации ML-моделей. После этого вы можете:
- Преобразовать модель в
- Использовать фреймворки (Kivy, BeeWare) для написания мобильных приложений на Python с ML;
- Или же организовать backend на Flask/FastAPI, а мобильное приложение будет слать туда запросы (но это уже другая история).
Так что, машинное обучение и мобильная разработка — совместимы. А Python — это не только про расчёты, но и про реальные приложения прямо в ваших карманах.
Сегодня разберём, как внедрить ML-модели, написанные на Python, в мобильное приложение: от обучения до запуска на смартфоне.
📦 Подготовка модели в Python
Нам понадобится
scikit-learn
, tensorflow
или pytorch
— выбор зависит от задачи. Допустим, мы хотим обучить простую модель для распознавания рукописных цифр с помощью TensorFlow
.import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
(x_train, y_train), (x_test, y_test) = mnist.load_data()
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(128, activation='relu'),
Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)
model.save('mnist_model.h5')
Итак, модель обучена и сохранена. Но
.h5
— не совсем мобильный формат. Дальше — оптимизация.🔧 Конвертация модели для мобильного применения
В случае с TensorFlow используем
TensorFlow Lite
— формат, специально созданный для мобильных и встроенных устройств.import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model('mnist_model.h5')
tflite_model = converter.convert()
with open('mnist_model.tflite', 'wb') as f:
f.write(tflite_model)
Теперь у нас есть файл
mnist_model.tflite
, который можно встроить в Android или iOS-приложение.📱 Внедрение в Android-приложение
Если вы используете Android (например, пишете UI на Kotlin), то подключаете TensorFlow Lite через зависимость
implementation "org.tensorflow:tensorflow-lite:2.x.y"
, кладёте .tflite
файл в assets и вызываете модель прямо из Java/Kotlin-кода. Это уже не Python, но вся машинная логика осталась нашей.А что если хочется Python'а и на уровне мобильного приложения? Есть выход — Kivy.
🐍 Kivy — Python на мобильных
Kivy позволяет создавать кроссплатформенные мобильные приложения на Python. С ML-моделями он тоже дружит, но есть нюанс: модели должны быть в легковесном формате, желательно
.tflite
или сериализованные NumPy-объекты.Пример сопровождения модели в Kivy:
import numpy as np
import tensorflow as tf
from kivy.app import App
from kivy.uix.label import Label
class MLApp(App):
def build(self):
interpreter = tf.lite.Interpreter(model_path="mnist_model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# dummy input
input_data = np.random.rand(1, 28, 28).astype(np.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
prediction = interpreter.get_tensor(output_details[0]['index'])
return Label(text=f'Prediction: {np.argmax(prediction)}')
MLApp().run()
Запустить такой код можно на Android, если собрать приложение используя
buildozer
.🎯 Итог
Python отлично подходит для подготовки и оптимизации ML-моделей. После этого вы можете:
- Преобразовать модель в
tflite
и встроить её в нативные Android/iOS-приложения;- Использовать фреймворки (Kivy, BeeWare) для написания мобильных приложений на Python с ML;
- Или же организовать backend на Flask/FastAPI, а мобильное приложение будет слать туда запросы (но это уже другая история).
Так что, машинное обучение и мобильная разработка — совместимы. А 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. Работать с сериями изображений с его помощью — одно удовольствие, а возможности практически безграничны.
Привет! Сегодня мы окунемся в мир ORM — Object-Relational Mapping. Звучит как заклинание, да? На деле, всё проще: ORM позволяет работать с базой данных, как будто вы работаете с обычными объектами Python. Больше никаких SQL-запросов, только чистый, приятный код. Давайте разберемся, как это работает и чем нам это может помочь.
Представьте, вы пишете блог (как я!) и хотите хранить информацию о статьях: заголовок, текст, дату публикации. Можно, конечно, вручную конструировать SQL-запросы, трекать подключения к базе, писать конвертацию типов. А можно — просто использовать ORM, например, SQLAlchemy или Peewee.
Начнем с SQLAlchemy — одного из самых популярных вариантов.
Устанавливаем:
Создадим простое приложение:
Готово! Мы только что:
- Создали таблицу в SQLite без единого SQL-запроса
- Вставили новую запись в базу данных
- Использовали объектно-ориентированный подход
Если вы знакомы с Django, то знаете, что у него свой встроенный ORM — возможно, один из лучших для быстрого старта. Но если вы хотите легковесность и контроль — SQLAlchemy и Peewee (более минималистичный вариант) вас приятно удивят.
Для сравнения — как выглядит чтение данных:
Или обновление:
Да, ORM не избавляет от необходимости думать о данных, транзакциях и индексации. Но он делает код чище, безопаснее и легче в сопровождении.
Совет: используйте ORM везде, где важна читаемость и масштабируемость проекта. Особенно, если вы работаете в команде — структура кода будет единообразной, и новому участнику будет проще разобраться.
В следующий раз расскажу, как связать несколько таблиц и делать отношения "один-ко-многим" в ORM-стиле. А пока — протестируйте код выше, поэкспериментируйте. Ведь лучший способ выучить ORM — начать его действительно использовать!
Представьте, вы пишете блог (как я!) и хотите хранить информацию о статьях: заголовок, текст, дату публикации. Можно, конечно, вручную конструировать SQL-запросы, трекать подключения к базе, писать конвертацию типов. А можно — просто использовать ORM, например, SQLAlchemy или Peewee.
Начнем с SQLAlchemy — одного из самых популярных вариантов.
Устанавливаем:
pip install sqlalchemy
Создадим простое приложение:
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.orm import declarative_base, sessionmaker
from datetime import datetime
Base = declarative_base()
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
title = Column(String)
content = Column(String)
published_at = Column(DateTime, default=datetime.utcnow)
# Настраиваем соединение с SQLite
engine = create_engine('sqlite:///blog.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# Создаем и сохраняем пост
new_post = Post(title="My First ORM Post", content="ORMs make life easier!")
session.add(new_post)
session.commit()
Готово! Мы только что:
- Создали таблицу в SQLite без единого SQL-запроса
- Вставили новую запись в базу данных
- Использовали объектно-ориентированный подход
Если вы знакомы с Django, то знаете, что у него свой встроенный ORM — возможно, один из лучших для быстрого старта. Но если вы хотите легковесность и контроль — SQLAlchemy и Peewee (более минималистичный вариант) вас приятно удивят.
Для сравнения — как выглядит чтение данных:
posts = session.query(Post).filter(Post.title.like("%ORM%")).all()
for post in posts:
print(post.title, post.published_at)
Или обновление:
post = session.query(Post).first()
post.title = "Updated title"
session.commit()
Да, ORM не избавляет от необходимости думать о данных, транзакциях и индексации. Но он делает код чище, безопаснее и легче в сопровождении.
Совет: используйте ORM везде, где важна читаемость и масштабируемость проекта. Особенно, если вы работаете в команде — структура кода будет единообразной, и новому участнику будет проще разобраться.
В следующий раз расскажу, как связать несколько таблиц и делать отношения "один-ко-многим" в ORM-стиле. А пока — протестируйте код выше, поэкспериментируйте. Ведь лучший способ выучить ORM — начать его действительно использовать!
👍1
🔥 Как асинхронное программирование улучшает производительность сетевых приложений?
Если вы уже писали на 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
и другие. Освоив их однажды, вы больше никогда не захотите возвращаться к бесконечным “зависаниям”.🔥1
Если тебе когда-нибудь хотелось создать веб-приложение для анализа данных — и при этом не хочется влезать в мир JavaScript, HTML и CSS — то ты попал по адресу. Сегодня я расскажу про Plotly Dash: мощный инструмент для построения интерактивных аналитических приложений, полностью на Python. Звучит как магия? Это потому, что почти так и есть.
Plotly Dash — это библиотека на Python, которая позволяет создавать веб-приложения для визуализации и анализа данных с помощью кода, который выглядит как обычный скрипт. Без необходимости знать фронтенд. Интерфейс строится на основе компонент React, но всё спрятано под капотом — ты просто создаёшь layout и указываешь логику в виде Python-функций.
Рассмотрим простейший пример.
Допустим, нам нужно создать дашборд, который показывает, как меняется синусоида в зависимости от частоты, которую выбирает пользователь. Для этого нам нужно установить Dash:
Теперь код приложения:
Это полноценное веб-приложение. На странице пользователь может регулировать ползунок, меняющий частоту синусоиды, и график будет обновляться в реальном времени. Всё это — с минимальным количеством кода.
Dash особенно мощен, когда тебе нужно построить интерактивные фильтры данных, таблицы, выпадающие списки, вкладки, загрузку CSV-файлов — для всего этого уже есть готовые компоненты. Соединение Plotly (интерактивные графики) и Dash (веб-интерфейс плюс логика) делает библиотеку отличным выбором для Data Science.
Дополнительно Dash легко разворачивается на Heroku, Render или любой другой платформе с поддержкой Python. А значит, ты можешь делать прототипы, MVP и небольшие демонстрационные проекты без громоздких фреймворков.
Совет от меня: начни с чего-то простого. Например, загрузка CSV-файла и построение графика по выбранным колонкам. Это поможет понять принципы связи layout-компонентов и callback-функций. А дальше — хоть предиктивная аналитика с машинным обучением!
Dash не заменит тебе полноценную веб-разработку, но если ты Python-разработчик, которому нужно быстро визуализировать данные — это просто находка.
Plotly Dash — это библиотека на Python, которая позволяет создавать веб-приложения для визуализации и анализа данных с помощью кода, который выглядит как обычный скрипт. Без необходимости знать фронтенд. Интерфейс строится на основе компонент React, но всё спрятано под капотом — ты просто создаёшь layout и указываешь логику в виде Python-функций.
Рассмотрим простейший пример.
Допустим, нам нужно создать дашборд, который показывает, как меняется синусоида в зависимости от частоты, которую выбирает пользователь. Для этого нам нужно установить Dash:
pip install dash
Теперь код приложения:
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import numpy as np
import plotly.graph_objs as go
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Dynamic Sine Wave Plot"),
dcc.Slider(
id='frequency-slider',
min=1,
max=10,
step=0.5,
value=1,
marks={i: str(i) for i in range(1, 11)}
),
dcc.Graph(id='sine-graph')
])
@app.callback(
Output('sine-graph', 'figure'),
Input('frequency-slider', 'value')
)
def update_graph(frequency):
x_vals = np.linspace(0, 2 * np.pi, 500)
y_vals = np.sin(frequency * x_vals)
figure = go.Figure(
data=[
go.Scatter(x=x_vals, y=y_vals, mode='lines', name='Sine Wave')
],
layout=go.Layout(
title=f"Sine Wave with Frequency {frequency}",
xaxis={'title': 'x'},
yaxis={'title': 'sin(f*x)'}
)
)
return figure
if __name__ == '__main__':
app.run_server(debug=True)
Это полноценное веб-приложение. На странице пользователь может регулировать ползунок, меняющий частоту синусоиды, и график будет обновляться в реальном времени. Всё это — с минимальным количеством кода.
Dash особенно мощен, когда тебе нужно построить интерактивные фильтры данных, таблицы, выпадающие списки, вкладки, загрузку CSV-файлов — для всего этого уже есть готовые компоненты. Соединение Plotly (интерактивные графики) и Dash (веб-интерфейс плюс логика) делает библиотеку отличным выбором для Data Science.
Дополнительно Dash легко разворачивается на Heroku, Render или любой другой платформе с поддержкой Python. А значит, ты можешь делать прототипы, MVP и небольшие демонстрационные проекты без громоздких фреймворков.
Совет от меня: начни с чего-то простого. Например, загрузка CSV-файла и построение графика по выбранным колонкам. Это поможет понять принципы связи layout-компонентов и callback-функций. А дальше — хоть предиктивная аналитика с машинным обучением!
Dash не заменит тебе полноценную веб-разработку, но если ты Python-разработчик, которому нужно быстро визуализировать данные — это просто находка.
❤1🔥1
🔍 Создание и настройка сред тестирования для Python проектов
Если вы только начинаете путешествие по миру Python, рано или поздно столкнётесь с необходимостью тестировать свой код. И вот тут начинается магия: автоматические тесты, виртуальные окружения, покрытие кода — всё это становится неотъемлемой частью любого серьёзного проекта. Сегодня разберём, как создать и настроить удобную и гибкую среду тестирования, с которой приятно работать.
🎯 Начнем с основ: виртуальное окружение
Работаем только в virtual environment. Это спасёт вас от конфликтов зависимостей и превращения системы в «зоопарк» библиотек.
Создаём окружение:
Теперь все зависимости будут установлены локально. Отлично!
🧪 Подключаем pytest
Для начала работы с тестами советую использовать
Создайте файл с тестами
Запуск всех тестов:
🔥 Бонус: автопоиск файлов с тестами, читаемые отчёты и подсветка ошибок прямо в терминале!
📦 Организация структуры проекта
Хорошая структура проекта помогает тестированию:
В
📈 Настройка покрытия кода
Хотите знать, сколько строк вашего кода реально покрыто тестами? Добавьте
Результат вас удивит: будет показано, какие строки были выполнены, а какие – нет. Это незаменимо для отслеживания «мертвого» кода.
🔧 Прогон тестов перед коммитом
Используйте pre-commit hooks, чтобы тесты автоматически запускались перед отправкой коммитов. Добавим файл
Устанавливаем и активируем:
Теперь каждая попытка зафиксировать изменения будет сопровождаться автоматической проверкой формата и, при желании, запуском тестов.
📚 Резюмируем
- Используйте
-
- Настройте
- Подключайте
- Используйте
Грамотно выстроенная среда тестирования экономит часы отладки, делает проект масштабируемым и увеличивает ваше доверие к собственному коду. Успехов! 🚀
Если вы только начинаете путешествие по миру Python, рано или поздно столкнётесь с необходимостью тестировать свой код. И вот тут начинается магия: автоматические тесты, виртуальные окружения, покрытие кода — всё это становится неотъемлемой частью любого серьёзного проекта. Сегодня разберём, как создать и настроить удобную и гибкую среду тестирования, с которой приятно работать.
🎯 Начнем с основ: виртуальное окружение
Работаем только в virtual environment. Это спасёт вас от конфликтов зависимостей и превращения системы в «зоопарк» библиотек.
Создаём окружение:
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
Теперь все зависимости будут установлены локально. Отлично!
🧪 Подключаем pytest
Для начала работы с тестами советую использовать
pytest
. Он лаконичен, мощен и популярен в сообществе. Установим его:pip install pytest
Создайте файл с тестами
test_math_utils.py
:def add(a, b):
return a + b
def test_add_positive_numbers():
assert add(2, 3) == 5
def test_add_negative_numbers():
assert add(-1, -1) == -2
Запуск всех тестов:
pytest
🔥 Бонус: автопоиск файлов с тестами, читаемые отчёты и подсветка ошибок прямо в терминале!
📦 Организация структуры проекта
Хорошая структура проекта помогает тестированию:
my_project/
│
├── src/
│ └── core.py
├── tests/
│ └── test_core.py
├── requirements.txt
└── pytest.ini
В
pytest.ini
можно настраивать поведение pytest
:[pytest]
testpaths = tests
python_files = test_*.py
📈 Настройка покрытия кода
Хотите знать, сколько строк вашего кода реально покрыто тестами? Добавьте
pytest-cov
:pip install pytest-cov
pytest --cov=src tests/
Результат вас удивит: будет показано, какие строки были выполнены, а какие – нет. Это незаменимо для отслеживания «мертвого» кода.
🔧 Прогон тестов перед коммитом
Используйте pre-commit hooks, чтобы тесты автоматически запускались перед отправкой коммитов. Добавим файл
.pre-commit-config.yaml
:repos:
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.3.2
hooks:
- id: prettier
- repo: https://github.com/pre-commit/mirrors-pylint
rev: v2.13.9
hooks:
- id: pylint
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v1.6.0
hooks:
- id: autopep8
Устанавливаем и активируем:
pip install pre-commit
pre-commit install
Теперь каждая попытка зафиксировать изменения будет сопровождаться автоматической проверкой формата и, при желании, запуском тестов.
📚 Резюмируем
- Используйте
venv
для изоляции сред-
pytest
– ваш друг в мире тестов- Настройте
pytest.ini
под структуру проекта- Подключайте
pytest-cov
для анализа покрытия- Используйте
pre-commit
для автоматизации проверокГрамотно выстроенная среда тестирования экономит часы отладки, делает проект масштабируемым и увеличивает ваше доверие к собственному коду. Успехов! 🚀
Название: Сценарий оживает — пишем интерактивные фильмы на Python
Интерактивное кино — это где пользователь чувствует себя режиссёром. Помните Black Mirror: Bandersnatch? Или игры от Telltale? Хочешь такого же эффекта, но на Python? Легко.
В этом посте я расскажу, как создавать интерактивные сценарии, с поддержкой переходов, ветвлений и даже "оцифровки" сюжета — структуру, по которой можно визуализировать сюжет как дерево.
Ключевая идея — представить сценарий в виде графа, где каждая сцена — это узел, а выбор — это ребро. Для начала создадим структуру сцены.
📦 Основной ингредиент: простая модель сцены
Каждая сцена включает текст и возможные выборы. Попробуем построить мини-историю.
Теперь сделаем функцию, которая будет прогонять пользователя через историю.
И запускаем:
📊 Теперь — оцифровка: дерево выбора
Допустим, ты хочешь отрисовать структуру сюжета. Здесь пригодится модуль graphviz.
Установим его:
Теперь можно визуализировать сюжет:
В результате получим PNG-диаграмму с графом всех сцен. Это удобно, когда сценарий становится большим и запутанным.
🧩 Идеи для расширения:
- Добавить условные переходы в зависимости от состояния игрока (что он уже выбрал ранее).
- Сохранять прохождения.
- Автоматическая генерация HTML/Web-интерфейса.
- Генерация сценария из JSON или YAML — удобно авторам без знаний Python.
🎬 Вывод
На Python легко создать интерактивную историю, точнее — движок для неё. Но самый главный ингредиент — твоя фантазия. Python в этом случае — режиссёрская панель и монтажный отсек одновременно. Такое кино ты нигде не купишь — ты его пишешь сам.
Интерактивное кино — это где пользователь чувствует себя режиссёром. Помните Black Mirror: Bandersnatch? Или игры от Telltale? Хочешь такого же эффекта, но на Python? Легко.
В этом посте я расскажу, как создавать интерактивные сценарии, с поддержкой переходов, ветвлений и даже "оцифровки" сюжета — структуру, по которой можно визуализировать сюжет как дерево.
Ключевая идея — представить сценарий в виде графа, где каждая сцена — это узел, а выбор — это ребро. Для начала создадим структуру сцены.
📦 Основной ингредиент: простая модель сцены
class Scene:
def __init__(self, text, choices):
self.text = text
self.choices = choices # {'choice_text': next_scene_key}
Каждая сцена включает текст и возможные выборы. Попробуем построить мини-историю.
story = {
"start": Scene(
"Ты просыпаешься в лесу. На севере слышны шаги. На юге видишь свет костра.",
{
"Пойти на север": "north_path",
"Пойти на юг": "campfire"
}
),
"north_path": Scene(
"Ты натыкаешься на странного мужчину с топором.",
{
"Поздороваться": "talk_man",
"Спрятаться": "hide"
}
),
"campfire": Scene(
"Около костра сидят путешественники. Они машут тебе рукой.",
{
"Присоединиться": "join_travelers",
"Убежать в лес": "run_away"
}
),
# ...
}
Теперь сделаем функцию, которая будет прогонять пользователя через историю.
def play(story, start_key):
current_key = start_key
while current_key in story:
scene = story[current_key]
print(f"\n{scene.text}\n")
for i, choice in enumerate(scene.choices.keys(), 1):
print(f"{i}. {choice}")
try:
index = int(input("Выбери действие: ")) - 1
choice_text = list(scene.choices.keys())[index]
current_key = scene.choices[choice_text]
except (IndexError, ValueError):
print("Неверный выбор. Попробуй снова.")
И запускаем:
if __name__ == "__main__":
play(story, "start")
📊 Теперь — оцифровка: дерево выбора
Допустим, ты хочешь отрисовать структуру сюжета. Здесь пригодится модуль graphviz.
Установим его:
pip install graphviz
Теперь можно визуализировать сюжет:
from graphviz import Digraph
def export_story_graph(story, filename="story"):
dot = Digraph()
for key, scene in story.items():
dot.node(key, scene.text[:30] + ("..." if len(scene.text) > 30 else ""))
for choice_text, next_key in scene.choices.items():
dot.edge(key, next_key, label=choice_text)
dot.render(filename, format='png', cleanup=True)
export_story_graph(story)
В результате получим PNG-диаграмму с графом всех сцен. Это удобно, когда сценарий становится большим и запутанным.
🧩 Идеи для расширения:
- Добавить условные переходы в зависимости от состояния игрока (что он уже выбрал ранее).
- Сохранять прохождения.
- Автоматическая генерация HTML/Web-интерфейса.
- Генерация сценария из JSON или YAML — удобно авторам без знаний Python.
🎬 Вывод
На Python легко создать интерактивную историю, точнее — движок для неё. Но самый главный ингредиент — твоя фантазия. Python в этом случае — режиссёрская панель и монтажный отсек одновременно. Такое кино ты нигде не купишь — ты его пишешь сам.