0c269a97ee
Der SAVEPOINT v3.16 vermutete, das Aehnlichkeits-Gate 0,55 sei "grosszuegig" und Jikan stehe in der Kette zu frueh (vor OMDb). Nachgerechnet - titel_aehnlichkeit ist eine reine Funktion - ergibt sich ein anderes Bild als vermutet: "Alien" vs. "Alien 9" -> 0,83 TRIFFT "Inception" vs. "Deception" -> 0,78 TRIFFT "Hero" vs. "Heroman" -> 0,73 TRIFFT "The Dark Knight" vs. "Dark Knight Rises" -> 0,69 TRIFFT Ein Kinofilm, den TMDB verpasst, bekam damit Anime-Metadaten mit Confidence 0,85 - und OMDb, das ihn kennt, wurde nie gefragt. Bemerkenswert dabei, und das widerlegt die Vermutung "einfach zu niedrig": Fuer den Fall, fuer den Jikan ueberhaupt eingebaut wurde, ist das Gate sogar zu HOCH. "Evangelion 2.22" gegen den MAL-Titel "Evangelion: 2.0 You Can (Not) Advance" ergibt 0,51 und faellt durch. Eine einzelne Zahl kann beides nicht leisten. Deshalb zwei Schwellen statt Umsortieren (Reihenfolge bleibt, AGENTS Regel B): Nur ein praktisch exakter Titel (>= 0,9) beendet die Kette. Ein unscharfer Treffer wird GEMERKT, dann wird OMDb gefragt - und erst wenn OMDb nichts hat, kommt er als VORSCHLAG mit Confidence 0,6 zum Zug. Damit gewinnt "exakt" immer gegen "unscharf", egal aus welcher Quelle. Antwort auf die Commander-Frage "JIKAN ist drin - wird das genutzt?": ja, und ab jetzt an der richtigen Stelle. Ehrlicher Vorbehalt: Live gegengeprueft ist das nicht - MyAnimeList war waehrend dieser Sitzung durchweg weg (Jikan antwortete HTTP 504 auf jede Anfrage). Die Arithmetik des Gates ist davon unberuehrt und in test_jikan_helpers.py festgehalten, die Kettenlogik in test_prescan_helpers.py. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
79 lines
3.5 KiB
Python
79 lines
3.5 KiB
Python
"""Was das Ähnlichkeits-Gate von Jikan wirklich durchlässt — gemessen.
|
|
|
|
Hintergrund (26.07.2026): Der SAVEPOINT v3.16 vermutete, das Gate 0,55 sei
|
|
„großzügig" und Jikan stehe in der Metadaten-Kette zu früh (vor OMDb). Beides
|
|
war nachrechenbar, weil `titel_aehnlichkeit` eine reine Funktion ist — und die
|
|
Rechnung ergab ein anderes Bild als die Vermutung:
|
|
|
|
- Für kurze Kinofilm-Titel ist das Gate WIRKLICH zu locker (Alien → 0,83).
|
|
- Für den Fall, für den Jikan eingebaut wurde, ist es sogar zu STRENG
|
|
(„Evangelion 2.22" gegen den MAL-Titel → 0,51, fällt durch).
|
|
|
|
Eine einzelne Zahl kann also beides nicht leisten. Die Folge steht in
|
|
prescan._scan_video: „exakt schlägt unscharf" statt „erster gewinnt".
|
|
|
|
Die Anime-Titel unten existieren auf MyAnimeList; die Zahlen sind ausgerechnet,
|
|
nicht geschätzt. MyAnimeList selbst war bei dieser Messung nicht erreichbar
|
|
(Jikan antwortete durchweg HTTP 504) — die Live-Abfrage steht damit weiter aus,
|
|
die Arithmetik des Gates ist davon aber unberührt.
|
|
"""
|
|
|
|
from clients.jikan import JikanClient, titel_aehnlichkeit
|
|
|
|
|
|
def test_kurze_kinofilm_titel_reissen_das_gate_0_55():
|
|
"""Diese vier würden ohne die Änderung Anime-Metadaten bekommen, obwohl
|
|
OMDb die Filme kennt — es wurde nur nie gefragt."""
|
|
faelle = [
|
|
("Alien", "Alien 9", 0.83),
|
|
("Inception", "Deception", 0.78),
|
|
("Hero", "Heroman", 0.73),
|
|
("The Dark Knight", "Dark Knight Rises", 0.69),
|
|
]
|
|
for disc, anime, erwartet in faelle:
|
|
score = titel_aehnlichkeit(disc, anime)
|
|
assert round(score, 2) == erwartet, f"{disc} vs {anime}: {score}"
|
|
# ... liegt über dem Gate (Jikan gibt also einen Treffer zurück) ...
|
|
assert score >= JikanClient.MINDEST_AEHNLICHKEIT
|
|
# ... aber unter „sicher", darf die Kette also nicht beenden.
|
|
assert score < JikanClient.SICHER_AEHNLICHKEIT
|
|
|
|
|
|
def test_echter_treffer_gilt_weiter_als_sicher():
|
|
"""Exakter Titel → 1,0. Der Normalfall eines echten Anime-Fundes darf durch
|
|
die Verschärfung NICHT verlorengehen (AGENTS Regel B)."""
|
|
assert titel_aehnlichkeit("Monster", "Monster") == 1.0
|
|
assert titel_aehnlichkeit("Cowboy Bebop", "COWBOY BEBOP") == 1.0
|
|
# Interpunktion und Kleinschreibung sind egal — norm() wirft sie weg
|
|
assert titel_aehnlichkeit("Akira", "AKIRA!") == 1.0
|
|
for a, b in (("Monster", "Monster"), ("Akira", "AKIRA!")):
|
|
assert titel_aehnlichkeit(a, b) >= JikanClient.SICHER_AEHNLICHKEIT
|
|
|
|
|
|
def test_untertitel_zaehlt_noch_als_sicher_genug():
|
|
"""Discs tragen oft den Kurztitel, MAL den vollen. Das muss ein sicherer
|
|
Treffer bleiben, sonst hilft die Quelle bei Anime nicht mehr."""
|
|
assert titel_aehnlichkeit("Steins Gate", "Steins;Gate") >= JikanClient.SICHER_AEHNLICHKEIT
|
|
|
|
|
|
def test_der_fall_fuer_den_jikan_gebaut_wurde_faellt_heute_durch():
|
|
"""Gegenbeweis zur Vermutung „das Gate ist zu großzügig": Für Evangelion
|
|
2.22 ist es zu STRENG. Der Wert ist dokumentiert, damit ein späteres
|
|
Anheben des Gates nicht unbemerkt auch diesen Fall killt."""
|
|
score = titel_aehnlichkeit(
|
|
"Evangelion 2.22", "Evangelion: 2.0 You Can (Not) Advance"
|
|
)
|
|
assert round(score, 2) == 0.51
|
|
assert score < JikanClient.MINDEST_AEHNLICHKEIT
|
|
|
|
|
|
def test_voellig_anderer_titel_wird_verworfen():
|
|
score = titel_aehnlichkeit("Blade", "Blade of the Immortal")
|
|
assert score < JikanClient.MINDEST_AEHNLICHKEIT
|
|
|
|
|
|
def test_leere_titel_geben_null():
|
|
assert titel_aehnlichkeit("", "Monster") == 0.0
|
|
assert titel_aehnlichkeit("Monster", "") == 0.0
|
|
assert titel_aehnlichkeit("!!!", "???") == 0.0
|