249 lines
9.4 KiB
Plaintext
249 lines
9.4 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Setup Django environment\n",
|
|
"import os\n",
|
|
"import sys\n",
|
|
"import django\n",
|
|
"\n",
|
|
"# Set up Django environment\n",
|
|
"os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'car_inventory.settings')\n",
|
|
"django.setup()\n",
|
|
"\n",
|
|
"# Import models\n",
|
|
"from inventory.models import CarMake, CarModel, CarSerie, CarTrim"
|
|
],
|
|
"id": "64ce4f8ed9e90534"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get all car makes\n",
|
|
"all_makes = CarMake.objects.all()\n",
|
|
"total_makes = all_makes.count()\n",
|
|
"\n",
|
|
"# Find makes without models using annotations\n",
|
|
"from django.db.models import Count\n",
|
|
"makes_without_models = CarMake.objects.annotate(model_count=Count('carmodel')).filter(model_count=0)\n",
|
|
"makes_without_models_count = makes_without_models.count()\n",
|
|
"\n",
|
|
"print(f\"Total car makes: {total_makes}\")\n",
|
|
"print(f\"Car makes without models: {makes_without_models_count} ({makes_without_models_count/total_makes*100:.2f}%)\")\n",
|
|
"\n",
|
|
"# Display the first 10 makes without models\n",
|
|
"if makes_without_models:\n",
|
|
" print(\"\\nSample of car makes without models:\")\n",
|
|
" for make in makes_without_models[:10]:\n",
|
|
" print(f"
|
|
],
|
|
"id": "7807a14272fbf44b"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get all car models\n",
|
|
"all_models = CarModel.objects.all()\n",
|
|
"total_models = all_models.count()\n",
|
|
"\n",
|
|
"# Find models without series using annotations\n",
|
|
"models_without_series = CarModel.objects.annotate(serie_count=Count('carserie')).filter(serie_count=0)\n",
|
|
"models_without_series_count = models_without_series.count()\n",
|
|
"\n",
|
|
"print(f\"\\nTotal car models: {total_models}\")\n",
|
|
"print(f\"Car models without series: {models_without_series_count} ({models_without_series_count/total_models*100:.2f}%)\")\n",
|
|
"\n",
|
|
"# Display the first 10 models without series\n",
|
|
"if models_without_series:\n",
|
|
" print(\"\\nSample of car models without series:\")\n",
|
|
" for model in models_without_series[:10]:\n",
|
|
" print(f\"- {model.name} (Make: {model.id_car_make."
|
|
],
|
|
"id": "318b5426d54f0705"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get all car series\n",
|
|
"all_series = CarSerie.objects.all()\n",
|
|
"total_series = all_series.count()\n",
|
|
"\n",
|
|
"# Find series without trims using annotations\n",
|
|
"series_without_trims = CarSerie.objects.annotate(trim_count=Count('cartrim')).filter(trim_count=0)\n",
|
|
"series_without_trims_count = series_without_trims.count()\n",
|
|
"\n",
|
|
"print(f\"\\nTotal car series: {total_series}\")\n",
|
|
"print(f\"Car series without trims: {series_without_trims_count} ({series_without_trims_count/total_series*100:.2f}%)\")\n",
|
|
"\n",
|
|
"# Display the first 10 series without trims\n",
|
|
"if series_without_trims:\n",
|
|
" print(\"\\nSample of car series without trims:\")\n",
|
|
" for serie in series_without_trims[:10]:\n",
|
|
" print(f\"- {serie.name} (Model: {serie.id_car_model.name}, Make: {serie.id_car_model.id_car_make."
|
|
],
|
|
"id": "30eaf3383d2b34e1"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"# Data for the chart\n",
|
|
"categories = ['Makes', 'Models', 'Series']\n",
|
|
"total_counts = [total_makes, total_models, total_series]\n",
|
|
"empty_counts = [makes_without_models_count, models_without_series_count, series_without_trims_count]\n",
|
|
"with_children_counts = [total_makes - makes_without_models_count,\n",
|
|
" total_models - models_without_series_count,\n",
|
|
" total_series - series_without_trims_count]\n",
|
|
"\n",
|
|
"# Create a figure with two subplots\n",
|
|
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))\n",
|
|
"\n",
|
|
"# Bar chart showing total vs. without children\n",
|
|
"x = np.arange(len(categories))\n",
|
|
"width = 0.35\n",
|
|
"\n",
|
|
"ax1.bar(x - width/2, total_counts, width, label='Total')\n",
|
|
"ax1.bar(x + width/2, empty_counts, width, label='Without children')\n",
|
|
"ax1.set_xticks(x)\n",
|
|
"ax1.set_xticklabels(categories)\n",
|
|
"ax1.set_ylabel('Count')\n",
|
|
"ax1.set_title('Car Hierarchy Analysis')\n",
|
|
"ax1.legend()\n",
|
|
"\n",
|
|
"# Pie charts showing percentage with/without children\n",
|
|
"labels = ['With children', 'Without children']\n",
|
|
"sizes = [[with_children_counts[i], empty_counts[i]] for i in range(3)]\n",
|
|
"colors = [['#66b3ff', '#ff9999'], ['#99ff99', '#ffcc99'], ['#c2c2f0', '#ffb3e6']]\n",
|
|
"\n",
|
|
"for i, category in enumerate(categories):\n",
|
|
" if i == 0:\n",
|
|
" ax2.pie(sizes[i], labels=labels, colors=colors[i], autopct='%1.1f%%',\n",
|
|
" startangle=90, wedgeprops={'alpha':0.7})\n",
|
|
" centre_circle = plt.Circle((0,0),0.70,fc='white')\n",
|
|
" ax2.add_patch(centre_circle)\n",
|
|
" ax2.text(0, 0, category, horizontalalignment='center', verticalalignment='center')\n",
|
|
" else:\n",
|
|
" # Calculate position for smaller pie charts\n",
|
|
" x_offset = 1.2 * (i-1)\n",
|
|
" ax2.pie(sizes[i], colors=colors[i], autopct='%1.1f%%',\n",
|
|
" startangle=90, wedgeprops={'alpha':0.7},\n",
|
|
" center=(x_offset, 0), radius=0.5)\n",
|
|
" centre_circle = plt.Circle((x_offset,0),0.35,fc='white')\n",
|
|
" ax2.add_patch(centre_circle)\n",
|
|
" ax2.text(x_offset, 0, category, horizontalalignment='center', verticalalignment='center')\n",
|
|
"\n",
|
|
"ax2.axis('equal')\n",
|
|
"ax2.set_title('Percentage Distribution')\n",
|
|
"\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
],
|
|
"id": "d23f0edf1ff334f7"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Find all trims and go up the hierarchy to find complete chains\n",
|
|
"complete_hierarchies = []\n",
|
|
"\n",
|
|
"for trim in CarTrim.objects.select_related('id_car_serie__id_car_model__id_car_make')[:20]:\n",
|
|
" serie = trim.id_car_serie\n",
|
|
" model = serie.id_car_model\n",
|
|
" make = model.id_car_make\n",
|
|
"\n",
|
|
" complete_hierarchies.append({\n",
|
|
" 'make': make.name,\n",
|
|
" 'model': model.name,\n",
|
|
" 'serie': serie.name,\n",
|
|
" 'trim': trim.name\n",
|
|
" })\n",
|
|
"\n",
|
|
"# Display as a formatted table\n",
|
|
"from IPython.display import display, HTML\n",
|
|
"import pandas as pd\n",
|
|
"\n",
|
|
"if complete_hierarchies:\n",
|
|
" print(\"\\nSample of complete car hierarchies:\")\n",
|
|
" df = pd.DataFrame(complete_hierarchies)\n",
|
|
" display(HTML(df.to_html(index=False"
|
|
],
|
|
"id": "3cd9822a8ac1a880"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Create DataFrames for export\n",
|
|
"import pandas as pd\n",
|
|
"\n",
|
|
"# Makes without models\n",
|
|
"makes_without_models_df = pd.DataFrame({\n",
|
|
" 'make_id': [make.id_car_make for make in makes_without_models],\n",
|
|
" 'make_name': [make.name for make in makes_without_models],\n",
|
|
" 'is_sa_import': [make.is_sa_import for make in makes_without_models]\n",
|
|
"})\n",
|
|
"\n",
|
|
"# Models without series\n",
|
|
"models_without_series_df = pd.DataFrame({\n",
|
|
" 'model_id': [model.id_car_model for model in models_without_series],\n",
|
|
" 'model_name': [model.name for model in models_without_series],\n",
|
|
" 'make_id': [model.id_car_make.id_car_make for model in models_without_series],\n",
|
|
" 'make_name': [model.id_car_make.name for model in models_without_series]\n",
|
|
"})\n",
|
|
"\n",
|
|
"# Series without trims\n",
|
|
"series_without_trims_df = pd.DataFrame({\n",
|
|
" 'serie_id': [serie.id_car_serie for serie in series_without_trims],\n",
|
|
" 'serie_name': [serie.name for serie in series_without_trims],\n",
|
|
" 'model_id': [serie.id_car_model.id_car_model for serie in series_without_trims],\n",
|
|
" 'model_name': [serie.id_car_model.name for serie in series_without_trims],\n",
|
|
" 'make_id': [serie.id_car_model.id_car_make.id_car_make for serie in series_without_trims],\n",
|
|
" 'make_name': [serie.id_car_model.id_car_make.name for serie in series_without_trims]\n",
|
|
"})\n",
|
|
"\n",
|
|
"# Save to CSV files (uncomment to use)\n",
|
|
"# makes_without_models_df.to_csv('makes_without_models.csv', index=False)\n",
|
|
"# models_without_series_df.to_csv('models_without_series.csv', index=False)\n",
|
|
"# series_without_trims_df.to_csv('series_without_trims.csv', index=False)\n",
|
|
"\n",
|
|
"# Display the first few rows of each DataFrame\n",
|
|
"print(\"\\nMakes without models (first 5):\")\n",
|
|
"display(makes_without_models_df.head())\n",
|
|
"\n",
|
|
"print(\"\\nModels without series (first 5):\")\n",
|
|
"display(models_without_series_df.head())\n",
|
|
"\n",
|
|
"print(\"\\nSeries without trims (first 5):\")\n",
|
|
"display(series_without_trims_df.head())"
|
|
],
|
|
"id": "6edeb052b327a48c"
|
|
}
|
|
],
|
|
"metadata": {},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|