jeffrey1963 commited on
Commit
8b0f06f
·
verified ·
1 Parent(s): 10f3e4f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +6 -46
app.py CHANGED
@@ -39,15 +39,6 @@ def _coerce_numeric(x):
39
  try: return float(s)
40
  except: return pd.NA
41
 
42
- # ---- NEW: in‑memory file helpers (no disk writes) ----
43
- def _csv_bytes(df: pd.DataFrame | None) -> bytes:
44
- buf = io.StringIO()
45
- (df if df is not None else pd.DataFrame()).to_csv(buf, index=False)
46
- return buf.getvalue().encode("utf-8")
47
-
48
- def _text_bytes(txt: str | None) -> bytes:
49
- return (txt or "").encode("utf-8")
50
-
51
  PARAM_PATTERNS = {
52
  "cost": r"cost\s*[:=]\s*\$?\s*([\d,]+(?:\.\d+)?)",
53
  "salvage": r"salvage\s*[:=]\s*\$?\s*([\d,]+(?:\.\d+)?)",
@@ -251,8 +242,7 @@ def handle_docx(file):
251
 
252
  def handle_image(img):
253
  if img is None:
254
- # include empty bytes for download buttons
255
- return "(no image)", {}, pd.DataFrame(), pd.DataFrame(), b"", b"", b"", 0.0, 0.0, 10, pd.Timestamp.now().year, {}, pd.DataFrame()
256
 
257
  from PIL import Image as PILImage
258
  pil = img if isinstance(img, PILImage.Image) else PILImage.fromarray(img)
@@ -262,17 +252,6 @@ def handle_image(img):
262
  df_raw = _table_from_ocr_text(ocr_text or "")
263
  df_norm = _normalize_depr_columns(df_raw) if df_raw is not None else pd.DataFrame()
264
 
265
- # numerics (helps when you edit later)
266
- if not df_norm.empty:
267
- for c in ["Year","Begin BV","Depreciation","Accum Dep","End BV"]:
268
- if c in df_norm.columns:
269
- df_norm[c] = pd.to_numeric(df_norm[c], errors="coerce")
270
-
271
- # in‑memory artifacts
272
- raw_csv_bytes = _csv_bytes(df_raw)
273
- norm_csv_bytes = _csv_bytes(df_norm)
274
- txt_bytes = _text_bytes(ocr_text or "")
275
-
276
  cost, salv, life, year = _params_tuple(params)
277
 
278
  return (
@@ -280,14 +259,13 @@ def handle_image(img):
280
  params,
281
  df_raw, # raw table shown in OCR tab
282
  df_norm, # normalized table shown in OCR tab
283
- raw_csv_bytes, # bytes for RAW CSV download
284
- norm_csv_bytes, # bytes for NORMALIZED CSV download
285
- txt_bytes, # bytes for OCR TEXT download
286
  cost, salv, life, year, # auto-fill numbers
287
  params, # save params state
288
- df_norm # save normalized table to last_table
289
  )
290
 
 
 
291
  def fill_from_state(p):
292
  p = p or {}
293
  return (
@@ -313,7 +291,7 @@ def check_cb(cost, salv, life, year, table_state):
313
  if not isinstance(table_state, pd.DataFrame) or table_state.empty:
314
  return pd.DataFrame(), "No student table found to check."
315
 
316
- # re-normalize and coerce here every time
317
  actual = _normalize_depr_columns(table_state)
318
  for c in ["Year", "Begin BV", "Depreciation", "Accum Dep", "End BV"]:
319
  actual[c] = pd.to_numeric(actual[c], errors="coerce")
@@ -344,16 +322,7 @@ with gr.Blocks(title="Jerry • HW Intake (Echo)") as demo:
344
  ocr_txt = gr.Textbox(label="Raw OCR text", lines=12)
345
  params_json2 = gr.JSON(label="Detected parameters")
346
  raw_df = gr.Dataframe(label="Raw table guess", interactive=False)
347
- # make editable so you can fix numbers
348
- norm_df = gr.Dataframe(label="Detected table (normalized)", interactive=True)
349
-
350
- # ---- NEW: in‑memory downloads ----
351
- raw_dl = gr.DownloadButton(label="Download RAW CSV")
352
- norm_dl = gr.DownloadButton(label="Download NORMALIZED CSV")
353
- txt_dl = gr.DownloadButton(label="Download OCR TEXT")
354
-
355
- # re‑export after manual edits
356
- export_btn = gr.DownloadButton(label="Download EDITED NORMALIZED CSV")
357
 
358
  # --- Tab 3: Solve & Check ---
359
  with gr.Tab("Straight-Line • Solve & Check"):
@@ -393,9 +362,6 @@ with gr.Blocks(title="Jerry • HW Intake (Echo)") as demo:
393
  params_json2, # json
394
  raw_df, # raw table
395
  norm_df, # normalized table (tab 2)
396
- raw_dl, # NEW: bytes -> RAW CSV download
397
- norm_dl, # NEW: bytes -> NORMALIZED CSV download
398
- txt_dl, # NEW: bytes -> OCR TEXT download
399
  in_cost, in_salv, in_life, in_year, # autofill inputs
400
  last_params, # state
401
  last_table, # state
@@ -412,12 +378,6 @@ with gr.Blocks(title="Jerry • HW Intake (Echo)") as demo:
412
  btn_build.click(build_cb, [in_cost, in_salv, in_life, in_year], [expected_df])
413
  btn_check.click(check_cb, [in_cost, in_salv, in_life, in_year, last_table], [deltas_df, coach_txt])
414
 
415
- # ---- NEW: export edited normalized CSV ----
416
- def export_current(norm_df_current: pd.DataFrame):
417
- return _csv_bytes(norm_df_current if isinstance(norm_df_current, pd.DataFrame) else pd.DataFrame())
418
-
419
- export_btn.click(export_current, inputs=norm_df, outputs=export_btn)
420
-
421
  gr.Markdown("— Echo mode finished. When this looks good, we’ll plug in the SL solver + coaching.")
422
 
423
  if __name__ == "__main__":
 
39
  try: return float(s)
40
  except: return pd.NA
41
 
 
 
 
 
 
 
 
 
 
42
  PARAM_PATTERNS = {
43
  "cost": r"cost\s*[:=]\s*\$?\s*([\d,]+(?:\.\d+)?)",
44
  "salvage": r"salvage\s*[:=]\s*\$?\s*([\d,]+(?:\.\d+)?)",
 
242
 
243
  def handle_image(img):
244
  if img is None:
245
+ return "(no image)", {}, pd.DataFrame(), pd.DataFrame(), 0.0, 0.0, 10, pd.Timestamp.now().year, {}, pd.DataFrame()
 
246
 
247
  from PIL import Image as PILImage
248
  pil = img if isinstance(img, PILImage.Image) else PILImage.fromarray(img)
 
252
  df_raw = _table_from_ocr_text(ocr_text or "")
253
  df_norm = _normalize_depr_columns(df_raw) if df_raw is not None else pd.DataFrame()
254
 
 
 
 
 
 
 
 
 
 
 
 
255
  cost, salv, life, year = _params_tuple(params)
256
 
257
  return (
 
259
  params,
260
  df_raw, # raw table shown in OCR tab
261
  df_norm, # normalized table shown in OCR tab
 
 
 
262
  cost, salv, life, year, # auto-fill numbers
263
  params, # save params state
264
+ df_norm # 🔹 save normalized table to last_table (same as docx)
265
  )
266
 
267
+
268
+
269
  def fill_from_state(p):
270
  p = p or {}
271
  return (
 
291
  if not isinstance(table_state, pd.DataFrame) or table_state.empty:
292
  return pd.DataFrame(), "No student table found to check."
293
 
294
+ # 👇 Gradio returns strings → re-normalize and coerce here every time
295
  actual = _normalize_depr_columns(table_state)
296
  for c in ["Year", "Begin BV", "Depreciation", "Accum Dep", "End BV"]:
297
  actual[c] = pd.to_numeric(actual[c], errors="coerce")
 
322
  ocr_txt = gr.Textbox(label="Raw OCR text", lines=12)
323
  params_json2 = gr.JSON(label="Detected parameters")
324
  raw_df = gr.Dataframe(label="Raw table guess", interactive=False)
325
+ norm_df = gr.Dataframe(label="Detected table (normalized)", interactive=False)
 
 
 
 
 
 
 
 
 
326
 
327
  # --- Tab 3: Solve & Check ---
328
  with gr.Tab("Straight-Line • Solve & Check"):
 
362
  params_json2, # json
363
  raw_df, # raw table
364
  norm_df, # normalized table (tab 2)
 
 
 
365
  in_cost, in_salv, in_life, in_year, # autofill inputs
366
  last_params, # state
367
  last_table, # state
 
378
  btn_build.click(build_cb, [in_cost, in_salv, in_life, in_year], [expected_df])
379
  btn_check.click(check_cb, [in_cost, in_salv, in_life, in_year, last_table], [deltas_df, coach_txt])
380
 
 
 
 
 
 
 
381
  gr.Markdown("— Echo mode finished. When this looks good, we’ll plug in the SL solver + coaching.")
382
 
383
  if __name__ == "__main__":