Business Intelligence & Analytics
Automated analytics module for parsing transaction logs, visualizing sales velocity, and optimizing inventory levels. 거래 로그를 파싱하고 판매 속도를 시각화하며 재고 수준을 최적화하는 자동 분석 모듈입니다.
Project Overview프로젝트 개요
In modern finance and commerce, decision-making is driven by data. This project demonstrates the ability to build an end-to-end analytics pipeline: from parsing raw transaction logs to generating actionable business intelligence reports. 현대 금융/커머스의 의사결정은 데이터가 주도합니다. 이 프로젝트는 원시 거래 로그 파싱부터 실행 가능한 BI 리포트 생성까지, 엔드투엔드 분석 파이프라인 구축 능력을 보여줍니다.
The module automates the calculation of sales velocity, identifies top-performing products, and triggers inventory reorder alerts based on statistical thresholds. 판매 속도(Sales Velocity) 계산을 자동화하고, 상위 성과 제품을 식별하며, 통계적 임계값 기반 재주문 알림을 트리거합니다.
Key Concepts Implemented구현한 핵심 개념
Data Aggregation데이터 집계
Processed raw time-stamped transaction logs to aggregate sales data by product and time period, handling gaps and anomalies in data.타임스탬프가 포함된 원시 거래 로그를 처리해 제품/기간별 판매 데이터를 집계하고, 데이터 결측 및 이상치를 처리했습니다.
Sales Velocity & Reporting판매 속도 및 리포팅
Defined and calculated KPIs like "Sales Velocity" to measure product performance and generated automated visual reports for stakeholders.제품 성과 측정을 위해 Sales Velocity 같은 KPI를 정의/계산하고, 이해관계자용 시각 리포트를 자동 생성했습니다.
Inventory Optimization재고 최적화
Implemented logic to categorize inventory needs (High/Medium/Low priority) based on historical sales trends and current stock levels.과거 판매 추세와 현재 재고 수준을 바탕으로 재고 우선순위(상/중/하)를 분류하는 로직을 구현했습니다.
Technical Implementation기술 구현
The implementation uses Matplotlib for visualization and standard libraries for efficient data parsing, prioritizing clean, modular code structure.Matplotlib로 시각화하고 표준 라이브러리로 효율적인 파싱을 수행하며, 모듈형/가독성 높은 구조를 우선했습니다.
#!/usr/bin/python3
"""
Sales Analytics: Generate plots showing item sales velocity
"""
import sys
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from inventory_stock import load_sales_history, get_sales_summary
#i need to import for y=only integers
from matplotlib.ticker import MaxNLocator
def plot_sales_velocity(days=30):
"""Generate bar chart showing units sold per item"""
summary = get_sales_summary(days)
if not summary:
print("No sales data available")
return
#Sort items by quantity sold (descending to show "winner items")
sorted_items = sorted(summary.items(), key=lambda x: x[1], reverse=True)
items = [x[0] for x in sorted_items]
quantities = [x[1] for x in sorted_items]
plt.figure(figsize=(10, 6))
bars = plt.bar(items, quantities, color='steelblue')
#Highlight top 3 sellers (Gold, Silver, Bronze)
colors = ['gold', 'silver', '#CD7F32']
for bar, color in zip(bars[:3], colors):
bar.set_color(color)
plt.xlabel('Product')
plt.ylabel('Units Sold')
plt.title(f'Sales Velocity - Last {days} Days')
plt.xticks(rotation=45, ha='right')
plt.gca().yaxis.set_major_locator(MaxNLocator(integer=True))
plt.tight_layout()
filename = f'sales_velocity_{days}days.png'
plt.savefig(filename, dpi=300)
print(f"✓ Plot saved as '{filename}'")
plt.show()
def plot_daily_sales(days=30):
"""Generate line chart showing daily sales over time"""
history = load_sales_history()
if not history:
print("No sales data available")
return
end_date = datetime.now()
start_date=end_date-timedelta(days=days)
#Initialize daily counts
daily_counts={}
curr = start_date
while curr <= end_date:
daily_counts[curr.date()] = 0
curr += timedelta(days=1)
#Aggregate sales
for sale in history:
sale_date = datetime.fromisoformat(sale["timestamp"]).date()
if start_date.date() <= sale_date <= end_date.date():
daily_counts[sale_date] += sum(sale["items"].values())
#Plot
dates = sorted(daily_counts.keys())
counts = [daily_counts[d] for d in dates]
plt.figure(figsize=(10, 6))
plt.plot(dates, counts, marker='o', linewidth=2)
plt.xlabel('Date')
plt.ylabel('Items Sold')
plt.title(f'Daily Sales - Last {days} Days')
plt.xticks(rotation=45,ha='right')
plt.gca().yaxis.set_major_locator(MaxNLocator(integer=True))
plt.tight_layout()
filename = f'daily_sales_{days}days.png'
plt.savefig(filename, dpi=300)
print(f"✓ Plot saved as '{filename}'")
plt.show()
def generate_reorder_report():
"""Print report showing items to reorder"""
summary = get_sales_summary(30)
if not summary:
print("No sales data found.")
return
print(f"\n {'='*60} \n 📊 REORDER REPORT (Last 30 Days) \n {'='*60}")
print(f"{'Product':<40} {'Sold':>10} {'Priority':>10} \n {'-'*60}")
for item, qty in sorted(summary.items(), key=lambda x: x[1], reverse=True):
if qty > 100: priority="HIGH"
elif qty > 50: priority="MEDIUM"
else: priority ="LOW"
print(f"{item:<40} {qty:>10} {priority:>10}")
print("="*60)
if __name__ == '__main__':
print("=== Warehouse Sales Analytics ===\n")
days = int(sys.argv[1]) if len(sys.argv) > 1 else 30
print(f"Analyzing last {days} days...\n")
plot_sales_velocity(days)
plot_daily_sales(days)
generate_reorder_report()