Kodduu Python
1.07K subscribers
312 photos
28 videos
188 links
Научись программировать на Python на интересных примерах

Самый быстрый курс https://stepik.org/a/187914
Самый нескучный курс https://stepik.org/a/185238

Во вопросам сотрудничества: @AlexErf
Download Telegram
Давайте расширим предыдущий пример, добавив к нашему микросервису возможность обновления и удаления данных пользователей. Также мы добавим более сложные элементы, такие как валидация данных и использование средств логирования для отслеживания событий.

import logging
from fastapi import FastAPI, HTTPException, status, Depends
from pydantic import BaseModel, EmailStr, validator
from typing import List, Optional
import databases
import sqlalchemy
from sqlalchemy import create_engine, Column, Integer, String, MetaData
import asyncio

# Setup logger
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

DATABASE_URL = "sqlite:///./test.db"
database = databases.Database(DATABASE_URL)
metadata = MetaData()

users = sqlalchemy.Table(
"users",
metadata,
Column("id", Integer, primary_key=True),
Column("name", String(50)),
Column("email", String(50))
)

engine = create_engine(DATABASE_URL)
metadata.create_all(engine)

class User(BaseModel):
id: int
name: str
email: EmailStr

class UserCreate(BaseModel):
name: str
email: EmailStr

@validator('name')
def validate_name(cls, value):
if not value.isalpha():
raise ValueError('Name must contain only letters')
return value

class UserUpdate(BaseModel):
name: Optional[str] = None
email: Optional[EmailStr] = None

app = FastAPI()

@app.on_event("startup")
async def startup():
await database.connect()
logger.info("Database connection established.")

@app.on_event("shutdown")
async def shutdown():
await database.disconnect()
logger.info("Database connection closed.")

@app.post("/users/", response_model=User, status_code=status.HTTP_201_CREATED)
async def create_user(user: UserCreate):
query = users.insert().values(name=user.name, email=user.email)
last_record_id = await database.execute(query)
logger.info(f"User created with ID: {last_record_id}")
return {**user.dict(), "id": last_record_id}

@app.get("/users/", response_model=List[User])
async def read_users():
query = users.select()
result = await database.fetch_all(query)
logger.info("Read all users")
return result

@app.get("/users/{user_id}", response_model=User)
async def read_user(user_id: int):
query = users.select().where(users.c.id == user_id)
user = await database.fetch_one(query)
if user is None:
logger.warning(f"User not found: {user_id}")
raise HTTPException(status_code=404, detail="User not found")
return user

@app.put("/users/{user_id}", response_model=User)
async def update_user(user_id: int, user: UserUpdate):
query = users.update().where(users.c.id == user_id).values(**user.dict(exclude_unset=True))
await database.execute(query)
updated_user = await read_user(user_id)
logger.info(f"User updated with ID: {user_id}")
return updated_user

@app.delete("/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_user(user_id: int):
query = users.delete().where(users.c.id == user_id)
await database.execute(query)
logger.info(f"User deleted with ID: {user_id}")
return {"message": "User deleted successfully"}


Этот код включает следующие дополнительные функции:

1. **Валидация данных**: Используется Pydantic для валидации имен и адресов электронной почты пользователей.
2. Логирование: Ведение журнала операций для отслеживания действий пользователей и ошибок.
3. Обновление и удаление данных: API теперь поддерживает запросы PUT и DELETE для обновления и удаления пользователей.

Таким образом, код остается структурированным и читаемым, а также обеспечивает дополнительный контроль над данными и их безопасностью.

Подпишись 👉🏻 @KodduuPython 🤖
Технологии экстремально малоразрядного квантования, такие как BitNet и модели с квантованием до 1.58 бита, представляют собой интересный подход в машинном обучении. Эти методы позволяют существенно сократить объем необходимой памяти и ускорить операции, такие как умножение матриц, за счет использования весов с очень низкой битовой глубиной.

Для реализации такого рода подхода можно использовать библиотеку TensorFlow или PyTorch, которые поддерживают различные техники квантования. Для примера, я покажу, как можно имитировать процесс квантования с использованием TensorFlow. В данном примере мы не будем достигать уровня 1.58 бита, но покажем, как можно квантовать модель с более высоким уровнем квантования, например, до 8 бит:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

# Загружаем и предобрабатываем данные
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape(-1, 28*28).astype('float32')
x_test = x_test.reshape(-1, 28*28).astype('float32')
y_train, y_test = to_categorical(y_train, 10), to_categorical(y_test, 10)

# Строим простую модель
inputs = Input(shape=(784,))
x = Dense(128, activation='relu')(inputs)
outputs = Dense(10, activation='softmax')(x)
model = Model(inputs=inputs, outputs=outputs)

# Компилируем модель
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Обучаем модель
model.fit(x_train, y_train, batch_size=64, epochs=5, validation_split=0.1)

# Квантуем модель
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
quantized_model = converter.convert()

# Сохраняем квантованную модель
with open('quantized_model.tflite', 'wb') as f:
f.write(quantized_model)

print("Модель квантована и сохранена.")


В этом примере мы создаем простую нейронную сеть для классификации рукописных цифр из набора данных MNIST, обучаем её, а затем применяем квантование, используя TensorFlow Lite. Квантованная модель имеет значительно меньший размер и может быть более эффективной при выполнении инференса на устройствах с ограниченными ресурсами.

Тем не менее, достижение уровня квантования в 1.58 бита требует специализированных подходов и возможно с использованием более продвинутых техник квантования, которые могут включать собственные разработки алгоритмов или использование экспериментального программного обеспечения.

Подпишись 👉🏻 @KodduuPython 🤖
Один из интересных и нестандартных подходов в сфере искусственного интеллекта связан с использованием генеративно-состязательных сетей (GANs) для создания синтетических данных. Этот метод позволяет генерировать новые, реалистичные образцы данных, которые могут быть использованы для обучения других машинных моделей, увеличения объемов данных без нарушения приватности и для улучшения моделей машинного обучения в условиях дефицита данных.

Примером применения GAN для создания синтетических изображений может служить следующий код на Python с использованием Keras (библиотеки над TensorFlow):

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, LeakyReLU, BatchNormalization, Reshape, Flatten
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.optimizers import Adam
from keras.datasets import mnist

# Загрузка и подготовка данных
(x_train, _), (_, _) = mnist.load_data()
x_train = (x_train - 127.5) / 127.5 # Нормализация данных в диапазон [-1, 1]
x_train = np.expand_dims(x_train, axis=3)

# Параметры
img_rows, img_cols, channels = 28, 28, 1
img_shape = (img_rows, img_cols, channels)

# Генератор
generator = Sequential([
Dense(256, input_dim=100),
LeakyReLU(alpha=0.2),
BatchNormalization(momentum=0.8),
Dense(512),
LeakyReLU(alpha=0.2),
BatchNormalization(momentum=0.8),
Dense(1024),
LeakyReLU(alpha=0.2),
BatchNormalization(momentum=0.8),
Dense(np.prod(img_shape), activation='tanh'),
Reshape(img_shape)
])
generator.summary()

# Дискриминатор
discriminator = Sequential([
Flatten(input_shape=img_shape),
Dense(512),
LeakyReLU(alpha=0.2),
Dense(256),
LeakyReLU(alpha=0.2),
Dense(1, activation='sigmoid')
])
discriminator.summary()
discriminator.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5), metrics=['accuracy'])

