File size: 4,489 Bytes
798602c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# ui/tabs/estimation/descriptive_tab.py

import gradio as gr
from controllers.estimation.descriptive_controller import run_descriptive_statistics
from controllers.utils.downloads import dataframe_to_csv


def build(state):
    gr.Markdown("## ๐Ÿงฎ Descriptive Statistics")

    # ---------------------------
    # Controls
    # ---------------------------
    with gr.Row():
        refresh_button = gr.Button("๐Ÿ”„ Refresh Numeric Columns")

        column_dropdown = gr.Dropdown(
            label="Select Numeric Variable",
            choices=[],
            interactive=True,
            elem_classes=["data-selector"],
            elem_id="custom_dropdown",
        )

        weights_dropdown = gr.Dropdown(
            label="Weights Column (optional)",
            choices=["โ€” None โ€”"],
            value="โ€” None โ€”",
            interactive=True,
            elem_classes=["data-selector"],
            elem_id="custom_dropdown",
        )

    with gr.Row():
        quantiles_input = gr.Textbox(
            label="Quantiles",
            value="0.25, 0.5, 0.75",
        )

        trim_input = gr.Textbox(
            label="Trimmed Mean ฮฑ",
            value="0.1",
        )

        winsor_input = gr.Textbox(
            label="Winsorized Limits",
            value="0.1, 0.1",
        )

    with gr.Column(elem_id="column_centered"):
        run_button = gr.Button("๐Ÿš€ Run Descriptive Statistics", elem_id="run_button")

    with gr.Row(visible=False) as download_row:
        filename_input = gr.Textbox(
            label="Filename (without extension)",
            placeholder="e.g. descriptive_stats",
        )
        download_button = gr.Button("๐Ÿ’พ Download Table as CSV")
        download_file = gr.File(
            label="Download link will appear here",
            interactive=False,
        )

    output_table = gr.Dataframe(
        label="Descriptive Statistics",
        interactive=False,
    )

    # ---------------------------
    # Helpers
    # ---------------------------
    def refresh_columns():
        numeric_cols = state.numeric_cols or []
        return (
            gr.update(choices=numeric_cols),
            gr.update(choices=["โ€” None โ€”"] + numeric_cols, value="โ€” None โ€”"),
        )

    def parse_quantiles(text):
        return [float(x.strip()) for x in text.split(",") if x.strip()]

    def parse_trim(text):
        return None if not text.strip() else float(text)

    def parse_winsor(text):
        if not text.strip():
            return None
        vals = [float(x.strip()) for x in text.split(",")]
        if len(vals) != 2:
            raise ValueError("Winsor limits must be two values.")
        return tuple(vals)

    def on_run(column, weights_col, q_text, trim_text, winsor_text):
        df = state.filtered_df if state.filtered_df is not None else state.df

        if df is None:
            return [], gr.update(visible=False), gr.update(visible=False)

        if weights_col == "โ€” None โ€”":
            weights_col = None

        stats_df = run_descriptive_statistics(
            df=df,
            column=column,
            quantile_probs=parse_quantiles(q_text),
            trim_alpha=parse_trim(trim_text),
            winsor_limits=parse_winsor(winsor_text),
            weights_col=weights_col,
            round_digits=4,
        )

        # cache for download
        state.export_table = stats_df

        return (
            stats_df,
            gr.update(visible=True),   # show download row
            gr.update(visible=True),   # show file output
        )

    def on_download(filename):
        return dataframe_to_csv(state.export_table, filename)

    # ---------------------------
    # Events
    # ---------------------------
    download_button.click(
        fn=on_download,
        inputs=filename_input,
        outputs=download_file,
    )

    refresh_button.click(
        fn=refresh_columns,
        inputs=[],
        outputs=[column_dropdown, weights_dropdown],
    )

    run_button.click(
        fn=on_run,
        inputs=[
            column_dropdown,
            weights_dropdown,
            quantiles_input,
            trim_input,
            winsor_input,
        ],
        outputs=[
            output_table,
            download_row,
            download_file,
        ],
    )