alidenewade commited on
Commit
7990da4
·
verified ·
1 Parent(s): 0b55761

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -34
app.py CHANGED
@@ -93,8 +93,8 @@ with gr.Blocks() as demo:
93
  generate_btn = gr.Button("Generate Model Points", variant="primary")
94
 
95
  with gr.Column(scale=2):
96
- model_points_display = gr.Dataframe(label="Generated Model Points", wrap=True, height=400)
97
- download_excel_btn = gr.DownloadButton(label="Download Excel", variant="secondary") # Removed value, will be set by click
98
  gr.Markdown("---")
99
  gr.Markdown("## 📊 Data Summary & Analysis")
100
  with gr.Tabs():
@@ -104,8 +104,6 @@ with gr.Blocks() as demo:
104
  gr.Markdown("Distribution of **Sum Assured**. Data is generated uniformly; a normal curve is fitted for illustration.")
105
  distribution_plot_display = gr.Plot()
106
  with gr.TabItem("Categorical Summary"):
107
- # For simplicity, we'll display sex distribution here.
108
- # You might want to add another Dataframe for policy_term or combine them.
109
  sex_summary_display = gr.Dataframe(label="Sex Distribution", wrap=True)
110
  policy_term_summary_display = gr.Dataframe(label="Policy Term Distribution", wrap=True)
111
 
@@ -119,7 +117,6 @@ with gr.Blocks() as demo:
119
  no_data_df_num = pd.DataFrame({'Message': ["No data generated or summary failed."]})
120
  no_data_df_cat = pd.DataFrame({'Message': ["No data generated or summary failed."]})
121
 
122
-
123
  current_df = df_state.value if df_state.value is not None else pd.DataFrame()
124
 
125
  if int(age_m) >= int(age_mx):
@@ -130,28 +127,27 @@ with gr.Blocks() as demo:
130
  return current_df, df_state.value, pd.DataFrame({'Error': ["Minimum Sum Assured must be less than Maximum Sum Assured."]}), empty_plot, pd.DataFrame({'Error': ["Minimum Sum Assured must be less than Maximum Sum Assured."]}), pd.DataFrame({'Error': ["Minimum Sum Assured must be less than Maximum Sum Assured."]})
131
  if not p_terms:
132
  gr.Warning("At least one Policy Term must be selected. Using defaults.")
133
- p_terms = [10, 15, 20] # Apply default if none selected
134
 
135
  gr.Info("Generating model points... Please wait.")
136
  try:
137
  df = generate_custom_model_points(mp_c, s, age_m, age_mx, sa_m, sa_mx, p_terms, incl_sex, pc_fixed)
138
  gr.Info(f"{len(df)} model points generated successfully!")
139
 
140
- # Numerical Summary
141
- numerical_cols = ['age_at_entry', 'sum_assured', 'duration_mth', 'policy_count']
142
- existing_numerical_cols = [col for col in numerical_cols if col in df.columns]
143
  desc_stats_df = no_data_df_num
144
- if existing_numerical_cols and not df.empty:
145
- desc_stats = df[existing_numerical_cols].describe().transpose()
146
- if 'count' in desc_stats.columns:
147
- desc_stats['count'] = desc_stats['count'].astype(int)
148
- # Gradio Dataframe handles formatting, so raw numbers are fine
149
- desc_stats_df = desc_stats.reset_index().rename(columns={'index': 'Statistic'})
 
 
 
 
150
  elif df.empty:
151
  desc_stats_df = pd.DataFrame({'Message': ["DataFrame is empty, no numerical data to describe."]})
152
 
153
-
154
- # Distribution Plot
155
  fig = empty_plot
156
  if 'sum_assured' in df.columns and not df['sum_assured'].empty:
157
  fig, ax = plt.subplots(figsize=(8, 5))
@@ -167,9 +163,7 @@ with gr.Blocks() as demo:
167
  ax.legend()
168
  ax.grid(axis='y', linestyle='--', alpha=0.7)
169
  plt.tight_layout()
170
- # Removed plot_object = fig, fig is directly returned
171
 
172
- # Categorical Summary
173
  sex_counts_df = no_data_df_cat
174
  term_counts_df = no_data_df_cat
175
 
@@ -177,7 +171,7 @@ with gr.Blocks() as demo:
177
  if 'sex' in df.columns:
178
  sex_counts = df['sex'].value_counts().reset_index()
179
  sex_counts.columns = ['Sex', 'Count']