# Состязательная модель
discriminator.trainable = False
gan = Sequential([generator, discriminator])
gan.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5))

# Тренировка GAN
def train_gan(epochs, batch_size=128, save_interval=50):
for epoch in range(epochs):
# Генерация шума
noise = np.random.normal(0, 1, (batch_size, 100))
# Генерация изображений
gen_imgs = generator.predict(noise)

# Подготовка реальных и синтетических данных
idx = np.random.randint(0, x_train.shape[0], batch_size)
real_imgs = x_train[idx]
valid = np.ones((batch_size, 1))
fake = np.zeros((batch_size, 1))

# Тренировка дискриминатора
d_loss_real = discriminator.train_on_batch(real_imgs, valid)
d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

# Тренировка генератора
noise = np.random.normal(0, 1, (batch_size, 100))
g_loss = gan.train_on_batch(noise, valid)

# Прогресс
print(f"{epoch} [D loss: {d_loss[0]}, acc.: {100*d_loss[1]}%] [G loss: {g_loss}]")

# Сохранение изображений
if epoch % save_interval == 0:
noise = np.random.normal(0, 1, (25, 100))
gen_imgs = generator.predict(noise)
gen_imgs = 0.5 * gen_imgs + 0.5 # Денормализация

train_gan(epochs=

10000, batch_size=32, save_interval=1000)


В этом примере:
- Генератор строит изображения из шума.
- Дискриминатор оценивает, насколько реалистично изображение.
- GAN обучается таким образом, чтобы генератор становился все лучше в создании реалистичных изображений, а дискриминатор — в их распознавании.

Такие GANs могут быть использованы в различных областях, от создания искусственного контента до улучшения моделей машинного зрения.

Подпишись 👉🏻 @KodduuPython 🤖
Один из необычных и передовых подходов в искусственном интеллекте — использование нейронных сетей для управления коммуникацией между мозгом и компьютером (BCI, Brain-Computer Interface). Эти технологии позволяют людям управлять внешними устройствами, такими как протезы или компьютеры, используя только свои мыслительные процессы. Нейронные сети играют ключевую роль в декодировании нейронных сигналов, что делает возможным преобразование мысленных команд в управляющие сигналы.

В этом примере мы рассмотрим простую модель, которая использует нейронную сеть для классификации и декодирования ЭЭГ-сигналов. ЭЭГ (электроэнцефалограмма) — это метод регистрации электрической активности мозга, и его данные часто используются в системах BCI.

Пример модели на Python с использованием Keras для классификации ЭЭГ-сигналов:

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, LSTM
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# Загрузка данных ЭЭГ (здесь мы используем гипотетическую функцию загрузки)
def load_eeg_data():
# В реальном примере данные должны быть загружены и предобработаны соответствующим образом
data = np.random.rand(1000, 128) # 1000 примеров, 128 признаков (например, амплитуды сигналов в разные моменты времени)
labels = np.random.randint(0, 2, 1000) # Бинарные метки классов
return data, labels

# Предобработка данных
data, labels = load_eeg_data()
labels = to_categorical(labels, num_classes=2)
data_train, data_test, labels_train, labels_test = train_test_split(data, labels, test_size=0.2)

# Масштабирование данных
scaler = StandardScaler()
data_train = scaler.fit_transform(data_train)
data_test = scaler.transform(data_test)

# Создание модели
model = Sequential([
LSTM(64, input_shape=(data_train.shape[1], 1), return_sequences=True),
Dropout(0.5),
LSTM(32),
Dropout(0.5),
Dense(2, activation='softmax')
])

# Компиляция модели
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Обучение модели
model.fit(data_train[:, :, np.newaxis], labels_train, epochs=20, batch_size=64)

# Оценка модели
loss, accuracy = model.evaluate(data_test[:, :, np.newaxis], labels_test)
print(f"Точность модели: {accuracy * 100}%")


В этом примере:
- Мы используем LSTM (Long Short-Term Memory) слои, так как они хорошо подходят для работы с временными рядами и последовательными данными, какими являются ЭЭГ-сигналы.
- Производится классификация между двумя состояниями на основе ЭЭГ-данных.
- Данные масштабируются для улучшения процесса обучения.

Системы BCI, использующие такой подход, могут быть использованы для помощи людям с ограниченными физическими возможностями, обеспечивая новый способ взаимодействия с окружающим миром.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте рассмотрим ещё один необычный подход в AI, который используется в области сохранения биоразнообразия и экологии — машинное обучение для распознавания и мониторинга видов дикой природы. Этот подход позволяет исследователям и экологам более эффективно отслеживать популяции животных, анализировать их поведение и принимать меры по сохранению видов.

### Пример: Использование ИИ для анализа аудиоданных тропических лесов

Представим, что у нас есть аудиозаписи из тропического леса, и наша задача — обучить модель, которая будет распознавать звуки различных видов животных. Это может помочь в мониторинге биологического разнообразия и раннем обнаружении изменений в экосистеме.

#### Вот пример кода на Python с использованием библиотеки librosa для анализа аудио и keras для создания модели машинного обучения:

import librosa
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder

# Загрузка и предобработка аудиоданных
def load_audio_files(path, labels):
features = []
for file, label in zip(path, labels):
# Загрузка аудиофайла
audio, sr = librosa.load(file, sr=None)
# Извлечение признаков (мел-спектрограмма)
melspec = librosa.feature.melspectrogram(y=audio, sr=sr, n_mels=40)
melspec = librosa.power_to_db(melspec, ref=np.max)
features.append(melspec)
return np.array(features), np.array(labels)

