🚀 Привет, питонисты! Готовы погрузиться в захватывающий мир тестирования параллельного и асинхронного кода? Пристегните ремни, мы отправляемся в путешествие по лабиринтам многопоточности и асинхронности!
Представьте, что ваш код – это оркестр в Мариинском театре. Каждый инструмент (поток или корутина) играет свою партию. А вы – дирижёр, который должен убедиться, что все звучит гармонично. Вот только как это сделать, когда все играют одновременно? 🎵 Давайте разберемся!
Первое правило тестирования параллельного кода: изолируйте тесты! Каждый тест должен быть как отдельная комната в звукоизолированной студии. Используйте моки и стабы, чтобы симулировать внешние зависимости. Вот пример с использованием unittest.mock:
from unittest.mock import patch
import asyncio
async def fetch_data(url):
# Реальный запрос к API
...
@patch('your_module.fetch_data')
async def test_process_data(mock_fetch):
mock_fetch.return_value = {'key': 'value'}
result = await process_data('http://api.example.com')
assert result == 'processed value'
Видите? Мы изолировали тест от реального API. Теперь он быстрый, как Усэйн Болт, и предсказуемый, как восход солнца! 🌅
Асинхронный код может быть непредсказуемым, как погода в Питере. Но ваши тесты должны быть стабильными, как гранитная набережная. Используйте семафоры, события и другие примитивы синхронизации, чтобы контролировать порядок выполнения. Вот пример с использованием asyncio.Event:
import asyncio
async def test_order_of_execution():
event = asyncio.Event()
results = []
async def task1():
await event.wait()
results.append(1)
async def task2():
results.append(2)
event.set()
await asyncio.gather(task1(), task2())
assert results == [2, 1]
Этот тест всегда будет проходить, даже если вы запустите его на компьютере, работающем на картофельной батарейке! 🥔⚡️
⏰ Установка таймаутов в тестах – это как страховка. Вы надеетесь, что она не понадобится, но лучше иметь ее под рукой. Вот как можно использовать таймауты в pytest:
import pytest
import asyncio
@pytest.mark.asyncio
async def test_long_running_task():
with pytest.raises(asyncio.TimeoutError):
await asyncio.wait_for(never_ending_task(), timeout=1.0)
Этот тест убедится, что ваша функция не зависнет, как старый Windows при запуске Crysis! 💻💥
В мире async/await фикстуры тоже должны быть асинхронными. Используйте async fixtures в pytest для подготовки и очистки тестового окружения. Вот пример:
import pytest
import asyncio
@pytest.fixture
async def database():
db = await create_database_connection()
yield db
await db.close()
@pytest.mark.asyncio
async def test_database_query(database):
result = await database.fetch('SELECT * FROM users')
assert len(result) > 0
Эта фикстура – как заботливая мама, которая готовит завтрак перед школой и убирает посуду после. Только вместо завтрака у нас база данных! 🍳🏫
🏎 Запуск тестов параллельно не только ускоряет процесс, но и помогает выявить проблемы с состоянием гонки. Используйте pytest-xdist, но будьте осторожны: убедитесь, что ваши тесты действительно независимы друг от друга. Вот команда для запуска:
pytest -n auto your_test_file.py
Это как устроить гонки Формулы-1 для ваших тестов. Победит самый быстрый и надежный код! 🏁
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Сделать ИГРУ на PYGAME Python | 2D Shooter | Персонаж, прицеливание
В этом видео мы начнем создавать 2д игру, а именно 2d shooter на библиотеке Pygame, используя Python. Суть будет в управлении персонажем с видом сверху, а так же наведении его при помощи мыши.
🔥 Подписывайся на наш Телеграм-канал про Python 🔥
🖇 https://…
🔥 Подписывайся на наш Телеграм-канал про Python 🔥
🖇 https://…
👍4
🌳 Привет, друзья-разработчики! Сегодня поговорим о мощном инструменте, который может превратить вас в настоящего код-волшебника – Abstract Syntax Trees (AST). Если вы когда-нибудь задумывались, как работают линтеры, компиляторы или автоматические рефакторинг-инструменты, то добро пожаловать в увлекательный мир синтаксических деревьев!
🔍 Представьте, что ваш код – это книга, а AST – её подробное содержание, где каждая глава, параграф и предложение аккуратно структурированы в древовидную форму. Каждый узел такого дерева представляет собой конструкцию вашего кода: функции, классы, операторы и даже отдельные переменные.
💡 В Python работа с AST стала намного проще благодаря встроенному модулю ast. Давайте разберем несколько практических примеров:
import ast
code = """
def calculate_sum(a, b):
result = a + b
print(f"Sum: {result}")
return result
"""
# Создаем AST
tree = ast.parse(code)
# Анализируем структуру
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
print(f"Найдена функция: {node.name}")
elif isinstance(node, ast.Name):
print(f"Найдена переменная: {node.id}")
🔧 Этот простой пример показывает, как мы можем "гулять" по дереву AST и находить различные элементы кода. Это базовый строительный блок для создания более сложных анализаторов.
class DebugTransformer(ast.NodeTransformer):
def visit_FunctionDef(self, node):
# Добавляем отладочный print в начало каждой функции
debug_print = ast.Expr(
value=ast.Call(
func=ast.Name(id='print', ctx=ast.Load()),
args=[ast.Constant(value=f"Вызов функции {node.name}")],
keywords=[]
)
)
node.body.insert(0, debug_print)
return node
# Применяем трансформацию
transformed = DebugTransformer().visit(tree)
class StringOptimizer(ast.NodeTransformer):
def visit_BinOp(self, node):
# Оптимизация конкатенации строк
if isinstance(node.op, ast.Add):
if isinstance(node.left, ast.Constant) and isinstance(node.right, ast.Constant):
if isinstance(node.left.value, str) and isinstance(node.right.value, str):
return ast.Constant(value=node.left.value + node.right.value)
return node
🎯 Этот оптимизатор находит конкатенацию строковых литералов и объединяет их на этапе компиляции, что улучшает производительность.
🔍 Вот несколько интересных применений AST в реальных проектах:
- Статический анализ безопасности: поиск потенциальных уязвимостей в коде
- Автоматическая документация: генерация документации на основе структуры кода
- Миграция кода: автоматическое обновление устаревших конструкций
- Оптимизация производительности: автоматический поиск неэффективных паттернов
💡 Продвинутый пример: Давайте создадим анализатор сложности кода:
class ComplexityAnalyzer(ast.NodeVisitor):
def __init__(self):
self.complexity = 0
def visit_If(self, node):
self.complexity += 1
self.generic_visit(node)
def visit_For(self, node):
self.complexity += 2
self.generic_visit(node)
def visit_While(self, node):
self.complexity += 2
self.generic_visit(node)
# Использование
analyzer = ComplexityAnalyzer()
analyzer.visit(tree)
print(f"Сложность кода: {analyzer.complexity}")
- Работа с типами данных и аннотациями через AST
- Создание собственных декораторов с помощью трансформации AST
- Оптимизация циклов и условных конструкций
- Анализ потока данных в программе
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
__slots__: Магия оптимизации памяти в Python 🎩 ✨
Привет, питонисты! Сегодня поговорим о крутой фиче Python, которая может значительно сократить потребление памяти вашими объектами. Да-да, речь о магическом атрибуте slots!
🤔 Для начала давайте разберемся, почему вообще возникла необходимость в slots. По умолчанию Python хранит атрибуты объектов в специальном словаре dict. Это удобно и гибко – можно добавлять новые атрибуты на лету. Но у такой роскоши есть цена: дополнительные накладные расходы на память.
💡 Представьте, что у вас миллион объектов класса User с парой атрибутов. Каждый такой объект тащит за собой словарь dict, а это прожорливая структура данных. И тут на сцену выходит наш герой – slots!
🚀 Что даёт нам slots? Вместо создания словаря Python выделяет фиксированный массив в памяти под указанные атрибуты. Это как переход от просторного лофта к компактной студии – места меньше, зато экономия налицо!
📊 Реальные цифры? Пожалуйста! На практике использование slots может сократить потребление памяти на 30-50% для простых объектов. А при работе с миллионами инстансов экономия становится более чем существенной.
🎯 Где это реально пригодится:
- В больших датасетах, где у вас тысячи/миллионы однотипных объектов
- В микросервисах, где важна оптимизация памяти
- В системах реального времени, где каждый байт на счету
- В долгоживущих процессах, обрабатывающих потоки данных
⚠️ Но есть и подводные камни:
- Нельзя добавлять новые атрибуты после определения класса
- Наследование работает не так прозрачно, как с обычными классами
- Некоторые метаклассы могут конфликтовать со slots
🔧 Пример реального применения:
💡 Про что стоит помнить: slots – это не волшебная таблетка. Используйте его там, где действительно важна оптимизация памяти и где вы уверены в неизменном наборе атрибутов.
🎉 Вот такая она – магия slots! Простая, но эффективная оптимизация, которая может здорово помочь в правильном контексте. Пользуйтесь с умом!
А вы уже используете slots в своих проектах? Делитесь опытом в комментариях! 👇
Привет, питонисты! Сегодня поговорим о крутой фиче Python, которая может значительно сократить потребление памяти вашими объектами. Да-да, речь о магическом атрибуте slots!
💡 Представьте, что у вас миллион объектов класса User с парой атрибутов. Каждый такой объект тащит за собой словарь dict, а это прожорливая структура данных. И тут на сцену выходит наш герой – slots!
# Без slots
class User:
def __init__(self, name, age):
self.name = name
self.age = age
# Со slots
class OptimizedUser:
__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
🚀 Что даёт нам slots? Вместо создания словаря Python выделяет фиксированный массив в памяти под указанные атрибуты. Это как переход от просторного лофта к компактной студии – места меньше, зато экономия налицо!
📊 Реальные цифры? Пожалуйста! На практике использование slots может сократить потребление памяти на 30-50% для простых объектов. А при работе с миллионами инстансов экономия становится более чем существенной.
🎯 Где это реально пригодится:
- В больших датасетах, где у вас тысячи/миллионы однотипных объектов
- В микросервисах, где важна оптимизация памяти
- В системах реального времени, где каждый байт на счету
- В долгоживущих процессах, обрабатывающих потоки данных
⚠️ Но есть и подводные камни:
- Нельзя добавлять новые атрибуты после определения класса
- Наследование работает не так прозрачно, как с обычными классами
- Некоторые метаклассы могут конфликтовать со slots
🔧 Пример реального применения:
class DataPoint:
__slots__ = ['timestamp', 'value', 'sensor_id']
def __init__(self, timestamp, value, sensor_id):
self.timestamp = timestamp
self.value = value
self.sensor_id = sensor_id
# Представьте, что таких объектов у вас миллионы
data_points = [DataPoint(time.time(), random.random(), i) for i in range(1_000_000)]
💡 Про что стоит помнить: slots – это не волшебная таблетка. Используйте его там, где действительно важна оптимизация памяти и где вы уверены в неизменном наборе атрибутов.
🎉 Вот такая она – магия slots! Простая, но эффективная оптимизация, которая может здорово помочь в правильном контексте. Пользуйтесь с умом!
А вы уже используете slots в своих проектах? Делитесь опытом в комментариях! 👇
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Стоит ли добавлять ограничения по патронам. Свапы оружия. Обоймы?
https://youtu.be/5NSH-sNi-6U
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Сделать ИГРУ на PYGAME Python | 2D Shooter | Стрельба, выстрел
В этом видео мы продолжим создавать 2д игру, а именно 2d shooter на библиотеке Pygame, используя Python. Сегодня мы добавим возможность стрельбы нашему персонажу. Добавим текстуру пули, поработаем с группами в пайгейм.
🔥 Подписывайся на наш Телеграм-канал…
🔥 Подписывайся на наш Телеграм-канал…
❤2
🐍 Привет, питонисты! Сегодня поговорим о настоящей магии в мире Python – метапрограммировании и динамическом создании функций.
Начнем с простого примера. Помните eval() и exec()? Это базовые инструменты метапрограммирования, но использовать их нужно с осторожностью – как острый нож в руках повара. Гораздо интереснее копнуть глубже!
def create_power_function(power):
def power_func(x):
return x ** power
return power_func
# Создаём функции на лету
square = create_power_function(2)
cube = create_power_function(3)
Но это только верхушка айсберга!
А вы знали, что можно создавать функции с динамическим количеством аргументов? Или генерировать методы классов на лету? Это как будто у вас есть 3D-принтер для кода! 🖨
import types
def create_dynamic_function(func_name, args, body):
namespace = {}
func_code = f"def {func_name}({', '.join(args)}):\n{body}"
exec(func_code, globals(), namespace)
return namespace[func_name]
# Магия в действии
greet = create_dynamic_function(
"greet",
["name"],
" return f'Привет, {name}!'"
)
Но помните – с большой силой приходит большая ответственность!
- При создании API с повторяющимися паттернами
- Для автоматизации рутинных задач
- При разработке фреймворков и библиотек
Отдельного внимания заслуживают декораторы – это ведь тоже метапрограммирование! Они как умные обёртки для функций, которые могут изменять их поведение. И да, их тоже можно создавать динамически!
Экспериментируйте, но не забывайте про читаемость кода – ваши коллеги скажут спасибо! 😉
P.S. Если вам понравилась статья, подписывайтесь на канал и делитесь своими магическими трюками в комментариях! 🎮
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Привет, питонисты! Сегодня поговорим о том, как сделать работу с путями в Python более элегантной и современной. Если вы всё ещё используете os.path, то пора двигаться вперёд!
Модуль pathlib появился в Python 3.4 и полностью изменил правила игры. Это как пересесть с древнего велосипеда на Tesla – всё те же базовые принципы, но насколько же удобнее!
- Объектно-ориентированный подход вместо строковых операций
- Кроссплатформенность из коробки
- Цепочки методов, которые читаются как поэзия
- Меньше кода, больше смысла
🎯 Давайте посмотрим на практические примеры:
# Старый подход с os.path
import os.path
file_path = os.path.join('data', 'users', 'config.json')
parent_dir = os.path.dirname(file_path)
file_name = os.path.basename(file_path)
# Новый подход с pathlib
from pathlib import Path
file_path = Path('data') / 'users' / 'config.json'
parent_dir = file_path.parent
file_name = file_path.name
path = Path('config.json')
if path.exists():
print('Файл существует!')Path('nested/directories/structure').mkdir(parents=True, exist_ok=True)# Найти все .py файлы в текущей директории
python_files = list(Path('.').glob('*.py'))
path = Path('document.pdf')
print(path.suffix) # .pdf
print(path.stem) # documentconfig_path = (Path.home() / 'projects' / 'app' / 'config.json')
if config_path.exists():
data = json.loads(config_path.read_text())
with Path('log.txt').open('w') as f:
f.write('Logging started')🤔 Когда стоит использовать os.path? Практически никогда! Разве что при работе с легаси-кодом или если вам нужны какие-то очень специфические операции с путями.
P.S. Не забудьте поставить лайк и поделиться постом с коллегами, которые всё ещё живут в мире os.path 😉😉😉😉
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
Forwarded from Новости Hostetski:)
Ограничения:
- Один бесплатный сервер на аккаунт.
- Заказы проходят ручную модерацию, поэтому время выдачи сервера может составлять до 24 часов.
Важно: Серверы останутся с вами на постоянной основе, пока вы их продлеваете (продление — бесплатно). Вы также можете докупить дополнительные ресурсы к этому тарифу, чтобы пользоваться им как полноценным сервером Cloud.
https://htk.ge/index.php?rp=/store/nat-cloud
и выберите тариф Cloud-F.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2❤🔥2
Что выдаст код выше?
Anonymous Quiz
25%
С++ the best
46%
Php the best
7%
Ничего
13%
Error
8%
Не знаю
👍3👎2❤1
Python Hub - сборище Питонистов
Photo
Разбор 👨💻
🔍 Что возвращает метод строки find()?
Самый быстрый способ это узнать — заглянуть в документацию Python. Согласно официальной документации, если подстрока не найдена, метод `find()` возвращает -1.
Теперь интересный момент: что произойдет, если преобразовать `-1` в логическое значение? Давайте проверим:
Как видите, -1 в Python считается истинным значением (True) при приведении к типу bool.
Самый быстрый способ это узнать — заглянуть в документацию Python. Согласно официальной документации, если подстрока не найдена, метод `find()` возвращает -1.
Теперь интересный момент: что произойдет, если преобразовать `-1` в логическое значение? Давайте проверим:
print(bool(-1)) # Результат: True
Как видите, -1 в Python считается истинным значением (True) при приведении к типу bool.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Создание CLI приложений с Click в Python: от простого к продвинутому 🚀
Привет, пайтонисты! 👋 Сегодня поговорим о том, как создавать крутые CLI-приложения с помощью Click. Если вам надоело писать бесконечные if'ы для обработки аргументов командной строки, то этот пост определенно для вас!
Начнем с того, почему вообще стоит использовать Click, а не встроенный argparse:
- Декораторный подход, который выглядит элегантно и интуитивно понятен
- Автоматическая генерация справки и сообщений об ошибках
- Вложенные команды из коробки
- Поддержка автодополнения в shell
Давайте посмотрим на простой, но реальный пример. Представим, что мы делаем утилиту для работы с файлами:
Крутая штука в Click – это то, как легко добавлять новые команды. Хотите добавить подкоманду? Просто навешиваете еще один декоратор! 🎯
А теперь лайфхак, который многие упускают: Click умеет создавать красивые прогресс-бары:
Про что еще стоит знать?🤔
Click отлично работает с цветным выводом. Хотите привлечь внимание пользователя? Используйте click.secho():
И напоследок, трюк – создание интерактивных подтверждений:
P.S. Не забудьте установить библиотеку через pip install click.
https://click.palletsprojects.com/en/stable/
Привет, пайтонисты! 👋 Сегодня поговорим о том, как создавать крутые CLI-приложения с помощью Click. Если вам надоело писать бесконечные if'ы для обработки аргументов командной строки, то этот пост определенно для вас!
Начнем с того, почему вообще стоит использовать Click, а не встроенный argparse:
- Декораторный подход, который выглядит элегантно и интуитивно понятен
- Автоматическая генерация справки и сообщений об ошибках
- Вложенные команды из коробки
- Поддержка автодополнения в shell
Давайте посмотрим на простой, но реальный пример. Представим, что мы делаем утилиту для работы с файлами:
import click
@click.group()
def cli():
"""Утилита для работы с файлами"""
pass
@cli.command()
@click.argument('path')
@click.option('--lines', '-l', is_flag=True, help='Показать количество строк')
def analyze(path, lines):
"""Анализирует файл и выводит статистику"""
try:
with open(path) as f:
content = f.readlines()
if lines:
click.echo(f'Количество строк: {len(content)}')
except FileNotFoundError:
click.secho('Файл не найден! 😱', fg='red')
if __name__ == '__main__':
cli()
Крутая штука в Click – это то, как легко добавлять новые команды. Хотите добавить подкоманду? Просто навешиваете еще один декоратор! 🎯
А теперь лайфхак, который многие упускают: Click умеет создавать красивые прогресс-бары:
@cli.command()
@click.argument('path')
def process(path):
"""Обрабатывает файлы с прогресс-баром"""
files = os.listdir(path)
with click.progressbar(files, label='Обработка файлов') as bar:
for f in bar:
# что-то делаем с файлом
time.sleep(0.1)
Про что еще стоит знать?
Click отлично работает с цветным выводом. Хотите привлечь внимание пользователя? Используйте click.secho():
click.secho('Внимание! 🚨', fg='yellow', bold=True)
click.secho('Ошибка! ❌', fg='red')
click.secho('Успех! ✅', fg='green')И напоследок, трюк – создание интерактивных подтверждений:
if click.confirm('Уверены, что хотите удалить все файлы? 🤔'):
click.echo('Поехали! 🚀')P.S. Не забудьте установить библиотеку через pip install click.
https://click.palletsprojects.com/en/stable/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Сделать ИГРУ на PYGAME Python | 2D Shooter | Коллизия, карта
В этом видео мы продолжим создавать 2д игру, а именно 2d shooter на библиотеке Pygame, используя Python. Сегодня мы добавим коллизию, чтобы человек не смог ходить и стрелять сквозь стены (spritecollide), а так же добавим само создание карты.
🔥 Подписывайся…
🔥 Подписывайся…
👍2
🤔 Привет, Питонисты! Сегодня поговорим о вечном противостоянии в мире тестирования. Знаете, как в споре "табы или пробелы", у нас есть другая горячая тема: unit-тесты против property-based тестирования. Давайте разберёмся без занудства, но с конкретикой!
🎯 Unit-тестирование - это как стрельба по мишеням. Мы точно знаем, какой результат хотим получить, и проверяем конкретные случаи. Например:
def test_sum():
assert sum([1, 2, 3]) == 6
assert sum([-1, 1]) == 0
- Понятны даже джуниору
- Легко дебажить
- Отлично подходят для документирования кода
- Быстро выполняются
- Покрывают только те кейсы, о которых мы подумали
- Часто пропускаем edge-cases
- Может быть много копипасты
from hypothesis import given
import hypothesis.strategies as st
@given(st.lists(st.integers()))
def test_sum_properties(numbers):
assert sum(numbers) == sum(reversed(numbers))
assert sum(numbers + [0]) == sum(numbers)
🚀 Преимущества property-testing:
- Находит неочевидные баги
- Меньше кода, больше покрытие
- Заставляет думать о свойствах функций, а не о конкретных значениях
🤯 Недостатки:
- Сложнее придумывать правильные свойства
- Медленнее выполняются
- Может быть сложно понять, почему тест упал
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6😁3🗿2❤1
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Роутеры и структура бота AIOgram 3 | PYTHON TELEGRAM BOT | Router
В этом видео мы рассмотрим новую тему библиотеки Aiogram, которая нужна для написания телеграм ботов на Python. А именно поговорим про роутеры и то, как разбить телеграм бота на файлы.
🔥 Подписывайся на наш Телеграм-канал про Python 🔥
🖇 https://t.me/pythonhub001…
🔥 Подписывайся на наш Телеграм-канал про Python 🔥
🖇 https://t.me/pythonhub001…
👍3❤1
Привет, питонисты! Сегодня поговорим о том, как превратить свой код в настоящий искусственный интеллект.
Давайте сразу посмотрим на простой пример в PyTorch:
import torch
import torch.nn as nn
class SimpleNet(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(784, 128)
self.relu = nn.ReLU()
self.layer2 = nn.Linear(128, 10)
def forward(self, x):
x = self.layer1(x)
x = self.relu(x)
return self.layer2(x)
Создаем модель одной строчкой! 🎯
model = SimpleNet().to('cuda' if torch.cuda.is_available() else 'cpu')
import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10)
])
# Компилируем модель
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
1. Подготовка данных (самая нудная, но важная часть)
2. Определение архитектуры (тут можно пофантазировать)
3. Обучение модели (запасайтесь терпением и мощным железом)
🎮 Давайте посмотрим, как выглядит обучение на реальных данных:
# PyTorch стиль
optimizer = torch.optim.Adam(model.parameters())
criterion = nn.CrossEntropyLoss()
for epoch in range(10):
for batch_x, batch_y in dataloader:
optimizer.zero_grad()
outputs = model(batch_x)
loss = criterion(outputs, batch_y)
loss.backward()
optimizer.step()
# Разбиваем данные
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Следим за метриками
val_loss = []
for epoch in range(epochs):
model.train()
# ... обучение ...
model.eval()
with torch.no_grad():
val_predictions = model(X_val)
v_loss = criterion(val_predictions, y_val)
val_loss.append(v_loss.item())
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
Признайтесь, кто из вас устал от статичных matplotlib графиков? Сегодня поговорим о том, как превратить ваши данные в интерактивные произведения искусства с помощью Plotly и Bokeh!
🎨 Начинаем с Plotly
Plotly - это как швейцарский нож в мире визуализации. Вот простой пример создания интерактивного графика:
import plotly.express as px
import pandas as pd
# Создаём тестовые данные
df = pd.DataFrame({
'Месяц': ['Янв', 'Фев', 'Март', 'Апр', 'Май'],
'Продажи': [100, 150, 200, 180, 250],
'Прибыль': [20, 30, 40, 35, 50]
})
# Создаём интерактивный график
fig = px.line(df, x='Месяц', y=['Продажи', 'Прибыль'],
title='Динамика продаж и прибыли',
template='plotly_dark')
# Добавляем hover-эффекты
fig.update_traces(mode='lines+markers', hovertemplate='%{y:,.0f}₽')
# Сохраняем как HTML или показываем в браузере
fig.write_html('sales_dashboard.html')
А теперь давайте создадим что-то более продвинутое с Bokeh:
from bokeh.plotting import figure, show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, HoverTool
import numpy as np
# Создаём интерактивный scatter plot
x = np.random.normal(0, 1, 1000)
y = np.random.normal(0, 1, 1000)
source = ColumnDataSource(data=dict(
x=x,
y=y,
size=np.random.uniform(5, 15, 1000),
color=['#%06x' % np.random.randint(0, 0xFFFFFF) for _ in range(1000)]
))
p = figure(width=800, height=600, title='Интерактивный Scatter Plot')
p.scatter('x', 'y', size='size', color='color', alpha=0.6, source=source)
# Добавляем интерактивные подсказки
hover = HoverTool(tooltips=[
('X', '@x{0.000}'),
('Y', '@y{0.000}'),
('Размер', '@size{0.00}')
])
p.add_tools(hover)
show(p)
Вот несколько крутых возможностей, о которых многие не знают:
1. Анимированные переходы в Plotly:
import plotly.graph_objects as go
fig = go.Figure(
data=[go.Scatter(x=[1, 2, 3], y=[1, 3, 2])],
layout=dict(
updatemenus=[dict(
type="buttons",
buttons=[dict(label="Play",
method="animate",
args=[None])]
)]
)
)
1. Real-time обновления в Bokeh:
from bokeh.plotting import curdoc
from functools import partial
from tornado.ioloop import IOLoop
def update():
source.data['y'] = np.random.rand(100)
curdoc().add_periodic_callback(update, 100) # Обновление каждые 100мс
💡 Pro-tip: Для больших датасетов используйте датаклассы и оптимизируйте память:
from dataclasses import dataclass
from typing import List
@dataclass
class DataPoint:
x: float
y: float
category: str
data_points: List[DataPoint] = [] # Эффективнее, чем DataFrame для больших данных
⚡️ Личный опыт: недавно делал дашборд для финтех-проекта. Начал с Matplotlib, намучался с интерактивностью, переписал на Plotly - заказчик в восторге, пользователи счастливы. Время разработки сократилось вдвое!
- Plotly: если нужны красивые графики "из коробки" и важна простота использования
- Bokeh: если работаете с большими данными или нужна глубокая кастомизация
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1