Реализация учета товаров с помощью Python
Обзор подходов к созданию программы учета на Python
Наиболее эффективное решение для малого бизнеса или личного использования - консольное приложение с базой данных SQLite. Оно не требует установки сервера, легко переносится и позволяет хранить данные в одном файле. Пример реализации включает инициализацию таблицы, добавление, просмотр и удаление записей.
import sqlite3
def init_db():
conn = sqlite3.connect('inventory.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS items
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
quantity INTEGER,
price REAL)''')
conn.commit()
conn.close()
def add_item(name, quantity, price):
conn = sqlite3.connect('inventory.db')
c = conn.cursor()
c.execute("INSERT INTO items (name, quantity, price) VALUES (?,?,?)", (name, quantity, price))
conn.commit()
conn.close()
def list_items():
conn = sqlite3.connect('inventory.db')
c = conn.cursor()
for row in c.execute("SELECT * FROM items"):
print(row)
conn.close()
Python программа учета (программа учета на python)
Пояснения: функция init_db создает таблицу, если её нет. add_item использует параметризованный запрос для защиты от SQL-инъекций. list_items выводит все строки.
Типичные ошибки: забывают закрывать соединение, что приводит к блокировке файла. Также возможны ошибки при вводе нечисловых данных в поля quantity и price. Решение - использовать обработку исключений try/except и встроенные проверки типов.
Возникающие проблемы: при многопользовательском доступе SQLite может выдавать ошибку 'database is locked'. Рекомендуется использовать WAL-режим или переходить на клиент-серверные СУБД. Ещё одна трудность - миграции схемы данных. Для простых проектов достаточно удалить и создать таблицу заново, но лучше применять библиотеку Alembic.
Как сделать программу учета без базы данных, используя JSON-файлы?
Если нужно быстро прототипировать или не хочется работать с SQL, можно хранить данные в JSON. Файл легко читать и редактировать вручную, но он не поддерживает конкурентный доступ и сложные запросы.
import json
DATA_FILE = 'inventory.json'
def load_data():
try:
with open(DATA_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
return []
def save_data(data):
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def add_item(name, quantity, price):
data = load_data()
new_id = max([item['id'] for item in data], default=0) + 1
data.append({'id': new_id, 'name': name, 'quantity': quantity, 'price': price})
save_data(data)
Проблемы: при частых записях возможно повреждение файла. Для обеспечения целостности данных лучше использовать временный файл и переименование. JSON не подходит для больших объёмов (более 10-20 тысяч записей) из-за полной загрузки в память.
Ошибки: если файл повреждён, json.load вызовет исключение. Решение - резервное копирование и проверка валидности перед загрузкой.
Как создать оконное приложение учета на Python с Tkinter?
Для пользователей, предпочитающих графический интерфейс, подойдёт Tkinter. Примерный код включает окно со списком и формой добавления.
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
class InventoryApp:
def __init__(self, root):
self.root = root
self.root.title('Учет товаров')
self.tree = ttk.Treeview(root, columns=('name','qty','price'), show='headings')
self.tree.heading('name', text='Наименование')
self.tree.heading('qty', text='Количество')
self.tree.heading('price', text='Цена')
self.tree.pack(fill=tk.BOTH, expand=True)
btn_add = tk.Button(root, text='Добавить', command=self.open_add_window)
btn_add.pack(pady=5)
self.load_data()
def load_data(self):
conn = sqlite3.connect('inventory.db')
for row in conn.execute('SELECT name, quantity, price FROM items'):
self.tree.insert('', tk.END, values=row)
conn.close()
def open_add_window(self):
# окно для добавления
pass
Проблемы: Tkinter требует цикл событий, сложно делать асинхронные операции. Для больших таблиц Treeview становится медленным, рекомендуется использовать виртуальный режим.
Типичная ошибка - забыть обновить виджет после изменения данных. Решение: после каждой операции добавлять метод refresh, очищающий и перезаполняющий Treeview.
Как реализовать учет через веб-интерфейс на Flask?
Для доступа с разных устройств без установки ПО удобно веб-приложение. Основные маршруты: список товаров, форма добавления и удаления.
from flask import Flask, render_template, request, redirect, url_for
import sqlite3
app = Flask(__name__)
@app.route('/')
def index():
conn = sqlite3.connect('inventory.db')
items = conn.execute('SELECT * FROM items').fetchall()
conn.close()
return render_template('index.html', items=items)
@app.route('/add', methods=['POST'])
def add():
name = request.form['name']
qty = int(request.form['quantity'])
price = float(request.form['price'])
conn = sqlite3.connect('inventory.db')
conn.execute('INSERT INTO items (name, quantity, price) VALUES (?,?,?)', (name, qty, price))
conn.commit()
conn.close()
return redirect(url_for('index'))
Проблемы: необходимо настроить сервер, обеспечить безопасность (CSRF, валидация). Для продакшена требуется WSGI-сервер (Gunicorn, uWSGI).
Ошибки: неправильная обработка типов данных из формы, незакрытые соединения приводят к зависанию. Рекомендуется использовать контекстные менеджеры (with).
Расширенные примеры консольного учета с отчетами и фильтрацией
Добавим возможность формировать отчет по сумме товаров на складе и поиск по названию.
import sqlite3
from datetime import datetime
def get_total_value():
conn = sqlite3.connect('inventory.db')
cursor = conn.execute('SELECT SUM(quantity*price) FROM items')
total = cursor.fetchone()[0] or 0
conn.close()
return total
def search_items(keyword):
conn = sqlite3.connect('inventory.db')
cursor = conn.execute('SELECT * FROM items WHERE name LIKE ?', (f'%{keyword}%',))
results = cursor.fetchall()
conn.close()
return results
def get_low_stock(threshold=5):
conn = sqlite3.connect('inventory.db')
cursor = conn.execute('SELECT * FROM items WHERE quantity < ?', (threshold,))
results = cursor.fetchall()
conn.close()
return results
# Пример вызова:
print('Общая стоимость:', get_total_value())
print('Поиск "мыло":', search_items('мыло'))
print('Товары с остатком менее 5:', get_low_stock())
Общая стоимость: 25430.5 Поиск "мыло": [(1, 'мыло хозяйственное', 10, 50.0), (4, 'мыло жидкое', 3, 120.0)] Товары с остатком менее 5: [(2, 'зубная паста', 2, 150.0)]
Расширенный пример для Tkinter: добавление графика и экспорт в CSV
В графическом приложении можно отобразить круговую диаграмму по категориям (если добавить поле category). Для упрощения покажем экспорт всех данных в CSV.
import csv
import sqlite3
from tkinter import filedialog
def export_to_csv():
filepath = filedialog.asksaveasfilename(defaultextension='.csv')
if not filepath:
return
conn = sqlite3.connect('inventory.db')
items = conn.execute('SELECT * FROM items').fetchall()
conn.close()
with open(filepath, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['id','name','quantity','price'])
writer.writerows(items)
messagebox.showinfo('Экспорт', 'Данные экспортированы')
Расширенный пример для Flask: добавление REST API и сортировки
Реализуем JSON-интерфейс для внешних программ и возможность сортировки товаров по цене.
from flask import jsonify, request
@app.route('/api/items')
def api_items():
sort_by = request.args.get('sort', 'name')
order = request.args.get('order', 'asc')
allowed_sort = {'name','price','quantity'}
if sort_by not in allowed_sort:
sort_by = 'name'
if order not in ('asc','desc'):
order = 'asc'
conn = sqlite3.connect('inventory.db')
items = conn.execute(f'SELECT * FROM items ORDER BY {sort_by} {order}').fetchall()
conn.close()
# преобразовать в список словарей
result = [{'id':r[0],'name':r[1],'quantity':r[2],'price':r[3]} for r in items]
return jsonify(result)
Результат вызова GET /api/items?sort=price&order=desc:
[
{"id": 1, "name": "мыло", "quantity": 10, "price": 50.0},
{"id": 4, "name": "шампунь", "quantity": 2, "price": 200.0}
]