# Предположим, у нас есть список путей к файлам и соответствующие метки
file_paths = ['path/to/audio1.wav', 'path/to/audio2.wav', ...]
labels = ['species1', 'species2', ...]

# Загрузка данных
X, y = load_audio_files(file_paths, labels)

# Кодирование меток
le = LabelEncoder()
y_encoded = le.fit_transform(y)
y_categorical = to_categorical(y_encoded)

# Разделение данных на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y_categorical, test_size=0.2, random_state=42)

# Модель
model = Sequential([
Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(X_train.shape[1], X_train.shape[2], 1)),
MaxPooling2D(pool_size=(2, 2)),
Dropout(0.25),
Flatten(),
Dense(128, activation='relu'),
Dropout(0.5),
Dense(len(le.classes_), activation='softmax')
])

# Компиляция и обучение модели
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test))

# Оценка модели
score = model.evaluate(X_test, y_test, verbose=0)
print(f'Точность модели: {score[1] * 100}%')


В этом примере:
- Мы используем librosa для загрузки аудиофайлов и извлечения мел-спектрограмм, которые являются мощным способом представления аудиосигналов.
- Создаем модель с конволюционными слоями (CNN), которые хорошо подходят для анализа визуаль

Подпишись 👉🏻 @KodduuPython 🤖
Попробуем использовать библиотеку art, которая позволяет создавать арт-тексты и различные виды ASCII арта. Её можно использовать для украшения интерфейсов консольных приложений или просто для развлечения.

### Установка

Для начала вам нужно установить библиотеку, если она у вас ещё не установлена:

pip install art


### Пример использования

Ниже приведён пример скрипта, который выводит различные стили текста и некоторые виды ASCII арта:

from art import *

def main():
# Отображение текста в разных арт-стилях
text_art = text2art("Art!") # Выбор стиля ASCII арта для текста
print(text_art)

font_list = ['block', 'bubble', 'bulbhead'] # Некоторые интересные шрифты для примера
for font in font_list:
print("Font:", font)
print(text2art("Hello!", font=font))

# Добавление различных ASCII изображений
animal_arts = ['butterfly', 'cat', 'dog']
for animal in animal_arts:
print("Animal art for:", animal)
print(art(animal))

# Однолинейный ASCII арт
one_line_art = one_line_art("love")
print("One-line art for love:")
print(one_line_art)

if __name__ == "__main__":
main()


### Описание кода
- text2art: функция для создания арт-текста с использованием разных шрифтов.
- art: функция, возвращающая ASCII изображения из предопределённого списка.
- one_line_art: возвращает символы в виде одной строки для некоторых ключевых слов.

Этот код можно запускать в консоли, и он показывает различные виды искусства ASCII, что может быть особенно интересно для пользовательских сообщений в консольных приложениях или командных файлах.

Подпишись 👉🏻 @KodduuPython 🤖
Чтобы создать код на Python для управления роботизированной рукой, которая может складывать вещи, нужно рассмотреть несколько аспектов: управление сервоприводами руки, логику обнаружения и захвата предметов, а также последовательность действий для складывания.

Допустим, у нас есть роботизированная рука с несколькими степенями свободы, которую мы управляем через Raspberry Pi или Arduino. В этом примере я покажу основной скелет программы на Python, используя библиотеку gpiozero для Raspberry Pi. Если вы используете Arduino или другую систему, код будет отличаться, но концепция останется та же.

### Шаг 1: Настройка
Установите библиотеку gpiozero, если вы используете Raspberry Pi. Это можно сделать через pip:

pip install gpiozero


### Шаг 2: Код программы

from gpiozero import Servo
from time import sleep

# Настройка GPIO пинов для сервоприводов
# Пример: GPIO17, GPIO27, GPIO22 для основания, плеча и кисти соответственно
servo_base = Servo(17)
servo_arm = Servo(27)
servo_hand = Servo(22)

def initialize():
""" Инициализирует руку в начальное положение """
servo_base.mid()
servo_arm.min()
servo_hand.min()
sleep(1)

def pick_item():
""" Процедура захвата предмета """
servo_hand.max() # Открывает захват
sleep(1)
servo_arm.max() # Опускает руку
sleep(1)
servo_hand.min() # Закрывает захват
sleep(1)
servo_arm.min() # Поднимает руку
sleep(1)

def place_item():
""" Помещает предмет в новое место """
servo_arm.max()
sleep(1)
servo_hand.max()
sleep(1)
servo_arm.min()
sleep(1)

def main():
initialize()
while True:
pick_item()
servo_base.max() # Поворот на 90 градусов для размещения
sleep(1)
place_item()
servo_base.mid() # Возвращение в исходное положение
sleep(10) # Ожидание перед следующим циклом

if __name__ == "__main__":
main()


### Объяснение кода
1. Инициализация: Рука устанавливается в начальное положение.
2. Захват предмета: Рука опускается, захватывает предмет и поднимается обратно.
3. Перемещение предмета: Рука переносит предмет, помещает его в новое место и возвращается.

Этот код является лишь примером и предполагает, что вы знаете размеры и веса объектов, которые рука будет перемещать, и что они всегда будут находиться в доступном месте. В реальных условиях также понадобится интеграция с системами машинного зрения для точного определения положения объектов и возможно использование более сложных алгоритмов для управления сервоприводами.

Подпишись 👉🏻 @KodduuPython 🤖
👍1
Создадим основу программы для управления складским роботом, который может перемещаться по складу, поднимать и перемещать коробки с одного места на другое. Этот код будет использовать концепцию конечных автоматов для управления различными состояниями робота: поиск товара, подход к товару, подъем товара, перенос товара и разгрузка товара.

### Шаг 1: Установка
Для начала установим библиотеку transitions, которая поможет нам управлять состояниями робота.

pip install transitions


### Шаг 2: Код программы

from transitions import Machine
import time

class WarehouseRobot:
states = ['searching', 'approaching', 'lifting', 'carrying', 'unloading']

def __init__(self):
self.machine = Machine(model=self, states=WarehouseRobot.states, initial='searching')

