Python
Make this a .py file that I can download

import subprocess
import sys

# Function to install missing packages
def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

# List of required packages
required_packages = ['pandas', 'numpy', 'plotly', 'scipy', 'matplotlib']

# Install missing packages
for package in required_packages:
    try:
        __import__(package)
    except ImportError:
        print(f"Installing {package}...")
        install(package)

# Import libraries after ensuring installation
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from datetime import datetime, timedelta
from scipy.stats import poisson
import random
import matplotlib.pyplot as plt

# Step 1: Generate Inventory Data for the Dessert Bar
def generate_inventory_data(items):
    """ Generate inventory data for each dessert item. """
    return pd.DataFrame({
        "Item": items,
        "Starting_Stock": np.random.randint(100, 500, size=len(items)),
        "Reorder_Threshold": np.random.randint(10, 30, size=len(items)),
        "Cost_Per_Item": np.random.uniform(8.0, 40.0, size=len(items)),
        "Selling_Price": np.random.uniform(15.0, 75.0, size=len(items))
    })

# Step 2: Generate Customer Preferences
def generate_customer_preferences(items):
    """ Generate customer preferences for dessert items. """
    return {item: random.uniform(0.5, 1.0) for item in items}

# Step 3: Generate Advanced Sales Data with Seasonality and Events
def generate_sales_data(inventory_df, start_date, days, preferences):
    """ Generate sales data over a specified number of days. """
    sales_data = []
    for day in range(days):
        date = start_date + timedelta(days=day)
        holiday_multiplier = 3 if date.month == 12 and date.day in [24, 25, 31] else 1  # Holiday effect
        for index, row in inventory_df.iterrows():
            preference_factor = preferences[row["Item"]] + np.random.normal(0, 0.1)
            preference_factor = max(min(preference_factor, 1), 0)  # Ensure it's between 0 and 1
            seasonal_variation = 15 * np.sin((2 * np.pi / 30) * day)  # Monthly seasonality
            lambda_val = (25 * preference_factor + seasonal_variation) * holiday_multiplier
            sales_quantity = int(poisson.rvs(max(lambda_val, 1)))
            sales_data.append({
                "Date": date,
                "Item": row["Item"],
                "Sales": max(sales_quantity, 0)
            })
    return pd.DataFrame(sales_data)

# Step 4: Advanced Sales Trend Analysis
def analyze_sales_trends(sales_df):
    """ Analyze sales trends and calculate moving averages. """
    sales_summary = sales_df.groupby(['Date', 'Item']).sum().reset_index()
    sales_summary['Sales_MA'] = sales_summary.groupby('Item')['Sales'].transform(lambda x: x.rolling(window=7, min_periods=1).mean())
    sales_summary['Sales_Change'] = sales_summary.groupby('Item')['Sales'].pct_change().fillna(0)
    return sales_summary

# Step 5: Inventory Tracking and Replenishment Alerts
def track_inventory_replenishment(inventory_df, sales_df):
    """ Track remaining stock and alert for replenishment. """
    sales_summary = sales_df.groupby('Item')['Sales'].sum().reset_index()
    inventory_df = pd.merge(inventory_df, sales_summary, on='Item', how='left')
    inventory_df['Sales'] = inventory_df['Sales'].fillna(0)
    inventory_df['Remaining_Stock'] = inventory_df['Starting_Stock'] - inventory_df['Sales']
    inventory_df['Replenish'] = inventory_df['Remaining_Stock'] < inventory_df['Reorder_Threshold']
    return inventory_df

