File size: 2,829 Bytes
74e6fc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import gradio as gr
import pandas as pd
import plotly.express as px

def clean_and_analyze(file):
    if file is None:
        return None, "Please upload a file.", gr.update(choices=[])
    
    # Load data
    try:
        if file.name.endswith('.csv'):
            df_raw = pd.read_csv(file.name, header=None)
        else:
            df_raw = pd.read_excel(file.name, header=None)
        
        # Smart Header Detection (Finding the 'real' table start)
        non_null_counts = df_raw.notnull().sum(axis=1)
        header_idx = non_null_counts.idxmax()
        
        df = df_raw.iloc[header_idx + 1:].reset_index(drop=True)
        df.columns = [str(c).strip() for c in df_raw.iloc[header_idx].values]
        df = df.dropna(axis=1, how='all').dropna(axis=0, how='all')

        # Convert numeric columns automatically
        for col in df.columns:
            numeric_conv = pd.to_numeric(df[col], errors='coerce')
            if numeric_conv.notnull().sum() > (len(df) * 0.4):
                df[col] = numeric_conv

        cols = df.columns.tolist()
        summary = f"✅ Successfully cleaned! Found {len(df)} rows and {len(cols)} columns."
        
        return df, summary, gr.update(choices=cols, value=cols[0]), gr.update(choices=cols, value=cols[-1])
    except Exception as e:
        return None, f"Error: {str(e)}", gr.update(choices=[]), gr.update(choices=[])

def create_plot(df, x_col, y_col):
    if df is None:
        return None
    fig = px.bar(df, x=x_col, y=y_col, color=y_col, 
                 title=f"{y_col} Analysis", template="plotly_white")
    return fig

# --- Gradio UI Layout ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 📊 Course Quality Tracker (Product Ops)")
    gr.Markdown("Upload raw exports (Zoom, LMS, CSV) and generate instant quality reports.")
    
    current_data = gr.State()
    
    with gr.Row():
        file_input = gr.File(label="Upload Messy CSV or Excel")
        with gr.Column():
            status_msg = gr.Textbox(label="System Status", interactive=False)
            x_sel = gr.Dropdown(label="Select Course/Identity Column")
            y_sel = gr.Dropdown(label="Select Quality Metric (Numeric)")
            plot_btn = gr.Button("Generate Insights", variant="primary")

    with gr.Tabs():
        with gr.TabItem("Visualization"):
            plot_output = gr.Plot()
        with gr.TabItem("Cleaned Data"):
            table_output = gr.DataFrame()

    # Logic Flows
    file_input.change(
        clean_and_analyze, 
        inputs=[file_input], 
        outputs=[current_data, status_msg, x_sel, y_sel]
    ).then(lambda df: df, inputs=[current_data], outputs=[table_output])

    plot_btn.click(
        create_plot, 
        inputs=[current_data, x_sel, y_sel], 
        outputs=[plot_output]
    )

demo.launch()