finale structure

This commit is contained in:
Елизавета Данилова 2026-05-07 22:08:36 +03:00
parent f4d7e204d7
commit 823a626d38
9 changed files with 26 additions and 196 deletions

26
.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
# Виртуальное окружение
.venv/
venv/
env/
# Кэш Python
__pycache__/
*.pyc
*.pyo
# Отчёты (генерируются программой)
reports/
*.txt
# IDE
.idea/
.vscode/
*.swp
# Системные файлы
.DS_Store
Thumbs.db
desktop.ini
# Бэкапы
*.backup

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.13 (InventoryManager)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated
View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (InventoryManager)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/InventoryManager.iml" filepath="$PROJECT_DIR$/.idea/InventoryManager.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

41
.idea/workspace.xml generated
View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="b32e6acd-5da1-46f8-a48d-12dc1410b7d6" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 3
}]]></component>
<component name="ProjectId" id="3BrXroiobVyuVOwKhaCCNo1Tl0n" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true"
}
}]]></component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-python-sdk-02acdf704d18-cbfc7b97e6b2-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-252.28539.27" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="b32e6acd-5da1-46f8-a48d-12dc1410b7d6" name="Changes" comment="" />
<created>1775248363717</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1775248363717</updated>
</task>
<servers />
</component>
</project>

View File

@ -1,15 +0,0 @@
ИНВЕНТАРИЗАЦИОННЫЙ ОТЧЁТ
==================================================
Общее количество товаров: 8
Общая стоимость склада: 2,750,000.00 руб.
Топ-3 категории по количеству товаров:
1. Электроника: 4 товаров
2. Мебель: 2 товаров
3. Канцелярия: 2 товаров
Товары с остатком менее 10 единиц:
- Стул офисный Ergohuman: 8 шт.
- Клавиатура Mechanical: 0 шт.
- Стол письменный: 5 шт.

View File

