From ec361df89ade4c33d168f0549e02938c7ba30dd4 Mon Sep 17 00:00:00 2001 From: Rob Date: Fri, 27 Mar 2026 13:46:50 +0100 Subject: [PATCH] =?UTF-8?q?Stichproben=20Validierung=20hinzugef=C3=BCgt.?= =?UTF-8?q?=20Zeigt=20am=20anfang=20einige=20Werte=20aus=20dem=20PDF=20an?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/validators.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/validators.py b/src/validators.py index 7843e31..4297bdd 100644 --- a/src/validators.py +++ b/src/validators.py @@ -159,6 +159,84 @@ def validate( return errors +def _extract_samples( + file_path: str | Path, + sheet_name: str, + config: Dict[str, Any], +) -> List[Dict]: + """Extract the first 10 days for persons 1, 5 and 10. + + Returns a list of dicts: + {'person': str, 'days': list[str]} (days[0] = Tag 1 … days[9] = Tag 10) + + Missing persons are silently skipped. + """ + import openpyxl + + result = [] + target_persons = [1, 5, 10] # 1-based indices into the data rows + num_days = 10 + + try: + wb = openpyxl.load_workbook(str(file_path), read_only=True, data_only=True) + if sheet_name not in wb.sheetnames: + wb.close() + return result + + ws = wb[sheet_name] + rows = list(ws.iter_rows(values_only=True)) + wb.close() + + name_col: int = config["excel_name_column"] + seq_col: int = config["excel_seq_column"] + name_header: str = config["excel_name_header"] + day_start: int = config["excel_day_start_col"] + + # Find header row + header_idx = None + for i, row in enumerate(rows): + if len(row) > name_col and row[name_col] is not None: + if name_header in str(row[name_col]): + header_idx = i + break + if header_idx is None: + return result + + # Collect data rows (rows after header with a valid seq number) + data_rows = [] + for row in rows[header_idx + 1:]: + if len(row) > seq_col and row[seq_col] is not None: + try: + int(row[seq_col]) + data_rows.append(row) + except (TypeError, ValueError): + pass + + def _fmt(val) -> str: + if val is None: + return "–" + if isinstance(val, float) and val == int(val): + return str(int(val)) + return str(val) + + for person_n in target_persons: + if person_n > len(data_rows): + continue + row = data_rows[person_n - 1] + name = str(row[name_col]).strip() if len(row) > name_col and row[name_col] else "?" + days = [] + for day_idx in range(num_days): + col_idx = day_start + day_idx + val = row[col_idx] if col_idx < len(row) else None + days.append(_fmt(val)) + result.append({"person": name, "days": days}) + + except Exception: + pass # Preview is best-effort; never block on sample errors + + return result + + def show_preview_and_confirm( file_path: str | Path, sheet_name: str, @@ -191,6 +269,20 @@ def show_preview_and_confirm( print(f"Teilnehmer : {person_count}") print(f"Fehler : {len(errors) if errors else 0}") + # --- Sample data from the Excel sheet ------------------------------------ + samples = _extract_samples(file_path, sheet_name, config) + if samples: + num_days = len(samples[0]["days"]) + day_headers = " ".join(f"{d+1:>3}" for d in range(num_days)) + separator = " ".join("---" for _ in range(num_days)) + print() + print("--- Stichproben aus dem Excel-Sheet (erste 10 Tage) ---") + print(f" {'Person':<30s} {day_headers}") + print(f" {'-'*30} {separator}") + for s in samples: + day_vals = " ".join(f"{v:>3}" for v in s["days"]) + print(f" {s['person']:<30s} {day_vals}") + if errors: print() print("--- Validierungsfehler ---")