import gradio as gr import pandas as pd import json from pathlib import Path # Load data def load_data(): tables = Path("artifacts/tables") figures = Path("artifacts/figures") app_summary = pd.read_csv(tables / "app_summary.csv") pricing = pd.read_csv(tables / "pricing_decisions.csv") sentiment = pd.read_csv(tables / "sentiment_per_app.csv") with open(figures / "kpis.json") as f: kpis = json.load(f) return app_summary, pricing, sentiment, kpis def get_overview(): app_summary, pricing, sentiment, kpis = load_data() return ( f"Total Apps Analyzed: {kpis['total_apps']}", f"Real Reviews Scraped: {kpis['total_real_reviews']}", f"Synthetic Reviews: {kpis['total_synthetic_reviews']}", f"Months Analyzed: {kpis['months_analyzed']}", f"Best Satisfaction: {kpis['best_app_satisfaction']}", f"Highest Churn Risk: {kpis['highest_churn_app']}", f"Lowest Churn Risk: {kpis['lowest_churn_app']}" ) with gr.Blocks(title="Productivity App Analyzer", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # Productivity App Analyzer ### AI for Big Data Management — ESCP Business School *Analyzing TickTick, Todoist, Microsoft To-Do, and Any.do using real reviews + synthetic data* """) # KPI Row with gr.Row(): kpi1 = gr.Textbox(label="Apps Analyzed", interactive=False) kpi2 = gr.Textbox(label="Real Reviews", interactive=False) kpi3 = gr.Textbox(label="Synthetic Reviews", interactive=False) kpi4 = gr.Textbox(label="Months Analyzed", interactive=False) with gr.Row(): kpi5 = gr.Textbox(label="Best Satisfaction", interactive=False) kpi6 = gr.Textbox(label="Highest Churn", interactive=False) kpi7 = gr.Textbox(label="Lowest Churn", interactive=False) # Charts gr.Markdown("## Visualizations") with gr.Tabs(): with gr.Tab("Sentiment Analysis"): gr.Image("artifacts/figures/sentiment_per_app.png", label="Sentiment Distribution per App") with gr.Tab("Churn & Satisfaction"): gr.Image("artifacts/figures/churn_satisfaction_per_app.png", label="Churn Risk & Satisfaction Scores") with gr.Tab("Usage Trends"): gr.Image("artifacts/figures/monthly_usage_trends.png", label="Monthly Active Users - 18 Months") with gr.Tab("ARIMA Forecasts"): gr.Image("artifacts/figures/arima_forecasts.png", label="6-Month User Forecasts per App") # Pricing Decisions gr.Markdown("## Pricing Recommendations") def get_pricing_table(): _, pricing, _, _ = load_data() return pricing[["app_name", "positive_ratio", "negative_ratio", "avg_churn", "avg_satisfaction", "pricing_action"]].round(3) pricing_table = gr.Dataframe( label="Rule-Based Pricing Decisions", interactive=False ) # App Summary gr.Markdown("## App Performance Summary") summary_table = gr.Dataframe( label="Average Churn, Satisfaction & Daily Tasks", interactive=False ) # Load on startup def load_all(): app_summary, pricing, sentiment, kpis = load_data() k = get_overview() pricing_df = pricing[["app_name", "positive_ratio", "negative_ratio", "avg_churn", "avg_satisfaction", "pricing_action"]].round(3) return (*k, pricing_df, app_summary) demo.load( fn=load_all, outputs=[kpi1, kpi2, kpi3, kpi4, kpi5, kpi6, kpi7, pricing_table, summary_table] ) gr.Markdown(""" --- *Data: 400 real Google Play reviews + 4,000 synthetic reviews | Methods: VADER Sentiment, ARIMA Forecasting, Rule-Based Pricing* """) demo.launch()