# Добавление переходов
self.machine.add_transition(trigger='find_item', source='searching', dest='approaching')
self.machine.add_transition(trigger='reach_item', source='approaching', dest='lifting')
self.machine.add_transition(trigger='lift_item', source='lifting', dest='carrying')
self.machine.add_transition(trigger='deliver_item', source='carrying', dest='unloading')
self.machine.add_transition(trigger='unload_item', source='unloading', dest='searching')

def find_item(self):
print("Ищу товар...")

def reach_item(self):
print("Подхожу к товару...")

def lift_item(self):
print("Поднимаю товар...")

def deliver_item(self):
print("Переношу товар...")

def unload_item(self):
print("Разгружаю товар...")

def simulate_robot():
robot = WarehouseRobot()
actions = [robot.find_item, robot.reach_item, robot.lift_item, robot.deliver_item, robot.unload_item]

# Имитация работы робота
for action in actions:
action()
time.sleep(2) # Добавлено задержка для имитации времени выполнения задач

if __name__ == "__main__":
simulate_robot()


### Объяснение кода
- Инициализация и состояния: Робот начинает в состоянии searching, где он ищет товар на складе.
- Переходы: Когда робот находит товар, он переходит в состояние approaching, затем в lifting, carrying и unloading.
- Действия: Для каждого состояния определены специфические действия (например, reach_item означает подход к товару).

Этот простой пример показывает основную структуру программы управления складским роботом. В реальных условиях потребуется интеграция с системами для навигации и манипуляции в реальном мире, а также возможно интеграция с системами складского учета.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте рассмотрим пример программы для управления роботом-уборщиком, который перемещается по определённой территории, обнаруживает и убирает мусор. В этом примере мы также воспользуемся концепцией конечных автоматов и добавим элементы случайности для имитации обнаружения мусора. Такой робот может найти применение в парках, на улицах или в больших помещениях.

### Шаг 1: Установка библиотеки
Установите библиотеку transitions и random, если последняя ещё не установлена:

pip install transitions
pip install random


### Шаг 2: Код программы

import random
from transitions import Machine
import time

class CleaningRobot:
states = ['patrolling', 'detecting', 'cleaning', 'returning']

def __init__(self):
self.machine = Machine(model=self, states=CleaningRobot.states, initial='patrolling')

# Добавление переходов
self.machine.add_transition('detect_trash', 'patrolling', 'detecting')
self.machine.add_transition('clean_trash', 'detecting', 'cleaning')
self.machine.add_transition('trash_cleaned', 'cleaning', 'returning')
self.machine.add_transition('finish_cleaning', 'returning', 'patrolling')

def patrol(self):
print("Патрулирую территорию...")
if random.randint(0, 10) > 8:
self.detect_trash()
else:
time.sleep(1) # Имитация времени патрулирования

def detect_trash(self):
print("Обнаружен мусор!")
time.sleep(1)
self.clean_trash()

def clean_trash(self):
print("Убираю мусор...")
time.sleep(2)
self.trash_cleaned()

def return_to_base(self):
print("Возвращаюсь на базу для опорожнения мусора...")
time.sleep(2)
self.finish_cleaning()

def simulate_robot():
robot = CleaningRobot()
for _ in range(10): # Симуляция 10 циклов работы робота
robot.patrol()

if __name__ == "__main__":
simulate_robot()


### Объяснение кода
- Состояния и переходы: Робот начинает с патрулирования (patrolling). Если обнаруживает мусор, переходит в состояние detecting, затем cleaning, после чистки — returning, и возвращается к патрулированию.
- Действия: Для каждого состояния определено конкретное действие, включая паузы для имитации затрат времени на выполнение задач.
- Случайное обнаружение мусора: Используется модуль random для имитации случайного обнаружения мусора во время патрулирования.

Этот пример демонстрирует базовую структуру программы для управления роботом-уборщиком. В реальности, такой робот может использовать датчики и камеры для более точного обнаружения мусора и препятствий на своём пути.

Подпишись 👉🏻 @KodduuPython 🤖
Программа для робота-охранника может включать мониторинг территории, обнаружение вторжений и реагирование на них. Давайте создадим пример кода, используя конечный автомат для управления различными состояниями робота: патрулирование, обнаружение вторжения, преследование и вызов помощи.

### Шаг 1: Установка библиотеки
Установите библиотеку transitions:

pip install transitions


### Шаг 2: Код программы

from transitions import Machine
import random
import time

class SecurityRobot:
states = ['patrolling', 'detecting', 'chasing', 'calling_for_help']

def __init__(self):
self.machine = Machine(model=self, states=SecurityRobot.states, initial='patrolling')

# Добавление переходов
self.machine.add_transition('detect_intruder', 'patrolling', 'detecting')
self.machine.add_transition('start_chase', 'detecting', 'chasing')
self.machine.add_transition('call_help', 'detecting', 'calling_for_help')
self.machine.add_transition('intruder_gone', 'chasing', 'patrolling')
self.machine.add_transition('help_arrived', 'calling_for_help', 'patrolling')

def patrol(self):
print("Патрулирую территорию...")
if random.randint(0, 20) > 18:
self.detect_intruder()

def detect_intruder(self):
print("Обнаружен вторженец! Пытаюсь идентифицировать...")
time.sleep(2)
if random.randint(0, 5) > 3:
self.start_chase()
else:
self.call_help()

def chase_intruder(self):
print("Преследую вторженца...")
time.sleep(3)
if random.randint(0, 5) > 2:
print("Вторженец сбежал.")
self.intruder_gone()
else:
self.call_help()

def call_for_help(self):
print("Вызываю помощь!")
time.sleep(3)
print("Помощь прибыла, возвращаюсь к патрулированию.")
self.help_arrived()

def simulate_robot():
robot = SecurityRobot()
for _ in range(10): # Симуляция 10 циклов работы робота
robot.patrol()
time.sleep(1)

if __name__ == "__main__":
simulate_robot()


### Объяснение кода
- Состояния и переходы: Робот начинает с патрулирования (patrolling). При обнаружении вторженца переходит в состояние detecting, где выбирает между началом преследования (chasing) или вызовом помощи (calling_for_help).
- Реагирование: В зависимости от случайного исхода, робот может преследовать вторженца или сразу вызывать помощь.
- Возвращение к патрулированию: После окончания ситуации робот возвращается к патрулированию.

Этот код демонстрирует базовую структуру программы для управления роботом-охранником. В реальных условиях, такой робот может использовать камеры, датчики движения и другие технологии для более точного обнаружения и отслеживания вторженцев, а также для автоматического вызова помощи.