180
- sex_counts['Percentage'] = (sex_counts['Count'] / sex_counts['Count'].sum() * 100).round(2) # Keep as number for potential sorting in Dataframe
181
  sex_counts_df = sex_counts
182
  else:
183
  sex_counts_df = pd.DataFrame({'Message': ["'sex' column not found or data is empty."]})
@@ -185,7 +179,7 @@ with gr.Blocks() as demo:
185
  if 'policy_term' in df.columns:
186
  term_counts = df['policy_term'].value_counts().sort_index().reset_index()
187
  term_counts.columns = ['Policy Term (Years)', 'Count']
188
- term_counts['Percentage'] = (term_counts['Count'] / term_counts['Count'].sum() * 100).round(2) # Keep as number
189
  term_counts_df = term_counts
190
  else:
191
  term_counts_df = pd.DataFrame({'Message': ["'policy_term' column not found or data is empty."]})
@@ -193,7 +187,6 @@ with gr.Blocks() as demo:
193
  sex_counts_df = pd.DataFrame({'Message': ["DataFrame is empty, no categorical data for 'sex'."]})
194
  term_counts_df = pd.DataFrame({'Message': ["DataFrame is empty, no categorical data for 'policy_term'."]})
195
 
196
-
197
  return df, df, desc_stats_df, fig, sex_counts_df, term_counts_df
198
 
199
  except Exception as e:
@@ -205,18 +198,13 @@ with gr.Blocks() as demo:
205
  def handle_download_button_click(current_df_to_download):
206
  if current_df_to_download is None or not isinstance(current_df_to_download, pd.DataFrame) or current_df_to_download.empty:
207
  gr.Warning("No data available to download. Generate model points first.")
208
- # Return a dummy file path or None if Gradio handles it gracefully for gr.DownloadButton
209
- # For safety, returning a named file path that won't be created avoids errors.
210
- return gr.DownloadButton.update(interactive=False) # Or simply return None if that works for your Gradio version.
211
 
212
  excel_output = io.BytesIO()
213
- # Ensure 'Statistic' column from describe().transpose().reset_index() is handled if it exists
214
- # The main df (current_df_to_download) should be fine as is.
215
  current_df_to_download.to_excel(excel_output, sheet_name='ModelPoints', engine='xlsxwriter', index=False)
216
  excel_output.seek(0)
217
- # When returning a file for gr.DownloadButton, Gradio expects a file path or a BytesIO object
218
- # The 'value' of the DownloadButton component itself is not what's downloaded.
219
- # The function should return the file object.
220
  return gr.File(file_path=excel_output, file_name="model_points.xlsx", visible=True)
221
 
222
 
@@ -235,13 +223,10 @@ with gr.Blocks() as demo:
235
  ]
236
  )
237
 
238
- # The DownloadButton's click function should return the file object to the button itself.
239
- # The `value` parameter in gr.DownloadButton is for the initial filename,
240
- # but the actual file content comes from the function's return.
241
  download_excel_btn.click(
242
  fn=handle_download_button_click,
243
  inputs=[df_state],
244
- outputs=[download_excel_btn] # The output should be the button itself to receive the file
245
  )
246
 
247
  if __name__ == "__main__":
 
93
  generate_btn = gr.Button("Generate Model Points", variant="primary")
94
 
95
  with gr.Column(scale=2):
96
+ model_points_display = gr.Dataframe(label="Generated Model Points", wrap=True) # CORRECTED: Removed height=400
97
+ download_excel_btn = gr.DownloadButton(label="Download Excel", variant="secondary")
98
  gr.Markdown("---")
99
  gr.Markdown("## 📊 Data Summary & Analysis")
100
  with gr.Tabs():
 
104
  gr.Markdown("Distribution of **Sum Assured**. Data is generated uniformly; a normal curve is fitted for illustration.")
105
  distribution_plot_display = gr.Plot()
106
  with gr.TabItem("Categorical Summary"):
 
 
107
  sex_summary_display = gr.Dataframe(label="Sex Distribution", wrap=True)
108
  policy_term_summary_display = gr.Dataframe(label="Policy Term Distribution", wrap=True)
109
 
 
117
  no_data_df_num = pd.DataFrame({'Message': ["No data generated or summary failed."]})
118
  no_data_df_cat = pd.DataFrame({'Message': ["No data generated or summary failed."]})
119
 
 
120
  current_df = df_state.value if df_state.value is not None else pd.DataFrame()
121
 
122
  if int(age_m) >= int(age_mx):
 
