Files
BrickTracker/bricktracker/statistics.py

132 lines
5.3 KiB
Python

"""
Statistics module for BrickTracker
Provides statistics and analytics functionality
"""
import logging
from typing import Any
from .sql import BrickSQL
from .theme_list import BrickThemeList
logger = logging.getLogger(__name__)
class BrickStatistics:
"""Main statistics class providing overview and detailed statistics"""
def __init__(self):
self.sql = BrickSQL()
def get_overview(self) -> dict[str, Any]:
"""Get overview statistics"""
result = self.sql.fetchone('statistics/overview')
if result:
return dict(result)
return {}
def get_theme_statistics(self) -> list[dict[str, Any]]:
"""Get statistics grouped by theme with theme names"""
results = self.sql.fetchall('statistics/themes')
# Load theme list to get theme names
theme_list = BrickThemeList()
statistics = []
for row in results:
stat = dict(row)
# Add theme name from theme list
theme = theme_list.get(stat['theme_id'])
stat['theme_name'] = theme.name if theme else f"Theme {stat['theme_id']}"
statistics.append(stat)
return statistics
def get_storage_statistics(self) -> list[dict[str, Any]]:
"""Get statistics grouped by storage location"""
results = self.sql.fetchall('statistics/storage')
return [dict(row) for row in results]
def get_purchase_location_statistics(self) -> list[dict[str, Any]]:
"""Get statistics grouped by purchase location"""
results = self.sql.fetchall('statistics/purchase_locations')
return [dict(row) for row in results]
def get_financial_summary(self) -> dict[str, Any]:
"""Get financial summary from overview statistics"""
overview = self.get_overview()
return {
'total_cost': overview.get('total_cost', 0),
'average_cost': overview.get('average_cost', 0),
'minimum_cost': overview.get('minimum_cost', 0),
'maximum_cost': overview.get('maximum_cost', 0),
'sets_with_price': overview.get('sets_with_price', 0),
'total_sets': overview.get('total_sets', 0),
'percentage_with_price': round(
(overview.get('sets_with_price', 0) / max(overview.get('total_sets', 1), 1)) * 100, 1
)
}
def get_collection_summary(self) -> dict[str, Any]:
"""Get collection summary from overview statistics"""
overview = self.get_overview()
return {
'total_sets': overview.get('total_sets', 0),
'unique_sets': overview.get('unique_sets', 0),
'total_parts_count': overview.get('total_parts_count', 0),
'unique_parts': overview.get('unique_parts', 0),
'total_minifigures_count': overview.get('total_minifigures_count', 0),
'unique_minifigures': overview.get('unique_minifigures', 0),
'total_missing_parts': overview.get('total_missing_parts', 0),
'total_damaged_parts': overview.get('total_damaged_parts', 0),
'storage_locations_used': overview.get('storage_locations_used', 0),
'purchase_locations_used': overview.get('purchase_locations_used', 0)
}
def get_sets_by_year_statistics(self) -> list[dict[str, Any]]:
"""Get statistics grouped by LEGO set release year"""
results = self.sql.fetchall('statistics/sets_by_year')
return [dict(row) for row in results]
def get_purchases_by_year_statistics(self) -> list[dict[str, Any]]:
"""Get statistics grouped by purchase year"""
results = self.sql.fetchall('statistics/purchases_by_year')
return [dict(row) for row in results]
def get_year_summary(self) -> dict[str, Any]:
"""Get year-based summary statistics"""
sets_by_year = self.get_sets_by_year_statistics()
purchases_by_year = self.get_purchases_by_year_statistics()
# Calculate summary metrics
years_represented = len(sets_by_year)
years_with_purchases = len(purchases_by_year)
# Find peak year for collection (by set count)
peak_collection_year = None
max_sets_in_year = 0
if sets_by_year:
peak_year_data = max(sets_by_year, key=lambda x: x['total_sets'])
peak_collection_year = peak_year_data['year']
max_sets_in_year = peak_year_data['total_sets']
# Find peak spending year
peak_spending_year = None
max_spending = 0
if purchases_by_year:
spending_years = [y for y in purchases_by_year if y.get('total_spent')]
if spending_years:
peak_spending_data = max(spending_years, key=lambda x: x['total_spent'] or 0)
peak_spending_year = peak_spending_data['purchase_year']
max_spending = peak_spending_data['total_spent']
return {
'years_represented': years_represented,
'years_with_purchases': years_with_purchases,
'peak_collection_year': peak_collection_year,
'max_sets_in_year': max_sets_in_year,
'peak_spending_year': peak_spending_year,
'max_spending': max_spending,
'oldest_set_year': min([y['year'] for y in sets_by_year]) if sets_by_year else None,
'newest_set_year': max([y['year'] for y in sets_by_year]) if sets_by_year else None
}