Подпишись 👉🏻 @KodduuPython 🤖
🏆2
### Классификация товаров с использованием машинного обучения на Python

В современном ритейле одной из ключевых задач является автоматизация процессов, включая классификацию товаров. Это не только сокращает время обработки данных, но и повышает точность работы системы управления запасами. Python предлагает мощные инструменты для решения такой задачи, в частности, с помощью библиотеки PyTorch можно эффективно реализовать модели глубокого обучения для классификации изображений товаров.

#### Подготовка данных

Для начала работы нам нужен набор данных, содержащий изображения товаров и соответствующие метки классов. В этом примере мы используем упрощённый набор данных, аналогичный MNIST, но в реальных условиях это будут фотографии товаров. Для обучения модели требуется следующий код подготовки данных:

from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# Трансформации для предобработки изображений
transform = transforms.Compose([
transforms.Resize((128, 128)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])

# Загрузка данных
train_data = datasets.ImageFolder(root='path_to_train_data', transform=transform)
train_loader = DataLoader(dataset=train_data, batch_size=32, shuffle=True)


#### Создание модели

Следующий шаг — создание модели нейронной сети. Мы будем использовать свёрточную нейронную сеть (CNN), так как она хорошо подходит для задач обработки изображений:

import torch
import torch.nn as nn
import torch.nn.functional as F

class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=5, stride=1, padding=2)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
self.conv2 = nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2)
self.fc1 = nn.Linear(64 * 32 * 32, 1000)
self.fc2 = nn.Linear(1000, 10) # предполагается 10 классов товаров

def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 64 * 32 * 32)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x

model = CNN()


#### Обучение модели

Третий шаг — обучение модели. Здесь важно правильно выбрать функцию потерь и оптимизатор:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Цикл обучения
for epoch in range(10):
for i, (images, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/10], Step [{i+1}], Loss: {loss.item():.4f}')


#### Применение и оценка модели

После обучения модели важно проверить её эффективность на тестовом наборе данных и на реальных примерах из бизнеса. Оценка качества классификации поможет понять, насколько хорошо модель справляется с задачей в условиях, максимально

приближенных к реальным.

#### Заключение

Автоматизация классификации товаров с помощью глубокого обучения на Python позволяет значительно повысить эффективность розничной торговли. Используя современные инструменты и алгоритмы, компании могут не только оптимизировать свои процессы, но и улучшить пользовательский опыт, предлагая быстрее и точнее обслуживание клиентов.

Подпишись 👉🏻 @KodduuPython 🤖
Давай напишем небольшой код на Python, который будет моделировать движение планет в солнечной системе. Мы создадим упрощённую систему с Солнцем, Землёй и Марсом, используя законы Ньютона и гравитационные силы.

Код будет использовать библиотеку matplotlib для анимации движения планет, чтобы вы могли визуализировать, как они движутся по своим орбитам.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# Константы
G = 6.67430e-11 # Гравитационная постоянная Ньютона
AU = 1.496e11 # одна астрономическая единица (расстояние от Земли до Солнца в метрах)
TIMESTEP = 24 * 3600 # один день в секундах

# Инициализация планет
class Planet:
def __init__(self, name, mass, distance, velocity):
self.name = name
self.mass = mass
self.pos = np.array([distance, 0])
self.vel = np.array([0, velocity])
self.trail = np.empty((0, 2), float)

def update_position(self, timestep):
self.trail = np.vstack([self.trail, self.pos])
self.pos += self.vel * timestep

def update_velocity(self, timestep, forces):
self.vel += forces / self.mass * timestep

def compute_gravitational_force(p1, p2):
distance_vector = p2.pos - p1.pos
distance = np.linalg.norm(distance_vector)
force_magnitude = G * p1.mass * p2.mass / distance**2
force_vector = force_magnitude * distance_vector / distance
return force_vector

# Создаем систему
sun = Planet('Sun', 1.989e30, 0, 0)
earth = Planet('Earth', 5.972e24, AU, 29.78e3)
mars = Planet('Mars', 6.39e23, 1.524 * AU, 24.077e3)

planets = [sun, earth, mars]

# Функция для обновления позиций и скоростей
def update_system(planets, timestep):
forces = {}
for planet in planets:
total_force = np.array([0.0, 0.0])
for other_planet in planets:
if planet != other_planet:
force = compute_gravitational_force(planet, other_planet)
total_force += force
forces[planet] = total_force

for planet in planets:
planet.update_velocity(timestep, forces[planet])
planet.update_position(timestep)

# Визуализация
fig, ax = plt.subplots()
ax.set_xlim(-2 * AU, 2 * AU)
ax.set_ylim(-2 * AU, 2 * AU)

points = {planet: ax.plot([], [], 'o', label=planet.name)[0] for planet in planets}
trails = {planet: ax.plot([], [], '-', color=points[planet].get_color())[0] for planet in planets}

def animate(frame):
update_system(planets, TIMESTEP)
for planet in planets:
points[planet].set_data(planet.pos[0], planet.pos[1])
trails[planet].set_data(planet.trail[:, 0], planet.trail[:, 1])
return points.values(), trails.values()

ani = FuncAnimation(fig, animate, frames=365, interval=50, blit=True)

plt.legend()
plt.show()


В этом коде мы моделируем орбиты Земли и Марса вокруг Солнца на протяжении одного земного года. Вы можете запустить этот код в любом Python окружении, которое поддерживает matplotlib.

Подпишись 👉🏻 @KodduuPython 🤖
Задача трех тел — это классическая задача в астродинамике и небесной механике, где рассматривается проблема предсказания движений трех тел, взаимодействующих через гравитационное притяжение. Примером может быть система, состоящая из Солнца, Земли и Луны.

Приведу пример кода на Python, который моделирует задачу трех тел в двумерном пространстве. Для этого мы будем использовать matplotlib для визуализации движения тел. В этом примере мы примем упрощение, что все три тела имеют сравнимые массы и могут влиять друг на друга.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# Константы
G = 6.67430e-11 # гравитационная постоянная, м^3 кг^-1 с^-2
TIME_STEP = 24 * 3600 # шаг времени (один день)

# Определение класса для тела в системе
class Body:
def __init__(self, name, mass, position, velocity):
self.name = name
self.mass = mass
self.position = np.array(position, dtype=float)
self.velocity = np.array(velocity, dtype=float)
self.trajectory = []