@ -1,8 +1,3 @@
"""
Модуль управления складскими запасами интернет-магазина
Содержит функции для работы с товарами, фильтрации, анализа и отчётности
"""
import csv import csv
import os import os
from typing import List, Dict, Optional from typing import List, Dict, Optional
@ -10,15 +5,6 @@ from collections import Counter
def load_products(filepath: str) -> List[Dict]: def load_products(filepath: str) -> List[Dict]:
"""
Загружает данные о товарах из CSV-файла.
Args:
filepath: Путь к CSV-файлу
Returns:
Список словарей с данными о товарах. При отсутствии файла возвращает пустой список
"""
products = [] products = []
try: try:
@ -45,15 +31,6 @@ def load_products(filepath: str) -> List[Dict]:
def validate_product(product: Dict) -> bool: def validate_product(product: Dict) -> bool:
"""
Проверяет корректность данных товара.
Args:
product: Словарь с данными товара
Returns:
True, если все поля присутствуют и корректны, иначе False
"""
required_fields = ['product_id', 'name', 'category', 'quantity', 'price', 'supplier'] required_fields = ['product_id', 'name', 'category', 'quantity', 'price', 'supplier']
for field in required_fields: for field in required_fields:
@ -85,73 +62,25 @@ def validate_product(product: Dict) -> bool:
def filter_by_category(products: List[Dict], category: str) -> List[Dict]: def filter_by_category(products: List[Dict], category: str) -> List[Dict]:
"""
Фильтрует товары по категории (регистронезависимо).
Args:
products: Список товаров
category: Название категории для фильтрации
Returns:
Новый список товаров указанной категории
"""
return [product for product in products return [product for product in products
if product['category'].lower() == category.lower()] if product['category'].lower() == category.lower()]
def filter_by_quantity(products: List[Dict], min_quantity: int) -> List[Dict]: def filter_by_quantity(products: List[Dict], min_quantity: int) -> List[Dict]:
"""
Фильтрует товары с остатком не ниже заданного.
Args:
products: Список товаров
min_quantity: Минимальное количество
Returns:
Отфильтрованный список товаров
"""
return [product for product in products return [product for product in products
if product['quantity'] >= min_quantity] if product['quantity'] >= min_quantity]
def calculate_total_value(products: List[Dict]) -> float: def calculate_total_value(products: List[Dict]) -> float:
"""
Вычисляет общую стоимость всех товаров на складе.
Args:
products: Список товаров
Returns:
Сумма произведений quantity * price для каждого товара
"""
return sum(product['quantity'] * product['price'] for product in products) return sum(product['quantity'] * product['price'] for product in products)
def find_low_stock(products: List[Dict], threshold: int) -> List[Dict]: def find_low_stock(products: List[Dict], threshold: int) -> List[Dict]:
"""
Находит товары с критически низким остатком.
Args:
products: Список товаров
threshold: Пороговое значение
Returns:
Список товаров с quantity <= threshold, отсортированный по возрастанию остатка
"""
low_stock = [product for product in products if product['quantity'] <= threshold] low_stock = [product for product in products if product['quantity'] <= threshold]
return sorted(low_stock, key=lambda x: x['quantity']) return sorted(low_stock, key=lambda x: x['quantity'])
def group_by_supplier(products: List[Dict]) -> Dict[str, Dict]: def group_by_supplier(products: List[Dict]) -> Dict[str, Dict]:
"""
Группирует товары по поставщикам.
Args:
products: Список товаров
Returns:
Словарь, где ключ поставщик, значение словарь со статистикой
"""
suppliers = {} suppliers = {}
for product in products: for product in products:
@ -169,15 +98,6 @@ def group_by_supplier(products: List[Dict]) -> Dict[str, Dict]:
def get_most_expensive_product(products: List[Dict]) -> Optional[Dict]: def get_most_expensive_product(products: List[Dict]) -> Optional[Dict]:
"""
Находит самый дорогой товар.
Args:
products: Список товаров
Returns:
Словарь товара с максимальной ценой, при пустом списке возвращает None
"""
if not products: if not products:
return None return None
@ -185,32 +105,12 @@ def get_most_expensive_product(products: List[Dict]) -> Optional[Dict]:
def search_by_name(products: List[Dict], keyword: str) -> List[Dict]: def search_by_name(products: List[Dict], keyword: str) -> List[Dict]:
"""
Ищет товары по ключевому слову в названии (регистронезависимо).
Args:
products: Список товаров
keyword: Ключевое слово для поиска
Returns:
Список товаров, содержащих ключевое слово в названии
"""
keyword_lower = keyword.lower() keyword_lower = keyword.lower()
return [product for product in products return [product for product in products
if keyword_lower in product['name'].lower()] if keyword_lower in product['name'].lower()]
def save_inventory_report(products: List[Dict], filepath: str) -> bool: def save_inventory_report(products: List[Dict], filepath: str) -> bool:
"""
Сохраняет инвентаризационный отчёт в текстовый файл.
Args:
products: Список товаров
filepath: Путь для сохранения отчёта
Returns:
True при успешной записи, False при ошибке
"""
try: try:
os.makedirs(os.path.dirname(filepath), exist_ok=True) os.makedirs(os.path.dirname(filepath), exist_ok=True)
@ -245,9 +145,6 @@ def save_inventory_report(products: List[Dict], filepath: str) -> bool:
def create_products_csv(): def create_products_csv():
"""
Создаёт файл data/products.csv с тестовыми данными
"""
os.makedirs('data', exist_ok=True) os.makedirs('data', exist_ok=True)
data = [ data = [
@ -270,9 +167,6 @@ def create_products_csv():
def main(): def main():
"""
Главная функция программы, выполняющая все шаги по анализу складских запасов.
"""
print("=" * 60) print("=" * 60)
print("УПРАВЛЕНИЕ СКЛАДСКИМИ ЗАПАСАМИ ИНТЕРНЕТ-МАГАЗИНА") print("УПРАВЛЕНИЕ СКЛАДСКИМИ ЗАПАСАМИ ИНТЕРНЕТ-МАГАЗИНА")
print("=" * 60) print("=" * 60)