AutoFeedback API

Result 09c1a7d7-2746-4ea5-902b-79afe0ea1c1b

{
  "llm" : {
    "feedback" : "# Exercise: parking\n\n### Correctness\n- `FlatRateCard.cost()` erfüllt die Vorgabe „fixe Monatskosten von 150 CHF“ nicht vollständig: Du gibst 150 nur zurück, wenn überhaupt geparkt wurde, sonst 0. Laut Aufgabenstellung sind es fixe Monatskosten (unabhängig davon, ob/ wie viel geparkt wurde).\n- Mit deiner aktuellen `FlatRateCard`-Logik wird der geforderte Gesamtumsatz von **156.75 CHF** (aus dem Aufgabenstatement) bei den gegebenen Parkzeiten nicht erreicht.\n\n### Suggestion\n- Überlege bei der `FlatRateCard`, was „fixe Monatskosten“ im Kontext von `cost()` und `reset()` bedeutet: Soll `cost()` vom Parken abhängen oder immer den Abo-Preis liefern? Und was genau soll `reset()` bei einem Abo zurücksetzen?\n- Rechne einmal den erwarteten Umsatz aus den drei Karten-Typen mit den im Beispiel verwendeten Parkzeiten nach und vergleiche das mit deiner Ausgabe; der Unterschied zeigt dir direkt, welche Karte sich anders verhalten muss.\n\n### Code Style\n- In `FlatRateCard` ist `totalTime` vermutlich gar nicht nötig, wenn es wirklich eine Pauschale ist; das macht die Klasse unnötig komplex.\n- Exception-Message in `GroupCard` könnte präziser sein (z.B. den übergebenen Wert mit ausgeben), damit man beim Debuggen schneller sieht, was passiert ist.\n\n\n# Exercise: labyrinth\n\n### Correctness\n- In `BacktrackingAlgorithm` setzt du `direction = 2` “je nach Level” und verwendest damit eine level-/startorientierungsabhängige Annahme; gefordert ist aber ein allgemeiner Algorithmus, der für alle Labyrinthe funktioniert, ohne manuelles Anpassen.\n- Dein Backtracking merkt sich nicht, welche Felder/Kanten bereits besucht wurden; dadurch kann der Algorithmus in Labyrinthen mit Zyklen/Schleifen (z.B. wenn man wieder an eine frühere Kreuzung kommt) potenziell unendlich laufen bzw. extrem lange pendeln, statt garantiert ein Ziel zu finden.\n- Die Variable `direction` ist in deiner Logik nicht an `figure.dir()` gekoppelt (du liest `figure.dir()` nie aus) und kann damit von der tatsächlichen Blickrichtung der Figur abweichen; wenn du sie für Korrektheit bräuchtest, wäre das ein Problem (aktuell wirkt sie eher wie „Pseudo-State“).\n- Die Rücksprung-Logik bei `pathToTheRight()` / `pathToTheLeft()` stellt die Blickrichtung nach einem Fehlschlag nicht konsistent wieder her: Du drehst beim Backtrack schon mit `turnAround()` zweimal und machst danach zusätzlich noch `turnLeft()` bzw. `turnRight()`; damit kann die Orientierung nach dem Block verlassen anders sein als vor dem Block.\n\n### Suggestion\n- Überlege dir, wie dein Algorithmus ohne „Start-Dir pro Level“ auskommt: Die Figur kennt ihre aktuelle Richtung selbst über `dir()` und die Pfad-Checks sind relativ (ahead/left/right); nutze das so, dass nichts hart codiert werden muss.\n- Damit Backtracking in Labyrinthen mit Schleifen terminiert, brauchst du eine Art „Gedächtnis“: z.B. welche Positionen (und ggf. mit welcher Richtung) schon in einem bestimmten Zustand abgearbeitet wurden, oder welche Abzweigungen an einer Kreuzung bereits ausprobiert sind.\n- Wenn du eine eigene `direction`-Variable behältst, synchronisiere sie konsequent mit der echten Figur-Richtung (oder lass sie ganz weg und verlasse dich nur auf die Figure-API), sonst wird das Debuggen sehr schwierig.\n- Prüfe deine Invariante „Nach dem Versuch eines Zweigs stehe ich wieder am selben Knoten und schaue wieder in die gleiche Richtung wie vor dem Versuch“: Geh die Drehungen Schritt für Schritt durch (für rechts/links/ahead) und kontrolliere, ob du am Ende wirklich exakt denselben Zustand wiederherstellst.\n\n### Code Style\n- In `BacktrackingAlgorithm` ist `direction` aktuell faktisch ungenutzt für die Entscheidung (nur mitgeführt); entweder entfernen oder so einsetzen, dass klar ist, wozu sie dient.\n- Der Kommentar „Anpassen je nach Level“ wirkt wie ein Workaround im Code; wenn der Algorithmus allgemein sein soll, würde ich solche Hinweise vermeiden bzw. durch eine saubere Herleitung ersetzen.\n- Viele Backtrack-Blöcke sind fast identisch (move, recurse, backtrack, restore); das schreit nach einer kleinen Hilfsmethode, um Duplikation zu reduzieren und Fehler in der Orientierung leichter zu vermeiden.\n\n\n# Exercise: swissmap\n\n### Correctness\n- Die Klasse `InteractiveArea` implementiert zwar `Shape`, aber `contains(...)` gibt immer `false` zurück; falls Du diese Klasse irgendwo verwenden würdest, würde Hover/Interaktion nie auslösen (und aktuell ist sie damit auch keine funktionierende Option als interaktiver Bereich).\n- Beim `ModeButton` verwendest Du `gui.setColor(new Color(1,1,1,50))`/`new Color(1,1,1,100)`; je nach `Color`-API sind das sehr wahrscheinlich nicht die erwarteten Wertebereiche (oft 0–255 oder 0.0–1.0), wodurch Transparenz/Farbe nicht wie beabsichtigt funktioniert oder sogar fehlschlägt.\n\n### Suggestion\n- Falls Du eine eigene `Shape`-Klasse behalten willst: Überlege Dir, wie `contains(x, y)` für Deinen Button/Marker tatsächlich entscheiden kann, ob ein Mauspunkt innerhalb liegt (z. B. über Grenzen um eine Position). Teste danach gezielt, ob `onMouseEnter/Exit` dann zuverlässig feuert.\n- Prüfe in der Doku/Signatur von `ch.trick17.gui.Color`, welche Wertebereiche die Konstruktorparameter erwarten. Wenn es z. B. 0–255 sind, müssen Deine aktuellen `1,1,1` fast schwarz ergeben; wenn es 0.0–1.0 sind, ist `50` als Alpha deutlich ausserhalb.\n\n### Code Style\n- In `ModeButton` sind Imports chaotisch/teilweise falsch bzw. unnötig (`import ch.trick17.gui.Gui.*;`, Wildcard-Imports, und gleichzeitig `import ch.trick17.gui.Gui;`). Räume das auf und importiere nur das, was Du wirklich brauchst.\n- `InteractiveArea` ist derzeit unbenutzt und zudem “Dummy”-implementiert; entweder entfernen oder korrekt implementieren und dann auch wirklich verwenden.\n- In `City.draw(...)` rufst Du `coord.toGuiX(gui)`/`toGuiY(gui)` mehrfach auf; speichere die Werte einmal in lokale Variablen, das macht den Code lesbarer und vermeidet Wiederholungen.\n- In `SwissMapApp` ist `Component button = new ModeButton(map);` unnötig allgemein; Du kannst direkt als `ModeButton` typisieren, solange Du nicht bewusst den Supertyp brauchst.\n\n\n# Exercise: visualizer\n\n### Correctness\n- In `Processor.getY()` wendest du `Math.log10(...)` direkt auf den Wert an und skalierst danach mit `/1000`; laut Aufgabenstellung soll die _y_-Achse logarithmisch sein, aber der Datenpunkt selbst soll als _effektive Rechengeschwindigkeit_ (Taktfrequenz * Cores) geliefert werden (die Log-Skalierung gehört damit nicht in die Daten, sondern in die Darstellung).\n- In `Processor.getDetails()` gibst du `clockRateKhz` mit dem Suffix `\"Mhz\"` aus, obwohl der Wert laut Feldname in kHz ist; zusätzlich verlangt die Aufgabe eine Umrechnung in kHz/MHz/GHz mit passender Formatierung (MHz/kHz ganzzahlig, GHz mit Dezimalstelle(n)).\n- In `Processor.getX()` kombinierst du Jahr und Monat als `year + month/12.0`; die Aufgabe verlangt explizit, Jahr und Monat zu einem einzigen Wert zu kombinieren (Monat als „Monatsindex“ im Jahr). Mit deiner Formel ist z.B. Januar nicht der „erste Monat“ im Jahr (weil du nicht klar definierst, ob `month` 0- oder 1-basiert ist), und es entstehen Off-by-one-Unschärfen.\n\n### Suggestion\n- Überleg dir, welche Klasse „wissen“ sollte, dass die y-Achse logarithmisch ist: der `Visualizer` (Darstellung) oder der `DataPoint` (Rohdaten). Wenn du im `DataPoint` bereits log-transformierst, wird es schwer, Details/Tooltips konsistent mit den „echten“ Werten zu halten.\n- Schau dir beim Prozessor-Datensatz die geforderte Reihenfolge genau an: erst „effektive Geschwindigkeit“ berechnen (aus kHz * cores), und erst danach überlegen, wie man sie für die Anzeige skaliert (Achsentyp). Prüfe dabei auch, ob du wirklich durch 1000 teilen willst, oder ob du stattdessen eine Einheitenumrechnung sauber trennst.\n- Für die Monats-Kombination: lege fest, ob `month` im CSV 1–12 ist, und baue dann eine eindeutige lineare Zeitachse (z.B. Jahr plus Bruchteil basierend auf dem Monatsindex). Teste mit zwei aufeinanderfolgenden Monaten, ob der Abstand konstant ist.\n- Für die Taktfrequenz-Anzeige: nimm den kHz-Wert als Ausgangspunkt und leite daraus ab, ob kHz/MHz/GHz sinnvoll ist; formatiere dann abhängig von der Einheit (Integer vs. Dezimalzahl), statt einfach ein fixes `\"Mhz\"` anzuhängen.\n\n### Code Style\n- In `Movie.getX()` steht der Kommentar `// Beispiel`, der hier wie ein Überbleibsel wirkt; den würde ich entfernen, damit klar ist, dass das deine finale Entscheidung ist.\n- Die Detailstrings sind teils inkonsistent formatiert (Kommas, Leerzeichen, Zeilenumbrüche, „core“ vs. „cores“, Einheiten-Schreibweise „Mhz“); ein einheitliches Format macht die Hover-Ansicht deutlich lesbarer.\n",
    "status" : "SUCCESS"
  }
}