Skip to content

Commit 4337907

Browse files
committed
Translate the output of coverage.py and measure-recognition.py
Everything a user reads was already English — README, UI, logs, changelog — but these two still printed their results in German. Logs were switched for the same reason in 0.6.13: someone reporting a problem should not have to translate their own output first. why-no-face.py arriving in English made the two of them the odd ones out. Only printed output and --help text; comments and docstrings stay German like the rest of the codebase. Column widths were re-aligned to the new labels and both scripts verified against a real gallery.
1 parent aa4b784 commit 4337907

2 files changed

Lines changed: 44 additions & 44 deletions

File tree

scripts/coverage.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,19 @@ def main():
157157
"sources": meta.get("sources", {})}
158158

159159
if not gal:
160-
print("keine Galerie gefunden", file=sys.stderr)
160+
print("no gallery found", file=sys.stderr)
161161
return 1
162162

163-
print(f"{'Person':22s} {'Fotos':>5s} {'Vielf.':>6s} {'frontal':>7s} {'halb':>5s} "
164-
f"{'Profil':>6s} {'S/W':>4s} {'Selbst':>6s} Kameras")
163+
print(f"{'person':22s} {'photos':>6s} {'divers':>6s} {'front':>6s} {'half':>5s} "
164+
f"{'profile':>7s} {'grey':>5s} {'self':>5s} cameras")
165165
print("-" * 96)
166166

167167
# Welche Kameras nachts ueberhaupt in Graustufen schalten? Das aus der Galerie
168168
# abzuleiten waere zirkulaer — fehlt die IR-Aufnahme, faende man die Kamera nie.
169169
# Also bei Frigate nachsehen, wie die Naechte dort tatsaechlich aussehen.
170170
ir_cams = ir_cameras(cfg)
171171
if ir_cams:
172-
print(f"Kameras mit IR-Nachtmodus: {', '.join(sorted(ir_cams))}\n")
172+
print(f"cameras that switch to IR at night: {', '.join(sorted(ir_cams))}\n")
173173

174174
advice = []
175175
for slug, g in gal.items():
@@ -209,35 +209,35 @@ def main():
209209
known = {c: k for c, k in cams.items() if c != "?"}
210210
cam_s = ", ".join(f"{c} {k}" for c, k in sorted(known.items(), key=lambda x: -x[1]))
211211
if cams.get("?"):
212-
cam_s = (cam_s + ", " if cam_s else "") + f"{cams['?']}x unbekannt"
213-
print(f"{g['name'][:22]:22s} {n:5d} {div_s:>6s} {front:>7d} {half:>5d} "
214-
f"{prof:>6d} {night:>4d} {rate:>5d}% {cam_s}")
212+
cam_s = (cam_s + ", " if cam_s else "") + f"{cams['?']}x unknown"
213+
print(f"{g['name'][:22]:22s} {n:6d} {div_s:>6s} {front:>6d} {half:>5d} "
214+
f"{prof:>7d} {night:>5d} {rate:>4d}% {cam_s}")
215215

216216
missing = []
217217
if n < 5:
218-
missing.append("zu wenige Fotos")
218+
missing.append("too few photos")
219219
if not front:
220-
missing.append("keine frontale Aufnahme")
220+
missing.append("no frontal shot")
221221
# S/W nur anmahnen, wo ueberhaupt eine Kamera in den IR-Modus schaltet.
222222
if ir_cams and not night and (known.keys() & ir_cams):
223-
missing.append("keine Aufnahme im IR-Nachtmodus")
223+
missing.append("no IR night shot")
224224
if len(known) == 1 and n >= 3:
225-
missing.append(f"nur an einer Kamera ({next(iter(known))})")
225+
missing.append(f"only one camera ({next(iter(known))})")
226226
if n > 1 and diversity > 0.55:
227-
missing.append(f"Fotos ähneln sich stark ({diversity:.2f})")
227+
missing.append(f"photos look very alike ({diversity:.2f})")
228228
# Der Selbst-Test ist bei kleinen Sammlungen systematisch pessimistisch —
229229
# als Mangel nur melden, wenn genug Fotos da sind, dass er aussagt.
230230
if n >= 8 and rate < 40:
231-
missing.append(f"Fotos stuetzen einander kaum (Selbst-Test {rate}%)")
231+
missing.append(f"photos barely support each other (self test {rate}%)")
232232
if missing:
233233
advice.append((rate, g["name"], missing))
234234

