Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions HWs/Sergey/homework2/homework02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
'''Разработать систему регистрации пользователя, используя Pydantic для валидации входных данных, обработки
вложенных структур и сериализации. Система должна обрабатывать данные в формате JSON.

Задачи:
1. Создать классы моделей данных с помощью Pydantic для пользователя и его адреса.
2. Реализовать функцию, которая принимает JSON строку, десериализует её в объекты Pydantic, валидирует данные, и в
случае успеха сериализует объект обратно в JSON и возвращает его.
3. Добавить кастомный валидатор для проверки соответствия возраста и статуса занятости пользователя.
4. Написать несколько примеров JSON строк для проверки различных сценариев валидации: успешные регистрации и случаи,
когда валидация не проходит (например возраст не соответствует статусу занятости).

Модели:
Address: Должен содержать следующие поля:
city: строка, минимум 2 символа.
street: строка, минимум 3 символа.
house_number: число, должно быть положительным.

User: Должен содержать следующие поля:
name: строка, должна быть только из букв, минимум 2 символа.
age: число, должно быть между 0 и 120.
email: строка, должна соответствовать формату email.
is_employed: булево значение, статус занятости пользователя.
address: вложенная модель адреса.

Валидация:
Проверка, что если пользователь указывает, что он занят (is_employed = true), его возраст должен быть от 18 до 65
лет.

# Пример JSON данных для регистрации пользователя
json_input = """{
"name": "John Doe",
"age": 70,
"email": "john.doe@example.com",
"is_employed": true,
"address": {
"city": "New York",
"street": "5th Avenue",
"house_number": 123
}
}"""
'''

from pydantic import BaseModel, ValidationError, Field, EmailStr, model_validator


class Address(BaseModel):
city: str = Field(min_length=2, description='Min length 2 characters')
street: str = Field(min_length=3, description='Min length 3 characters')
house_number: int = Field(gt=0, description='Always positive integer')


class User(BaseModel):
name: str = Field(pattern=r'^[a-zA-Zа-яА-Я -]+$', min_length=2, description='Only letters and min 2 characters')
age: int = Field(gt=0, le=120, description='Between 0 and 120')
email: EmailStr = Field(description='Email address format')
is_employed: bool
address: Address


@model_validator(mode='after')
def check_is_employed(self):
if self.is_employed and not (18 <= self.age <= 65):
raise ValueError("If user is employed, age must be between 18 and 65")
return self


def data_validator(data):
try:
user = User.model_validate_json(data, strict=True)
return user.model_dump_json()
except ValidationError as err:
return err.json()
# except ValueError as err:
# print("ValueError error:", err)


if __name__ == '__main__':
# valid
# json_input = """{
# "name": "John Doe",
# "age": 70,
# "email": "john.doe@example.com",
# "is_employed": true,
# "address": {
# "city": "New York",
# "street": "5th Avenue",
# "house_number": 123
# }
# }"""

json_input = """{
"name": "Michael Johnson",
"age": 52,
"email": "mjohnson@gmail.com",
"is_employed": false,
"address": {
"city": "New York",
"street": "7th Avenue",
"house_number": 25
}
}"""
print('User registration is successful')
print(data_validator(json_input))

# invalid email and house_number
# json_input = """{
# "name": "Barak Obama",
# "age": 61,
# "email": "@icloud.co",
# "is_employed": false,
# "address": {
# "city": "Washington",
# "street": "1",
# "house_number": "12a"
# }
# }"""

# invalid age
json_invalid = """{
"name": "Timbuktu",
"age": 70,
"email": "tb@icloud.com",
"is_employed": true,
"address": {
"city": "Boston",
"street": "Baker Street",
"house_number": 124
}
}"""
print('User registration is not successful')
print(data_validator(json_invalid))
96 changes: 96 additions & 0 deletions HWs/Sergey/homework4/homework04.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
'''Задача 1: Наполнение данными
Добавьте в базу данных следующие категории и продукты'''
from sqlalchemy import create_engine, Column, Integer, String, DECIMAL, Boolean, Text, ForeignKey, func
from sqlalchemy.orm import sessionmaker, declarative_base, relationship


