Trend-Radar + Pruefstand: Box beobachtet Modell-/Engine-Trends und testet Kandidaten selbst
- trend-radar-feed.sh (Cron Sa 05:15): Live-Puls ALLER Rollen mit Vorwochen-Vergleich, Engine-A/B gegen neuen llama.cpp-Build (Fruehwarnung vor So-Auto-Update), mechanische Watch-Liste (MMQ-Issue, ROCm-Releases, Community-Grid), HF-Kandidaten-Suche mit Zitat-Gate -> max. 1 Pruefstand-Kandidat/Woche - pruefstand.sh + harness.py (Cron So 01:00, no-agent): volles Programm je Kandidat - 6 Coding-Aufgaben mit echten Unit-Tests, 4 Agenten-Aufgaben (Tool-Loop + Endzustand), 4 Recherche-Fragen mit Zitat-Ehrlichkeits-Gate, Deutsch-Richter, Vision-Testbild, Tempo kurz+lang; Baseline der Amtsinhaber als Vergleichsmassstab - Leitplanken (User-Entscheid 17.07.): Download-Deckel 35 GB (drueber -> Karte), 1 Kandidat/Woche, Cache mit Auto-Aufraeumen, RAM-/Platz-Wache, Bench-Port :5899, Radar/Pruefstand EMPFEHLEN nur - Rollen-Wechsel bleibt Commander-Klick - E2E bewiesen (Mock-LLM): coding 6/6, recherche 4/4 inkl. Zitat-Gate, Agent-Roundtrip, Richter-Parsing; Suiten-Selbsttest mit Referenzloesungen 6/6 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"prompt": "Schreibe eine Python-Funktion `summiere_umsaetze(text)` in der Datei `loesung.py`. Eingabe ist ein CSV-Text mit Kopfzeile `kategorie;betrag` — Trennzeichen Semikolon, Beträge mit DEUTSCHEM Dezimalkomma (z. B. `12,50`). Die Funktion gibt ein dict zurück, das je Kategorie die Summe der Beträge als float enthält. Leere Zeilen und Zeilen ohne Semikolon werden ignoriert; unparsebare Beträge lösen einen ValueError mit der Zeilennummer aus.",
|
||||
"antwort_datei": "loesung.py",
|
||||
"timeout_s": 60
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from loesung import summiere_umsaetze
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_summen(self):
|
||||
text = ("kategorie;betrag\n"
|
||||
"essen;12,50\n"
|
||||
"essen;7,50\n"
|
||||
"\n"
|
||||
"strom;30,00\n")
|
||||
self.assertEqual(summiere_umsaetze(text),
|
||||
{"essen": 20.0, "strom": 30.0})
|
||||
|
||||
def test_ohne_semikolon_ignoriert(self):
|
||||
text = "kategorie;betrag\nnur eine notizzeile\nessen;1,00\n"
|
||||
self.assertEqual(summiere_umsaetze(text), {"essen": 1.0})
|
||||
|
||||
def test_kaputter_betrag(self):
|
||||
with self.assertRaises(ValueError):
|
||||
summiere_umsaetze("kategorie;betrag\nessen;zwoelf\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = unittest.main(exit=False).result
|
||||
sys.exit(0 if r.wasSuccessful() else 1)
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"prompt": "In der Datei `zeitfenster.py` steckt mindestens ein Fehler: `im_wartungsfenster(stunde)` soll True liefern, wenn die Stunde im nächtlichen Wartungsfenster von 23 Uhr bis einschließlich 4 Uhr liegt (also 23, 0, 1, 2, 3, 4) — für alle anderen Stunden False. Ungültige Stunden (<0 oder >23) sollen einen ValueError auslösen. Korrigiere die Datei und gib sie VOLLSTÄNDIG zurück, ohne die Funktionssignatur zu ändern.",
|
||||
"antwort_datei": "zeitfenster.py",
|
||||
"dateien": {
|
||||
"zeitfenster.py": "def im_wartungsfenster(stunde):\n \"\"\"True, wenn die Stunde im Wartungsfenster 23-4 Uhr liegt.\"\"\"\n if stunde < 0 or stunde > 24:\n raise ValueError(\"ungueltige Stunde\")\n return 23 <= stunde or stunde < 4\n"
|
||||
},
|
||||
"timeout_s": 60
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from zeitfenster import im_wartungsfenster
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_im_fenster(self):
|
||||
for h in (23, 0, 1, 2, 3, 4):
|
||||
self.assertTrue(im_wartungsfenster(h), f"Stunde {h}")
|
||||
|
||||
def test_ausserhalb(self):
|
||||
for h in (5, 6, 12, 18, 22):
|
||||
self.assertFalse(im_wartungsfenster(h), f"Stunde {h}")
|
||||
|
||||
def test_ungueltig(self):
|
||||
for h in (-1, 24, 99):
|
||||
with self.assertRaises(ValueError):
|
||||
im_wartungsfenster(h)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = unittest.main(exit=False).result
|
||||
sys.exit(0 if r.wasSuccessful() else 1)
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"prompt": "Schreibe in `loesung.py` eine Funktion `fehler_zeilen(log_text)`. Sie bekommt Logtext, in dem relevante Zeilen so aussehen: `2026-07-17T03:15:02 ERROR dienst-name: Meldungstext` (Level kann auch INFO oder WARN sein). Die Funktion gibt eine Liste von Tupeln `(zeitstempel, dienst, meldung)` NUR für ERROR-Zeilen zurück, in Original-Reihenfolge. Zeilen in anderem Format werden still ignoriert. Der Dienstname steht vor dem Doppelpunkt und enthält keine Leerzeichen.",
|
||||
"antwort_datei": "loesung.py",
|
||||
"timeout_s": 60
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from loesung import fehler_zeilen
|
||||
|
||||
LOG = """2026-07-17T03:15:02 ERROR llama-swap: Modell nicht gefunden
|
||||
2026-07-17T03:15:03 INFO mc2: Start ok
|
||||
kaputte zeile ohne format
|
||||
2026-07-17T03:16:10 WARN voice: Latenz hoch
|
||||
2026-07-17T03:17:00 ERROR mem0-service: Timeout nach 30s
|
||||
"""
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_nur_error(self):
|
||||
erg = fehler_zeilen(LOG)
|
||||
self.assertEqual(len(erg), 2)
|
||||
self.assertEqual(erg[0][0], "2026-07-17T03:15:02")
|
||||
self.assertEqual(erg[0][1], "llama-swap")
|
||||
self.assertEqual(erg[0][2], "Modell nicht gefunden")
|
||||
self.assertEqual(erg[1][1], "mem0-service")
|
||||
|
||||
def test_leer(self):
|
||||
self.assertEqual(fehler_zeilen("nur INFO hier\n"), [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = unittest.main(exit=False).result
|
||||
sys.exit(0 if r.wasSuccessful() else 1)
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"prompt": "Schreibe in `loesung.py` eine Klasse `Lager`. Konstruktor ohne Argumente. Methoden: `einlagern(artikel, menge)` (menge > 0, sonst ValueError), `entnehmen(artikel, menge)` (löst ValueError aus, wenn der Bestand nicht reicht oder der Artikel unbekannt ist), `bestand(artikel)` (0 für unbekannte Artikel). Bestände sind ganze Zahlen je Artikelname.",
|
||||
"antwort_datei": "loesung.py",
|
||||
"timeout_s": 60
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from loesung import Lager
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_ablauf(self):
|
||||
l = Lager()
|
||||
l.einlagern("kabel", 10)
|
||||
l.entnehmen("kabel", 4)
|
||||
self.assertEqual(l.bestand("kabel"), 6)
|
||||
self.assertEqual(l.bestand("unbekannt"), 0)
|
||||
|
||||
def test_unterbestand(self):
|
||||
l = Lager()
|
||||
l.einlagern("kabel", 2)
|
||||
with self.assertRaises(ValueError):
|
||||
l.entnehmen("kabel", 3)
|
||||
with self.assertRaises(ValueError):
|
||||
l.entnehmen("gibtsnicht", 1)
|
||||
|
||||
def test_menge_positiv(self):
|
||||
l = Lager()
|
||||
with self.assertRaises(ValueError):
|
||||
l.einlagern("kabel", 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = unittest.main(exit=False).result
|
||||
sys.exit(0 if r.wasSuccessful() else 1)
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"prompt": "Schreibe in `loesung.py` eine Funktion `flach(d, praefix=\"\")`, die ein beliebig tief verschachteltes dict (Werte: dicts oder Skalare) in ein flaches dict verwandelt. Schlüsselpfade werden mit Punkt verbunden, z. B. macht `{\"a\": {\"b\": 1}, \"c\": 2}` daraus `{\"a.b\": 1, \"c\": 2}`. Leere dicts verschwinden ersatzlos. Nicht-dict-Eingaben lösen einen TypeError aus.",
|
||||
"antwort_datei": "loesung.py",
|
||||
"timeout_s": 60
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from loesung import flach
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_verschachtelt(self):
|
||||
self.assertEqual(flach({"a": {"b": 1, "c": {"d": 2}}, "e": 3}),
|
||||
{"a.b": 1, "a.c.d": 2, "e": 3})
|
||||
|
||||
def test_leere_dicts(self):
|
||||
self.assertEqual(flach({"a": {}, "b": 1}), {"b": 1})
|
||||
|
||||
def test_typfehler(self):
|
||||
with self.assertRaises(TypeError):
|
||||
flach([1, 2])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = unittest.main(exit=False).result
|
||||
sys.exit(0 if r.wasSuccessful() else 1)
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"prompt": "Schreibe in `loesung.py` eine Funktion `slug(text)`: wandelt deutschen Text in einen URL-Slug. Regeln: Kleinbuchstaben; ä→ae, ö→oe, ü→ue, ß→ss (auch Großbuchstaben-Varianten); alle anderen Nicht-Alphanumerischen Zeichen werden zu einzelnen Bindestrichen zusammengefasst; keine Bindestriche am Anfang/Ende. Beispiel: `Größte \"Änderung\" 2026!` → `groesste-aenderung-2026`.",
|
||||
"antwort_datei": "loesung.py",
|
||||
"timeout_s": 60
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from loesung import slug
|
||||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_beispiel(self):
|
||||
self.assertEqual(slug('Größte "Änderung" 2026!'),
|
||||
"groesste-aenderung-2026")
|
||||
|
||||
def test_umlaute(self):
|
||||
self.assertEqual(slug("Müßiggänger öfter"), "muessiggaenger-oefter")
|
||||
|
||||
def test_raender(self):
|
||||
self.assertEqual(slug(" --Hallo Welt-- "), "hallo-welt")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = unittest.main(exit=False).result
|
||||
sys.exit(0 if r.wasSuccessful() else 1)
|
||||
Reference in New Issue
Block a user