def update_position(self, timestep):
self.position += self.velocity * timestep
self.trajectory.append(self.position.copy())

# Вычисление силы гравитации между двумя телами
def gravitational_force(body1, body2):
r_vec = body2.position - body1.position
r_mag = np.linalg.norm(r_vec)
r_hat = r_vec / r_mag
force_mag = G * body1.mass * body2.mass / r_mag**2
force_vec = force_mag * r_hat
return force_vec

# Обновление скорости и положения всех тел
def update_bodies(bodies, timestep):
forces = {body: np.zeros(2) for body in bodies}
for i, body1 in enumerate(bodies):
for j, body2 in enumerate(bodies):
if i != j:
force = gravitational_force(body1, body2)
forces[body1] += force / body1.mass

for body in bodies:
body.velocity += forces[body] * timestep
body.update_position(timestep)

# Создание тел
bodies = [
Body('Body1', 5.972e24, [-1e11, 0], [0, 15000]),
Body('Body2', 5.972e24, [1e11, 0], [0, -15000]),
Body('Body3', 5.972e24, [0, 1e11], [-15000, 0])
]

# Визуализация
fig, ax = plt.subplots()
ax.set_xlim(-3e11, 3e11)
ax.set_ylim(-3e11, 3e11)

points = {body: ax.plot([], [], 'o', label=body.name)[0] for body in bodies}
trajectories = {body: ax.plot([], [], label=body.name)[0] for body in bodies}

def animate(frame):
update_bodies(bodies, TIME_STEP)
for body in bodies:
x, y = zip(*body.trajectory)
trajectories[body].set_data(x, y)
points[body].set_data(body.position[0], body.position[1])
return points.values(), trajectories.values()

ani = FuncAnimation(fig, animate, frames=200, interval=20, blit=True)
plt.legend()
plt.show()


Этот код создает три тела с одинаковыми массами, каждое из которых изначально находится в разных углах и имеет начальные скорости, направленные так, чтобы тела двигались перпендикулярно друг к другу. Анимация покажет, как эти тела движутся под воздействием гравитационных сил друг друга. Эта система может проявлять хаотическое поведение из-за сложности взаимодействий.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте рассмотрим классическую логистическую задачу, такую как проблема транспортировки продукции с минимальными затратами. Задача будет заключаться в определении оптимального количества продукции, которое нужно перевозить от нескольких поставщиков к нескольким потребителям, чтобы минимизировать общие транспортные расходы.

### Задача
У нас есть три поставщика, каждый из которых может поставлять определённое количество продукции. Также есть три потребителя, каждый из которых требует определённое количество продукции. Стоимость транспортировки единицы продукции от каждого поставщика к каждому потребителю различается. Необходимо минимизировать общую стоимость транспортировки.

### Данные:
- Поставщики:
- Поставщик 1: может поставить до 20 единиц продукции.
- Поставщик 2: может поставить до 30 единиц продукции.
- Поставщик 3: может поставить до 25 единиц продукции.

- Потребители:
- Потребитель 1: требуется 25 единиц продукции.
- Потребитель 2: требуется 30 единиц продукции.
- Потребитель 3: требуется 20 единиц продукции.

- Стоимость транспортировки (в единицах валюты за продукт):
- От поставщика 1: к потребителям 1, 2 и 3 соответственно: 2, 3 и 1.
- От поставщика 2: к потребителям 1, 2 и 3 соответственно: 5, 4 и 8.
- От поставщика 3: к потребителям 1, 2 и 3 соответственно: 5, 6 и 1.

### Решение
Мы можем использовать линейное программирование для решения этой задачи. В Python это можно сделать с помощью библиотеки PuLP, которая позволяет моделировать линейные и целочисленные программы.

import pulp

# Создание модели
model = pulp.LpProblem("Minimize_Transportation_Costs", pulp.LpMinimize)

# Определение переменных
supply = [20, 30, 25]
demand = [25, 30, 20]
costs = [
[2, 3, 1],
[5, 4, 8],
[5, 6, 1]
]

# Переменные решения
x = pulp.LpVariable.dicts("shipment", [(i, j) for i in range(3) for j in range(3)], lowBound=0, cat='Integer')

# Целевая функция
model += pulp.lpSum([x[(i, j)] * costs[i][j] for i in range(3) for j in range(3)])

# Ограничения поставок
for i in range(3):
model += pulp.lpSum([x[(i, j)] for j in range(3)]) <= supply[i], f"Supply_Constraint_{i+1}"

# Ограничения спроса
for j in range(3):
model += pulp.lpSum([x[(i, j)] for i in range(3)]) >= demand[j], f"Demand_Constraint_{j+1}"

# Решение модели
model.solve()

# Вывод результатов
print("Статус:", pulp.LpStatus[model.status])
print("Минимальная стоимость:", pulp.value(model.objective))
for v in model.variables():
print(v.name, "=", v.varValue)


Этот скрипт создаёт и решает модель линейного программирования, чтобы найти оптимальное распределение продукции от поставщиков к потребителям с минимальными транспортными расходами. В коде используются переменные, представляющие количество товаров, отправляемых от каждого поставщика каждому потребителю, с ограничениями на доступные запасы и требуемые количества.

Подпишись 👉🏻 @KodduuPython 🤖
Линейное программирование (ЛП) — это метод решения задач оптимизации, при котором целевая функция и ограничения являются линейными. Этот метод широко используется в различных областях, включая производство, транспортировку, финансы и логистику, для нахождения оптимального результата в условиях заданных ограничений.

Для решения задач ЛП в Python можно использовать библиотеку PuLP, которая предоставляет инструменты для моделирования и решения линейных и целочисленных программ. Вот основные шаги работы с PuLP:

1. Определение модели: Создание объекта проблемы, который может быть направлен на минимизацию или максимизацию.
2. Определение переменных: Ввод переменных, которые будут использоваться для оптимизации. Можно задать их как непрерывные, целочисленные или бинарные.
3. Целевая функция: Определение функции, которую нужно максимизировать или минимизировать.
4. Ограничения: Добавление ограничений, которые должны быть соблюдены.
5. Решение проблемы: Вызов солвера для решения модели.
6. Анализ результатов: Проверка статуса решения и извлечение результатов.

