mannnon commited on
Commit
c4b616d
·
verified ·
1 Parent(s): 02c3beb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -56
app.py CHANGED
@@ -318,16 +318,21 @@ def find_float_after_label(text: str, label: str, max_numbers: int = 2, window:
318
  return out
319
 
320
  def extract_pdf_name(text: str):
321
- patterns = [
322
- r"Personne:\s*([A-Za-zÀ-ÿ\- ]+),\s*\d{2}/\d{2}/\d{4}",
323
- r"Personne:\s*([A-Za-zÀ-ÿ\- ]+)",
324
- ]
325
- for pattern in patterns:
326
- m = re.search(pattern, text, flags=re.S)
327
- if m:
328
- return m.group(1).strip()
329
- return None
330
 
 
 
 
 
 
 
 
 
 
 
 
 
331
 
332
  def parse_zebris_pdf(uploaded_pdf):
333
  text = extract_text_from_pdf(uploaded_pdf)
@@ -358,68 +363,97 @@ def parse_zebris_pdf(uploaded_pdf):
358
  "fore_peak_time_pct_d": np.nan,
359
  }
360
 
361
- # On normalise le texte pour éviter les problèmes de retours ligne / espaces
362
- text_flat = re.sub(r"\s+", " ", text).replace("\xa0", " ").strip()
 
363
 
364
  num = r"(\d+,\d+|\d+\.\d+|\d+)"
365
 
366
  def to_float(x):
367
  return float(x.replace(",", "."))
368
 
369
- def extract_pair(section_label, sub_label=None):
370
  """
371
- Extrait une paire Gauche / Droite du type :
372
- ... Gauche Droite 1066,5±67,8 1040,5±49,3 ...
 
373
  """
374
- if sub_label:
375
- pattern = (
376
- rf"{re.escape(section_label)}.*?"
377
- rf"{re.escape(sub_label)}\s+Gauche\s+Droite\s+"
378
- rf"{num}\s*±\s*{num}\s+{num}\s*±\s*{num}"
379
- )
380
- else:
381
- pattern = (
382
- rf"{re.escape(section_label)}\s+Gauche\s+Droite\s+"
383
- rf"{num}\s*±\s*{num}\s+{num}\s*±\s*{num}"
384
- )
385
-
386
- m = re.search(pattern, text_flat, flags=re.S)
387
  if not m:
388
  return np.nan, np.nan
389
-
390
- # groupes 1 et 3 = valeurs moyennes G / D
391
  return to_float(m.group(1)), to_float(m.group(3))
392
 
393
- # 1) Transition (section spécifique)
394
- tg, td = extract_pair("Instant du passage du talon vers l'avant-pied, s")
395
- data["transition_g"], data["transition_d"] = tg, td
396
-
397
- # 2) Forces max
398
- fg, fd = extract_pair("Force maximale, N", "Forefoot (Three zones)")
399
- mg, md = extract_pair("Force maximale, N", "Midfoot (Three zones)")
400
- hg, hd = extract_pair("Force maximale, N", "Heel (Three zones)")
401
 
402
- data["fore_force_g"], data["fore_force_d"] = fg, fd
403
- data["mid_force_g"], data["mid_force_d"] = mg, md
404
- data["heel_force_g"], data["heel_force_d"] = hg, hd
405
 
406
- # 3) Pressions max
407
- fpg, fpd = extract_pair("Pression maximale, N/cm²", "Forefoot (Three zones)")
408
- mpg, mpd = extract_pair("Pression maximale, N/cm²", "Midfoot (Three zones)")
409
- hpg, hpd = extract_pair("Pression maximale, N/cm²", "Heel (Three zones)")
410
-
411
- data["fore_pressure_g"], data["fore_pressure_d"] = fpg, fpd
412
- data["mid_pressure_g"], data["mid_pressure_d"] = mpg, mpd
413
- data["heel_pressure_g"], data["heel_pressure_d"] = hpg, hpd
414
 
415
- # 4) Timing pic de force
416
- ftg, ftd = extract_pair("Instant pic de force, % de phase d'appui", "Forefoot (Three zones)")
417
- mtg, mtd = extract_pair("Instant pic de force, % de phase d'appui", "Midfoot (Three zones)")
418
- htg, htd = extract_pair("Instant pic de force, % de phase d'appui", "Heel (Three zones)")
419
 
420
- data["fore_peak_time_pct_g"], data["fore_peak_time_pct_d"] = ftg, ftd
421
- data["mid_peak_time_pct_g"], data["mid_peak_time_pct_d"] = mtg, mtd
422
- data["heel_peak_time_pct_g"], data["heel_peak_time_pct_d"] = htg, htd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
 
424
  data["attaque_pdf"] = estimate_attack_from_pdf(data)
425
  return data
@@ -1208,7 +1242,7 @@ if uploaded_pdfs:
1208
  for pdf in uploaded_pdfs:
1209
  try:
1210
  pdfs_data.append(parse_zebris_pdf(pdf))
1211
- st.write(pdfs_data[-1])
1212
  except Exception as e:
1213
  st.warning(f"{pdf.name} : erreur lecture PDF ({e})")
1214
 
 
318
  return out
319
 
320
  def extract_pdf_name(text: str):
321
+ if not text:
322
+ return None
 
 
 
 
 
 
 
323
 
324
+ for line in text.splitlines():
325
+ clean = " ".join(line.replace("\xa0", " ").split())
326
+ if "Personne:" in clean:
327
+ after = clean.split("Personne:", 1)[1].strip()
328
+ # on coupe avant la date si elle existe
329
+ m = re.match(r"(.+?)(?:,\s*\d{2}/\d{2}/\d{4})?$", after)
330
+ if m:
331
+ name = m.group(1).strip()
332
+ if name:
333
+ return name
334
+
335
+ return None
336
 
