From 695983245d51e6bafada579cbd215f20620ce4b4 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Sun, 2 Aug 2026 01:41:28 +0200 Subject: [PATCH] fix(bericht): keine Doppelverweise und keine Platzhalter im Quellenverzeichnis Zwei Befunde aus dem Bericht zu Lage 60 vom 02.08.2026. 1. Doppelte Verweise, ein Folgefehler des Dubletten-Zusammenfuehrens. Zeigten zwei Nummern auf dieselbe Adresse, wurden beide Verweise auf dieselbe neue Nummer umgeschrieben und standen dann nebeneinander: "[24][24]". Im Bericht kam das dreimal vor, in der gespeicherten Fassung nicht. Aufeinanderfolgende Verweise auf dieselbe Nummer werden jetzt zusammengezogen. 2. Platzhalter ohne Adresse. Das Modell hatte einen Eintrag {"nr": 12, "name": "Quelle", "url": ""} erzeugt. Der Bericht druckte ihn als "12 Quelle" ohne Adresse und die Statistik fuehrte ein Medium namens "Quelle". Ein Eintrag ohne Adresse ist kein pruefbarer Beleg und kommt nicht mehr ins Verzeichnis; der Verweis darauf wird wie ein verwaister behandelt und entfernt. Gegenprobe an Lage 60: aus 30 Eintraegen werden 26 (drei doppelte Adressen zusammengefuehrt, ein Platzhalter entfernt), die Zaehlung bleibt lueckenlos, kein doppelter Verweis mehr im Text. Neu sind 4 Pruefungen, insgesamt laufen 220 ohne Netzzugriff und ohne Kosten. Co-Authored-By: Claude Opus 5 (1M context) --- src/report_generator.py | 15 ++++++++++++--- tests/test_quellenausgabe.py | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/report_generator.py b/src/report_generator.py index 0da3872..e71048f 100644 --- a/src/report_generator.py +++ b/src/report_generator.py @@ -138,11 +138,14 @@ def _dubletten_zusammenfuehren(sources: list) -> list: """ behalten: dict[str, dict] = {} reihenfolge: list[str] = [] + ohne_adresse = 0 for s in sources: schluessel = _url_schluessel(s.get("url") or "") if not schluessel: - reihenfolge.append(id(s)) - behalten[id(s)] = s + # Eintraege ohne Adresse sind keine pruefbaren Belege. Im Bericht + # vom 02.08.2026 stand so ein Platzhalter als "12 Quelle" ohne + # Adresse im Verzeichnis und als "Quelle 1" in der Statistik. + ohne_adresse += 1 continue if schluessel in behalten: behalten[schluessel].setdefault("alias_nrs", []).append(s.get("nr")) @@ -151,9 +154,11 @@ def _dubletten_zusammenfuehren(sources: list) -> list: reihenfolge.append(schluessel) ergebnis = [behalten[k] for k in reihenfolge] - entfernt = len(sources) - len(ergebnis) + entfernt = len(sources) - len(ergebnis) - ohne_adresse if entfernt: logger.info("Quellenverzeichnis: %d doppelte Adresse(n) zusammengefuehrt", entfernt) + if ohne_adresse: + logger.info("Quellenverzeichnis: %d Eintrag/Eintraege ohne Adresse entfernt", ohne_adresse) return ergebnis @@ -207,6 +212,10 @@ def _apply_citation_map(text: str, abbildung: dict) -> str: return "" ergebnis = re.sub(r"\[(\d{1,5}[a-z]?)\]", ersetze, text) + # Zeigten zwei Nummern auf dieselbe Adresse, landen ihre Verweise nach der + # Umschreibung auf derselben Zahl und stehen dann doppelt nebeneinander: + # "[24][24]". Im Bericht vom 02.08.2026 kam das dreimal vor. + ergebnis = re.sub(r"(\[(\d{1,5})\])(?:\s*\[\2\])+", r"\1", ergebnis) if verwaist: logger.warning( "Bericht: %d Quellenverweise ohne Verzeichniseintrag entfernt (%s)", diff --git a/tests/test_quellenausgabe.py b/tests/test_quellenausgabe.py index 8fddef3..fe1c0fa 100644 --- a/tests/test_quellenausgabe.py +++ b/tests/test_quellenausgabe.py @@ -172,6 +172,28 @@ pruefe("C13 Ausgabe zaehlt wieder lueckenlos", [s["nr"] for s in neu_d] == [1, 2 [s["nr"] for s in neu_d]) pruefe("C14 Verweis auf die entfernte Nummer zeigt auf den behaltenen Eintrag", abb_d.get(23) == abb_d.get(22) == 1 and abb_d.get(25) == abb_d.get(24) == 2, abb_d) +# Zeigen zwei Verweise nach dem Zusammenfuehren auf dieselbe Zahl, darf im +# Text nicht "[24][24]" stehen bleiben. Im Bericht vom 02.08.2026 dreimal. +pruefe("C15a doppelter Verweis auf dieselbe Nummer wird zusammengezogen", + rg._apply_citation_map("Beleg [22][23] und Ende.", abb_d) == "Beleg [1] und Ende.", + rg._apply_citation_map("Beleg [22][23] und Ende.", abb_d)) +pruefe("C15b verschiedene Nummern bleiben nebeneinander stehen", + rg._apply_citation_map("Beleg [22][24].", abb_d) == "Beleg [1][2].", + rg._apply_citation_map("Beleg [22][24].", abb_d)) + +# Eintraege ohne Adresse sind keine pruefbaren Belege. +ohne_adresse = rg._prepare_sources({"sources_json": json.dumps([ + {"nr": 11, "name": "tagesschau", "url": "https://www.tagesschau.de/a.html"}, + {"nr": 12, "name": "Quelle", "url": ""}, + {"nr": 13, "name": "ZDF heute", "url": "https://www.zdfheute.de/b.html"}, +], ensure_ascii=False)}) +pruefe("C15c Eintrag ohne Adresse kommt nicht ins Verzeichnis", + [s["nr"] for s in ohne_adresse] == [11, 13], [s["nr"] for s in ohne_adresse]) +_, abb_o = rg._renumber_sources(ohne_adresse) +pruefe("C15d Verweis auf den entfernten Eintrag wird getilgt", + rg._apply_citation_map("Beleg [11][12].", abb_o) == "Beleg [1].", + rg._apply_citation_map("Beleg [11][12].", abb_o)) + pruefe("C15 Text mit beiden Nummern bleibt aufloesbar", rg._apply_citation_map("Beleg [22] und [23].", abb_d) == "Beleg [1] und [1].", rg._apply_citation_map("Beleg [22] und [23].", abb_d))