### Пример: Максимизация прибыли
Предположим, у нас есть фабрика, производящая два типа продуктов (Продукт A и Продукт B). Нам нужно определить, сколько произвести каждого продукта, чтобы максимизировать прибыль, учитывая ограничения по рабочему времени и материалам.

Данные:
- Прибыль от каждого Продукта A: $20
- Прибыль от каждого Продукта B: $30
- Максимально доступные часы производства: 40 часов в неделю
- Продукт A требует 1 час производства на единицу
- Продукт B требует 2 часа производства на единицу
- Максимально доступное количество материалов: 30 единиц в неделю
- Продукт A требует 3 единицы материалов на изделие
- Продукт B требует 2 единицы материалов на изделие

Код:
import pulp

# Создание модели
model = pulp.LpProblem("Maximize_Profit", pulp.LpMaximize)

# Определение переменных
x = pulp.LpVariable("Product_A", lowBound=0, cat='Continuous')
y = pulp.LpVariable("Product_B", lowBound=0, cat='Continuous')

# Целевая функция
model += 20 * x + 30 * y, "Total_Profit"

# Ограничения
model += x + 2 * y <= 40, "Production_Hours"
model += 3 * x + 2 * y <= 30, "Material_Usage"

# Решение модели
model.solve()

# Вывод результатов
print("Статус:", pulp.LpStatus[model.status])
print("Максимальная прибыль:", pulp.value(model.objective))
print("Произвести Продукт A:", x.varValue)
print("Произвести Продукт B:", y.varValue)


Объяснение кода:
- В первых строках мы определяем модель и переменные, где переменные x и y обозначают количество произведенных единиц Продукта A и

B соответственно.
- Затем добавляется целевая функция, которая максимизирует прибыль, умножая количество каждого продукта на его прибыль.
- Далее мы добавляем ограничения, которые учитывают доступные часы производства и использование материалов.
- Вызываем солвер model.solve(), который ищет оптимальное решение задачи.
- Выводим результаты, показывающие статус решения, максимальную прибыль и рекомендованные объемы производства.

Этот пример иллюстрирует основные шаги работы с PuLP для решения линейных программировочных задач.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте рассмотрим другую концепцию: замыкания в Python. Замыкания могут показаться сложными, но на самом деле они просто позволяют функции динамически создавать другую функцию с некоторыми предустановленными параметрами.

Пример использования замыкания — это создание функций, которые могут запоминать состояние между вызовами.

Вот простой пример замыкания, которое создает функцию для умножения числа на какой-то коэффициент:

def multiplier(factor):
# Внешняя функция, которая принимает коэффициент
def multiply_by_factor(number):
# Внутренняя функция, которая использует коэффициент
return number * factor
return multiply_by_factor # Возвращаем внутреннюю функцию

# Создаем функцию, которая будет умножать числа на 3
times_three = multiplier(3)

# Теперь можно использовать эту функцию
print(times_three(5)) # Выводит 15, потому что 5 * 3 = 15


В этом примере, multiplier — это внешняя функция, которая принимает параметр factor. Она определяет и возвращает внутреннюю функцию multiply_by_factor, которая умножает входное число на factor. Поскольку внутренняя функция сохраняет ссылку на переменную factor внешней функции, она запоминает его между вызовами. Это и есть замыкание.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте теперь рассмотрим концепцию декораторов в Python. Декораторы — это функции, которые позволяют модифицировать поведение других функций. Они предоставляют гибкий способ "обернуть" функцию другой функцией, чтобы расширить её поведение без изменения самой функции.

Декораторы часто используются для добавления функциональности, которая должна применяться к нескольким функциям в программе, например, логирование, измерение времени выполнения и т.д.

Вот простой пример декоратора, который измеряет время выполнения функции:

import time

def timing_decorator(func):
# Это декоратор, принимающий функцию func в качестве параметра
def wrapper(*args, **kwargs):
start_time = time.time() # Запоминаем время перед вызовом функции
result = func(*args, **kwargs) # Вызываем функцию
end_time = time.time() # Запоминаем время после выполнения функции
print(f"{func.__name__} выполнена за {end_time - start_time} секунд")
return result
return wrapper # Возвращаем обертку

@timing_decorator
def my_function(x):
# Пример функции, которую можно "обернуть" декоратором
time.sleep(x) # Просто ждем x секунд
return x

# Теперь, когда мы вызываем my_function, она автоматически оборачивается декоратором
print(my_function(2)) # Выводит, сколько времени заняло выполнение функции, и возвращает x


В этом примере:
- timing_decorator — это функция, которая принимает другую функцию func и возвращает новую функцию wrapper.
- wrapper — это функция, которая обертывает исходную функцию func, добавляя дополнительное поведение (измерение времени).
- Используя @timing_decorator перед определением my_function, мы применяем декоратор к этой функции, так что каждый вызов my_function теперь автоматически обрабатывается декоратором.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте теперь рассмотрим концепцию генераторов в Python. Генераторы — это особый тип итераторов, который позволяет вам писать функции, которые могут выдавать значение и затем продолжать выполнение с того места, где они остановились. Генераторы создаются с помощью ключевого слова yield.

Генераторы полезны, когда вам нужно лениво генерировать значения, что может быть эффективнее с точки зрения памяти, чем создание всех значений сразу.

Вот простой пример генератора, который генерирует бесконечную последовательность чисел, начиная с указанного:

def infinite_counter(start=0):
# Генератор, начинающий счет с указанного числа
while True:
yield start # Возвращает текущее число и приостанавливает функцию
start += 1 # При следующем вызове продолжит с этого места

# Создаем генератор
counter = infinite_counter(10)

# Получаем первые пять чисел из генератора
for _ in range(5):
print(next(counter)) # Выведет 10, 11, 12, 13, 14


В этом примере:
- infinite_counter является функцией-генератором, которая начинает счет с переданного ей числа start.
- Ключевое слово yield используется для того, чтобы возвращать текущее значение start и приостанавливать выполнение функции.
- Когда next(counter) вызывается, выполнение генератора возобновляется с того места, где он был приостановлен, и счет продолжается.

Генераторы идеально подходят для работы с большими данными или для создания бесконечных последовательностей, где не требуется хранение всех элементов в памяти сразу.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте теперь рассмотрим концепцию асинхронного программирования в Python, используя asyncio, который представляет собой библиотеку для написания однопоточных, асинхронных приложений. Эта концепция часто используется для создания масштабируемых серверов или в приложениях, где обработка ввода-вывода может быть бутылочным горлышком.