337
  def parse_zebris_pdf(uploaded_pdf):
338
  text = extract_text_from_pdf(uploaded_pdf)
 
363
  "fore_peak_time_pct_d": np.nan,
364
  }
365
 
366
+ # normalisation forte du texte
367
+ text_flat = text.replace("\xa0", " ")
368
+ text_flat = re.sub(r"\s+", " ", text_flat).strip()
369
 
370
  num = r"(\d+,\d+|\d+\.\d+|\d+)"
371
 
372
  def to_float(x):
373
  return float(x.replace(",", "."))
374
 
375
+ def extract_gd_pair(block_text, label):
376
  """
377
+ Cherche un pattern du type:
378
+ label ... Gauche Droite 1066,5±67,8 1040,5±49,3
379
+ et renvoie (gauche, droite)
380
  """
381
+ pattern = (
382
+ rf"{re.escape(label)}\s*Gauche\s*Droite\s*"
383
+ rf"{num}\s*±\s*{num}\s*"
384
+ rf"{num}\s\s*{num}"
385
+ )
386
+ m = re.search(pattern, block_text, flags=re.S)
 
 
 
 
 
 
 
387
  if not m:
388
  return np.nan, np.nan
 
 
389
  return to_float(m.group(1)), to_float(m.group(3))
390
 
391
+ # on isole le bloc utile de la page 8
392
+ start_idx = text_flat.find("Analyse du pieds en trois zones")
393
+ if start_idx == -1:
394
+ start_idx = text_flat.find("Analyse du pieds en trois zones")
395
+ if start_idx == -1:
396
+ start_idx = text_flat.find("Modification de la charge")
 
 
397
 
398
+ end_idx = text_flat.find("Durée de contact au sol", start_idx if start_idx != -1 else 0)
 
 
399
 
400
+ if start_idx != -1 and end_idx != -1 and end_idx > start_idx:
401
+ zone_block = text_flat[start_idx:end_idx]
402
+ elif start_idx != -1:
403
+ zone_block = text_flat[start_idx:]
404
+ else:
405
+ zone_block = text_flat
 
 
406
 
407
+ # 1. Transition
408
+ tg, td = extract_gd_pair(zone_block, "Instant du passage du talon vers l'avant-pied, s")
409
+ data["transition_g"], data["transition_d"] = tg, td
 
410
 
411
+ # 2. Force maximale
412
+ fg, fd = extract_gd_pair(zone_block, "Forefoot (Three zones)")
413
+ # attention: Forefoot apparaît plusieurs fois dans la page, donc on fait des blocs plus précis
414
+ force_section_match = re.search(
415
+ rf"Force maximale,\s*N(.*?)Pression maximale,\s*N/cm²",
416
+ zone_block,
417
+ flags=re.S
418
+ )
419
+ if force_section_match:
420
+ force_section = force_section_match.group(1)
421
+ fg, fd = extract_gd_pair(force_section, "Forefoot (Three zones)")
422
+ mg, md = extract_gd_pair(force_section, "Midfoot (Three zones)")
423
+ hg, hd = extract_gd_pair(force_section, "Heel (Three zones)")
424
+ data["fore_force_g"], data["fore_force_d"] = fg, fd
425
+ data["mid_force_g"], data["mid_force_d"] = mg, md
426
+ data["heel_force_g"], data["heel_force_d"] = hg, hd
427
+
428
+ # 3. Pression maximale
429
+ pressure_section_match = re.search(
430
+ rf"Pression maximale,\s*N/cm²(.*?)Instant pic de force,\s*% de phase d'appui",
431
+ zone_block,
432
+ flags=re.S
433
+ )
434
+ if pressure_section_match:
435
+ pressure_section = pressure_section_match.group(1)
436
+ fpg, fpd = extract_gd_pair(pressure_section, "Forefoot (Three zones)")
437
+ mpg, mpd = extract_gd_pair(pressure_section, "Midfoot (Three zones)")
438
+ hpg, hpd = extract_gd_pair(pressure_section, "Heel (Three zones)")
439
+ data["fore_pressure_g"], data["fore_pressure_d"] = fpg, fpd
440
+ data["mid_pressure_g"], data["mid_pressure_d"] = mpg, mpd
441
+ data["heel_pressure_g"], data["heel_pressure_d"] = hpg, hpd
442
+
443
+ # 4. Timing pic de force
444
+ peak_section_match = re.search(
445
+ rf"Instant pic de force,\s*% de phase d'appui(.*)$",
446
+ zone_block,
447
+ flags=re.S
448
+ )
449
+ if peak_section_match:
450
+ peak_section = peak_section_match.group(1)
451
+ ftg, ftd = extract_gd_pair(peak_section, "Forefoot (Three zones)")
452
+ mtg, mtd = extract_gd_pair(peak_section, "Midfoot (Three zones)")
453
+ htg, htd = extract_gd_pair(peak_section, "Heel (Three zones)")
454
+ data["fore_peak_time_pct_g"], data["fore_peak_time_pct_d"] = ftg, ftd
455
+ data["mid_peak_time_pct_g"], data["mid_peak_time_pct_d"] = mtg, mtd
456
+ data["heel_peak_time_pct_g"], data["heel_peak_time_pct_d"] = htg, htd
457
 
458
  data["attaque_pdf"] = estimate_attack_from_pdf(data)
459
  return data
 
1242
  for pdf in uploaded_pdfs:
1243
  try:
1244
  pdfs_data.append(parse_zebris_pdf(pdf))
1245
+ st.write("PDF parsé :", pdfs_data[-1])
1246
  except Exception as e:
1247
  st.warning(f"{pdf.name} : erreur lecture PDF ({e})")
1248