# Step 6: Clear and Advanced Visualization of Sales Trends using Plotly
def plot_sales_trends(sales_summary):
    """ Create an advanced interactive plot of sales trends. """
    fig = go.Figure()

    # Clear colors and improved readability
    color_palette = ['#FF6347', '#4682B4', '#FFD700', '#20B2AA', '#ADFF2F', '#FFB6C1', '#9370DB', '#FFA07A']

    for idx, item in enumerate(sales_summary['Item'].unique()):
        item_data = sales_summary[sales_summary['Item'] == item]
        
        # Advanced bar for daily sales
        fig.add_trace(go.Bar(
            x=item_data['Date'], y=item_data['Sales'], name=f'Sales - {item}',
            marker=dict(color=color_palette[idx % len(color_palette)]),
            hoverinfo='y+name'
        ))

        # Line for moving average
        fig.add_trace(go.Scatter(
            x=item_data['Date'], y=item_data['Sales_MA'], mode='lines+markers',
            name=f'Moving Average - {item}',
            line=dict(color=color_palette[idx % len(color_palette)], dash='dash'),
            hoverinfo='y+name'
        ))

    # Modern, clean layout for improved readability
    fig.update_layout(
        title="Sales Trends at Premium Dessert Bar",
        title_x=0.5,
        title_font=dict(size=24, color='black'),
        xaxis_title="Date",
        yaxis_title="Sales Quantity",
        template="plotly_white",  # White background for clarity
        barmode='group',
        font=dict(size=14, color="black"),
        height=700,
        width=1200,
        showlegend=True,
        legend=dict(
            x=1.02,
            y=1,
            traceorder="normal",
            font=dict(size=12)
        )
    )

    # Enhance axis gridlines for visual clarity
    fig.update_xaxes(showgrid=True, gridwidth=0.5, gridcolor='lightgrey')
    fig.update_yaxes(showgrid=True, gridwidth=0.5, gridcolor='lightgrey')
    
    fig.show()

# Step 7: Optional Visualization with Matplotlib
def plot_sales_trends_matplotlib(sales_summary):
    """ Create a static plot of sales trends using Matplotlib. """
    plt.figure(figsize=(12, 8))
    
    # Clear colors and improved readability
    color_palette = ['#FF6347', '#4682B4', '#FFD700', '#20B2AA', '#ADFF2F', '#FFB6C1', '#9370DB', '#FFA07A']

    for idx, item in enumerate(sales_summary['Item'].unique()):
        item_data = sales_summary[sales_summary['Item'] == item]
        
        # Bar for daily sales
        plt.bar(item_data['Date'], item_data['Sales'], color=color_palette[idx % len(color_palette)], alpha=0.6, label=f'Sales - {item}')
        
        # Line for moving average
        plt.plot(item_data['Date'], item_data['Sales_MA'], color=color_palette[idx % len(color_palette)], linestyle='--', linewidth=2)

    # Modern, clean layout for improved readability
    plt.title("Sales Trends at Premium Dessert Bar", fontsize=24)
    plt.xlabel("Date", fontsize=16)
    plt.ylabel("Sales Quantity", fontsize=16)
    plt.xticks(rotation=45)
    plt.grid(axis='y', linestyle='--', alpha=0.7)
    plt.legend(loc='upper left', fontsize=12)
    plt.tight_layout()
    plt.show()

# Main Function: Dessert Bar Sales Simulation
def main():
    # Step 1: Expanded Premium Dessert Bar Menu
    items = [
        'Lavender Earl Grey Crème Brûlée', 'Pistachio Rosewater Mousse', 'Chocolate Hazelnut Torte',
        'Passion Fruit Pavlova', 'Matcha White Chocolate Tart', 'Saffron Panna Cotta', 
        'Dark Chocolate Fondant', 'Mango Coconut Macaron Tower', 'Lemon Basil Cheesecake', 
        'Blueberry Almond Tart', 'Vanilla Bean Soufflé', 'Caramelized Banana Mille-Feuille', 
        'Peach Bourbon Cobbler', 'Rose Lychee Sorbet', 'Salted Caramel Eclairs', 
        'Raspberry Chocolate Lava Cake'
    ]

    # Step 2: Generate Inventory Data
    inventory_df = generate_inventory_data(items)
    print("Inventory Data:\n", inventory_df)

    # Step 3: Generate Customer Preferences
    preferences = generate_customer_preferences(items)
    print("\nCustomer Preferences:\n", preferences)

    # Step 4: Generate Sales Data for 60 Days
    start_date = datetime(2024, 1, 1)
    days = 60
    sales_df = generate_sales_data(inventory_df, start_date, days, preferences)
    print("\nSales Data:\n", sales_df)

    # Step 5: Analyze Sales Trends
    sales_summary = analyze_sales_trends(sales_df)
    print("\nSales Summary:\n", sales_summary)

    # Step 6: Track Inventory and Replenishment
    inventory_status = track_inventory_replenishment(inventory_df, sales_df)
    print("\nInventory Status:\n", inventory_status)

    # Step 7: Visualize Sales Trends
    plot_sales_trends(sales_summary)

    # Optional Visualization with Matplotlib
    plot_sales_trends_matplotlib(sales_summary)

if __name__ == "__main__":
    main()