engine = create_engine('sqlite:///:memory:')

Base = declarative_base()

Session = sessionmaker(bind=engine)
session = Session()


class Product(Base):
__tablename__ = 'product'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(100))
price = Column(DECIMAL(7,2))
in_stock = Column(Boolean)
category_id = Column(Integer, ForeignKey('category.id'))


class Category(Base):
__tablename__ = 'category'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(100))
description = Column(Text)
products = relationship("Product", backref="category")


Base.metadata.create_all(engine)

'''Добавление категорий: Добавьте в таблицу categories следующие категории:
Название: "Электроника", Описание: "Гаджеты и устройства."
Название: "Книги", Описание: "Печатные книги и электронные книги."
Название: "Одежда", Описание: "Одежда для мужчин и женщин."'''
category_1 = Category(name="Электроника", description="Гаджеты и устройства.")
category_2 = Category(name="Книги", description="Печатные книги и электронные книги.")
category_3 = Category(name="Одежда", description="Одежда для мужчин и женщин.")

session.add_all([category_1, category_2, category_3])
session.commit()

'''Добавление продуктов: Добавьте в таблицу products следующие продукты, убедившись, что каждый продукт связан с
соответствующей категорией:
Название: "Смартфон", Цена: 299.99, Наличие на складе: True, Категория: Электроника
Название: "Ноутбук", Цена: 499.99, Наличие на складе: True, Категория: Электроника
Название: "Научно-фантастический роман", Цена: 15.99, Наличие на складе: True, Категория: Книги
Название: "Джинсы", Цена: 40.50, Наличие на складе: True, Категория: Одежда
Название: "Футболка", Цена: 20.00, Наличие на складе: True, Категория: Одежда'''
product_1 = Product(name="Смартфон", price=299.99, in_stock=True, category_id=1)
product_2 = Product(name="Ноутбук", price=499.99, in_stock=True, category_id=1)
product_3 = Product(name="Научно-фантастический роман", price=15.99, in_stock=True, category_id=2)
product_4 = Product(name="Джинсы", price=40.50, in_stock=True, category_id=3)
product_5 = Product(name="Футболка", price=20.00, in_stock=True, category_id=3)

session.add_all([product_1, product_2, product_3, product_4, product_5])
session.commit()

'''Задача 2: Чтение данных
Извлеките все записи из таблицы categories. Для каждой категории извлеките и выведите все связанные с ней продукты,
включая их названия и цены.'''
query_category = session.query(Category).all()
for category in query_category:
print(f"{category.id}. {category.name} - {category.description}:")
for product in category.products:
print(f" *** Название: {product.name}, Цена: {product.price}, Наличие: {product.in_stock}")
print("-" * 70)

'''Задача 3: Обновление данных
Найдите в таблице products первый продукт с названием "Смартфон". Замените цену этого продукта на 349.99.'''
product = session.query(Product).filter(Product.name == "Смартфон").first()
product.price = 349.99
session.commit()
print("-" * 70)
print(f" *** Название: {product.name}, Цена: {product.price}, Наличие: {product.in_stock}")

'''Задача 4: Агрегация и группировка
Используя агрегирующие функции и группировку, подсчитайте общее количество продуктов в каждой категории.'''
total_prod_in_ctg = (session.query(Category.name, func.count(Product.id).label('count_products')).outerjoin(Product
).group_by(Category.id).order_by(Category.id).all())
print("-" * 70)
for item in total_prod_in_ctg:
print("-" * 70)
print(f"Категория: '{item[0]}' - Количество: {item[1]}")
print("-" * 70)

'''Задача 5: Группировка с фильтрацией
Отфильтруйте и выведите только те категории, в которых более одного продукта.'''
print("-" * 70)
ctg_with_mult_prod = (session.query(Category.name, func.count(Product.id).label('count_products')).outerjoin(Product
).group_by(Category.id).having(func.count(Product.id) > 1).all())
print("Категории с более чем 1 продуктом:")
for item in ctg_with_mult_prod:
print(item[0])