235235
if advice:
236-
print("\nWas konkret fehlt (schwächste zuerst):")
236+
print("\nWhat is concretely missing (weakest first):")
237237
for rate, name, missing in sorted(advice):
238238
print(f" {name}: {', '.join(missing)}")
239239
else:
240-
print("\nAlle Personen sind breit abgedeckt.")
240+
print("\nEvery person is broadly covered.")
241241
return 0
242242

243243

scripts/measure-recognition.py

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,10 @@ def load_config(base: Path) -> dict:
172172

173173
def main():
174174
ap = argparse.ArgumentParser()
175-
ap.add_argument("--baseline", help="Pfad zu einer aelteren Galerie (entpacktes Backup)")
176-
ap.add_argument("--days", type=float, default=2, help="Zeitraum der Praxisprobe (0 = aus)")
175+
ap.add_argument("--baseline", help="path to an older gallery (an unpacked backup)")
176+
ap.add_argument("--days", type=float, default=2, help="window for the practical probe (0 = off)")
177177
ap.add_argument("--data", default=str(BASE / "data"))
178-
ap.add_argument("--top-k", type=int, help="match_top_k zum Vergleich uebersteuern")
178+
ap.add_argument("--top-k", type=int, help="override match_top_k for comparison")
179179
args = ap.parse_args()
180180

181181
global TOP_K
@@ -188,69 +188,69 @@ def main():
188188
TOP_K = max(1, int(cfg["faceid"].get("match_top_k", 3)))
189189
new = load_gallery(Path(args.data) / "persons")
190190
if not new:
191-
print("keine Galerie gefunden", file=sys.stderr)
191+
print("no gallery found", file=sys.stderr)
192192
return 1
193193
old = None
194194
if args.baseline:
195195
p = Path(args.baseline)
196196
old = load_gallery(p / "persons" if (p / "persons").is_dir() else p)
197197

198198
def size(g):
199-
return f"{len(g)} Personen / {sum(len(e) for _, e in g.values())} Fotos"
199+
return f"{len(g)} persons / {sum(len(e) for _, e in g.values())} photos"
200200

201-
print(f"jetzt: {size(new)}")
201+
print(f"now: {size(new)}")
202202
if old:
203-
print(f"vorher: {size(old)}")
204-
print(f"Schwelle {thr}, gemittelt ueber {TOP_K} Foto(s)\n")
203+
print(f"before: {size(old)}")
204+
print(f"threshold {thr}, averaged over {TOP_K} photo(s)\n")
205205

206206
# 1) Leave-one-out. Testmenge ist die aeltere Galerie, damit keine Seite ihre
207207
# eigenen Neuzugaenge benotet.
208208
test = old or new
209209
r_new = leave_one_out(test, new, thr)
210-
print(f"Leave-one-out ({r_new['n']} Testgesichter)")
211-
print(f"{'':22s} {'vorher':>10s} {'jetzt':>10s}" if old else f"{'':22s} {'jetzt':>10s}")
210+
print(f"Leave-one-out ({r_new['n']} test faces)")
211+
print(f"{'':22s} {'before':>10s} {'now':>10s}" if old else f"{'':22s} {'now':>10s}")
212212
if old:
213213
r_old = leave_one_out(test, old, thr)
214-
for lbl, k in (("korrekt erkannt", "hit"), ("falsche Person", "wrong"),
215-
("nicht erkannt", "miss")):
214+
for lbl, k in (("recognised correctly", "hit"), ("wrong person", "wrong"),
215+
("not recognised", "miss")):
216216
print(f" {lbl:20s} {r_old[k]:>10d} {r_new[k]:>10d}")
217-
print(f" {'mittlerer Score':20s} {r_old['score']:>10.3f} {r_new['score']:>10.3f}")
217+
print(f" {'mean score':20s} {r_old['score']:>10.3f} {r_new['score']:>10.3f}")
218218
else:
219-
for lbl, k in (("korrekt erkannt", "hit"), ("falsche Person", "wrong"),
220-
("nicht erkannt", "miss")):
219+
for lbl, k in (("recognised correctly", "hit"), ("wrong person", "wrong"),
220+
("not recognised", "miss")):
221221
print(f" {lbl:20s} {r_new[k]:>10d}")
222-
print(f" {'mittlerer Score':20s} {r_new['score']:>10.3f}")
222+
print(f" {'mean score':20s} {r_new['score']:>10.3f}")
223223