127
  return current_df, df_state.value, pd.DataFrame({'Error': ["Minimum Sum Assured must be less than Maximum Sum Assured."]}), empty_plot, pd.DataFrame({'Error': ["Minimum Sum Assured must be less than Maximum Sum Assured."]}), pd.DataFrame({'Error': ["Minimum Sum Assured must be less than Maximum Sum Assured."]})
128
  if not p_terms:
129
  gr.Warning("At least one Policy Term must be selected. Using defaults.")
130
+ p_terms = [10, 15, 20]
131
 
132
  gr.Info("Generating model points... Please wait.")
133
  try:
134
  df = generate_custom_model_points(mp_c, s, age_m, age_mx, sa_m, sa_mx, p_terms, incl_sex, pc_fixed)
135
  gr.Info(f"{len(df)} model points generated successfully!")
136
 
 
 
 
137
  desc_stats_df = no_data_df_num
138
+ if not df.empty:
139
+ numerical_cols = ['age_at_entry', 'sum_assured', 'duration_mth', 'policy_count']
140
+ existing_numerical_cols = [col for col in numerical_cols if col in df.columns]
141
+ if existing_numerical_cols:
142
+ desc_stats = df[existing_numerical_cols].describe().transpose()
143
+ if 'count' in desc_stats.columns:
144
+ desc_stats['count'] = desc_stats['count'].astype(int)
145
+ desc_stats_df = desc_stats.reset_index().rename(columns={'index': 'Statistic'})
146
+ else:
147
+ desc_stats_df = pd.DataFrame({'Message': ["No numerical columns found for summary."]})
148
  elif df.empty:
149
  desc_stats_df = pd.DataFrame({'Message': ["DataFrame is empty, no numerical data to describe."]})
150
 
 
 
151
  fig = empty_plot
152
  if 'sum_assured' in df.columns and not df['sum_assured'].empty:
153
  fig, ax = plt.subplots(figsize=(8, 5))
 
163
  ax.legend()
164
  ax.grid(axis='y', linestyle='--', alpha=0.7)
165
  plt.tight_layout()
 
166
 
 
167
  sex_counts_df = no_data_df_cat
168
  term_counts_df = no_data_df_cat
169
 
 
171
  if 'sex' in df.columns:
172
  sex_counts = df['sex'].value_counts().reset_index()
173
  sex_counts.columns = ['Sex', 'Count']
174
+ sex_counts['Percentage'] = (sex_counts['Count'] / sex_counts['Count'].sum() * 100).round(2)
175
  sex_counts_df = sex_counts
176
  else:
177
  sex_counts_df = pd.DataFrame({'Message': ["'sex' column not found or data is empty."]})
 
179
  if 'policy_term' in df.columns:
180
  term_counts = df['policy_term'].value_counts().sort_index().reset_index()
181
  term_counts.columns = ['Policy Term (Years)', 'Count']
182
+ term_counts['Percentage'] = (term_counts['Count'] / term_counts['Count'].sum() * 100).round(2)
183
  term_counts_df = term_counts
184
  else:
185
  term_counts_df = pd.DataFrame({'Message': ["'policy_term' column not found or data is empty."]})
 
187
  sex_counts_df = pd.DataFrame({'Message': ["DataFrame is empty, no categorical data for 'sex'."]})
188
  term_counts_df = pd.DataFrame({'Message': ["DataFrame is empty, no categorical data for 'policy_term'."]})
189
 
 
190
  return df, df, desc_stats_df, fig, sex_counts_df, term_counts_df
191
 
192
  except Exception as e:
 
198
  def handle_download_button_click(current_df_to_download):
199
  if current_df_to_download is None or not isinstance(current_df_to_download, pd.DataFrame) or current_df_to_download.empty:
200
  gr.Warning("No data available to download. Generate model points first.")
201
+ return gr.DownloadButton.update(interactive=False)
 
 
202
 
203
  excel_output = io.BytesIO()
 
 
204
  current_df_to_download.to_excel(excel_output, sheet_name='ModelPoints', engine='xlsxwriter', index=False)
205
  excel_output.seek(0)
206
+ # Returning a BytesIO object directly for file download
207
+ # Provide a filename for the browser
 
208
  return gr.File(file_path=excel_output, file_name="model_points.xlsx", visible=True)
209
 
210
 
 
223
  ]
224
  )
225
 
 
 
 
226
  download_excel_btn.click(
227
  fn=handle_download_button_click,
228
  inputs=[df_state],
229
+ outputs=[download_excel_btn]
230
  )
231
 
232
  if __name__ == "__main__":