Асинхронное программирование позволяет выполнять несколько задач "одновременно" на одном потоке, используя событийный цикл (event loop), который координирует все операции ввода-вывода и код, который должен быть выполнен.

### Пример: Асинхронное скачивание веб-страниц

Давайте рассмотрим пример, где мы асинхронно скачиваем несколько веб-страниц:

import asyncio
import aiohttp # Для асинхронных HTTP запросов

async def download_page(url):
async with aiohttp.ClientSession() as session: # Асинхронный контекст для сессии
async with session.get(url) as response: # Асинхронный запрос
content = await response.read() # Ждем, пока не загрузится содержимое
print(f"Downloaded {url} with content length {len(content)}")

async def main():
urls = [
"http://example.com",
"http://example.org",
"http://example.net"
]
tasks = [download_page(url) for url in urls] # Создаем список задач
await asyncio.gather(*tasks) # Запускаем все задачи одновременно

# Запускаем асинхронный event loop
asyncio.run(main())


### Как это работает:
- Функции, определенные с async def, называются асинхронными функциями. Они возвращают специальный объект, который можно ожидать (awaitable).
- await используется для ожидания результата асинхронной операции, что позволяет Python выполнять другой код во время ожидания завершения операции.
- aiohttp — это библиотека, предназначенная для выполнения асинхронных HTTP запросов.
- asyncio.gather используется для запуска нескольких асинхронных задач одновременно.

Этот подход идеально подходит для операций ввода-вывода, таких как запросы к веб-сервисам, доступ к базам данных и другие действия, которые требуют ожидания, так как позволяет эффективно использовать время ожидания для выполнения других задач.

Подпишись 👉🏻 @KodduuPython 🤖
Давайте рассмотрим концепцию многопоточности в Python, используя модуль threading. Многопоточность позволяет программе выполнять несколько задач одновременно. Это особенно полезно для выполнения операций, которые натурально блокируют выполнение программы, например, I/O операции, или для распределения работы на несколько процессоров.

### Пример: Многопоточное выполнение задач

Рассмотрим простой пример, где мы создаем несколько потоков для выполнения функции, которая просто ждет некоторое время и затем печатает сообщение:

import threading
import time

def thread_function(name, delay):
print(f"Thread {name}: starting")
time.sleep(delay) # Имитация затратной операции
print(f"Thread {name}: finishing after {delay} seconds")

def main():
threads = []
# Создаем три потока
for index in range(3):
# Задержка для каждого потока увеличивается
thread = threading.Thread(target=thread_function, args=(index, 2 + index))
threads.append(thread)
thread.start() # Запускаем поток

# Ждем завершения всех потоков
for thread in threads:
thread.join()

# Запускаем функцию main
main()


### Как это работает:
- threading.Thread создает новый поток, который будет выполнить target функцию с заданными args.
- thread.start() запускает поток.
- thread.join() используется для ожидания завершения потока. Это важно для синхронизации потоков, если последующая логика зависит от результатов выполнения этих потоков.

Многопоточность в Python подвержена некоторым ограничениям из-за глобальной блокировки интерпретатора (GIL), которая позволяет только одному потоку выполнять байт-код Python в любой момент времени. Однако для I/O-интенсивных задач многопоточность может существенно улучшить производительность, поскольку I/O операции часто освобождают GIL, позволяя другим потокам выполняться.

Многопоточность идеально подходит для операций, которые включают много ожидания, таких как запросы к сети, работа с файлами или другие подобные операции.

Подпишись 👉🏻 @KodduuPython 🤖
Дифференцирование в контексте дифференцируемого программирования относится к процессу вычисления производной функции относительно её входных переменных. Это важная концепция в машинном обучении и оптимизации, поскольку производные (или градиенты) используются для нахождения минимальных или максимальных значений функции, например, функции потерь в нейронных сетях.

В обычной математике производная функции показывает, как функция изменяется при небольшом изменении входной переменной. В программировании, особенно в машинном обучении, вычисление производных необходимо для алгоритмов оптимизации, таких как градиентный спуск. Эти алгоритмы используют градиенты для обновления параметров модели с целью минимизации функции потерь.

Пример:

Рассмотрим функцию \( f(x) = \sin(x) + x^2 \). Чтобы минимизировать эту функцию, нам нужно знать, как она изменяется в зависимости от \( x \). Производная функции \( f(x) \) даст нам эту информацию.

1. Аналитическое дифференцирование:
Можно вычислить производную аналитически:
\[ f'(x) = \cos(x) + 2x \]

2. Автоматическое дифференцирование:
В программировании, с помощью библиотек, таких как JAX, мы можем автоматически вычислить производные функций без необходимости вывода аналитического выражения.

Практическое значение:

1. Градиентный спуск:
В машинном обучении производные используются для обновления параметров модели. Градиентный спуск обновляет параметры в направлении отрицательного градиента функции потерь, что приводит к её уменьшению.
\[ \theta = \theta - \eta \nabla_\theta J(\theta) \]
где \( \theta \) — параметры модели, \( \eta \) — скорость обучения, \( \nabla_\theta J(\theta) \) — градиент функции потерь относительно параметров.

2. Обратное распространение ошибки:
В нейронных сетях дифференцирование используется для вычисления градиентов функции потерь относительно весов сети с помощью метода обратного распространения ошибки (backpropagation). Это позволяет эффективно обучать глубокие нейронные сети.

Пример кода на Python с использованием JAX:


import jax
import jax.numpy as jnp

# Определим функцию
def my_function(x):
return jnp.sin(x) + x**2

# Вычислим градиент функции относительно x
grad_function = jax.grad(my_function)

# Зададим значение x
x = 3.0

# Вычислим значение функции и градиента
value = my_function(x)
grad_value = grad_function(x)

print("Значение функции в точке x = {}: {}".format(x, value))
print("Градиент функции в точке x = {}: {}".format(x, grad_value))


В этом коде:
- Функция my_function определяет \( f(x) = \sin(x) + x^2 \).
- jax.grad используется для вычисления градиента этой функции.
- Мы вычисляем значение функции и её градиента в точке \( x = 3.0 \).

Таким образом, дифференцирование в контексте дифференцируемого программирования — это процесс автоматического вычисления производных, который используется для оптимизации и обучения моделей машинного обучения.

Подпишись 👉🏻 @KodduuPython 🤖