224224
if args.days > 0:
225225
print()
226226
lp = live_probe(old, new, args.days, thr, cfg)
227-
print(f"Praxisprobe ({args.days:g} Tage): {lp['events']} Ereignisse, "
228-
f"{lp['faces']} mit verwertbarem Gesicht"
229-
+ (f" ({lp['selfhits']} Selbsttreffer ausgeschlossen)" if lp["selfhits"] else ""))
227+
print(f"Practical probe ({args.days:g} days): {lp['events']} events, "
228+
f"{lp['faces']} with a usable face"
229+
+ (f" ({lp['selfhits']} self-hits excluded)" if lp["selfhits"] else ""))
230230
f = max(lp["faces"], 1)
231231
if old:
232-
print(f" erkannt vorher: {lp['old']:3d} ({100*lp['old']//f:3d}%) "
233-
f"jetzt: {lp['new']:3d} ({100*lp['new']//f:3d}%)")
234-
print(f" beide erkannt, aber anderer Name: {lp['disagree']}")
232+
print(f" recognised before: {lp['old']:3d} ({100*lp['old']//f:3d}%) "
233+
f"now: {lp['new']:3d} ({100*lp['new']//f:3d}%)")
234+
print(f" recognised by both but under a different name: {lp['disagree']}")
235235
if lp["gained"]:
236-
print(f" neu erkannt: {dict(lp['gained'])}")
236+
print(f" newly recognised: {dict(lp['gained'])}")
237237
else:
238-
print(f" erkannt: {lp['new']} ({100*lp['new']//f}%)")
238+
print(f" recognised: {lp['new']} ({100*lp['new']//f}%)")
239239

240240
if lp["per_person"]:
241241
# Ein Treffer knapp ueber der Schwelle faellt bei schlechterem Licht weg —
242242
# deshalb zaehlt der Abstand, nicht nur das Ja/Nein.
243-
print("\n Sicherheitsabstand je erkannter Person:")
244-
print(f" {'Person':24s} {'Treffer':>7s} {'Median':>7s} {'min':>6s} {'knapp':>6s}")
243+
print("\n Headroom above the threshold, per recognised person:")
244+
print(f" {'person':24s} {'hits':>7s} {'median':>7s} {'min':>6s} {'tight':>6s}")
245245
for name, scores in sorted(lp["per_person"].items(),
246246
key=lambda kv: -len(kv[1])):
247247
sc = sorted(scores)
248-
knapp = sum(1 for v in sc if v < thr + 0.05)
248+
tight = sum(1 for v in sc if v < thr + 0.05)
249249
mark = " *" if name in FAVORITES else ""
250250
print(f" {(name + mark)[:24]:24s} {len(sc):>7d} "
251-
f"{sc[len(sc)//2]:>7.2f} {sc[0]:>6.2f} {knapp:>6d}")
251+
f"{sc[len(sc)//2]:>7.2f} {sc[0]:>6.2f} {tight:>6d}")
252252
if FAVORITES:
253-
print(" * = Favorit")
253+
print(" * = favourite")
254254
return 0
255255

256256

0 commit comments

Comments
 (0)