AutoFeedback API

Result 956d9320-2a99-4907-8870-2b1f1c2a6ef3

{
  "llm" : {
    "feedback" : "# Exercise: parking\n\n### Correctness\n- `FlatRateCard` liefert mit `cost()` immer 150 CHF, auch nachdem `ParkingSystem.calculateRevenueAndReset()` `reset()` aufruft; damit wird bei jedem erneuten Umsatzlauf wieder 150 CHF addiert, obwohl das Abo nach dem Reset (analog zu den anderen Karten) nicht nochmals verrechnet werden dürfte.\n- In `GroupCard` ist `HOURLY_RATE` als `static` definiert: dadurch teilen sich alle `GroupCard`-Objekte denselben Tarif, und der zuletzt konstruierte `GroupCard` überschreibt den Tarif für alle anderen (falsche Kosten, sobald mehrere Gruppenkarten existieren).\n\n### Suggestion\n- Überlege dir bei der Abo-Karte, was `reset()` semantisch bedeuten soll: Wenn das System nach dem Reset nochmals Umsatz berechnet, sollte die Abo-Karte dann nochmals 150 CHF beitragen oder nicht? Passe den internen Zustand so an, dass `cost()` nach einem Reset nicht erneut den Monatsbetrag “gratis” nochmals liefert.\n- Prüfe bei der Gruppenkarte, ob der Tarif wirklich zu einer Klasse (static) oder zu einer konkreten Karte/Instanz gehört. Wenn jede Gruppenkarte ihren eigenen Tarif (abhängig von Personenanzahl) haben soll, muss dieser Wert pro Objekt gespeichert werden, nicht global.\n\n### Code Style\n- In `FlatRateCard` wird `totalTime` hochgezählt, aber nie für die Kostenberechnung verwendet; das macht die Klasse verwirrend.\n- In `GroupCard` sind Feldnamen gemischtsprachig/uneinheitlich (`PersonenAnzahl`, Parameter `i`); sprechende, konsistente Namen erleichtern das Verständnis.\n\n\n# Exercise: labyrinth\n\n### Correctness\n- In `TryStraightFirst` drehst du bei `pathToTheLeft()`/`pathToTheRight()` nur, machst aber in diesem Schleifendurchlauf keinen Schritt nach vorne; gefordert ist aber: wenn geradeaus nicht geht, dann links oder rechts **versuchen** (also abbiegen und dann auch laufen), sonst umkehren.\n- In `BacktrackingAlgorithm` / `BacktrackingAlgorithmWithMemory` probierst du nach dem „vorwärts“-Zweig direkt „links“ und „rechts“, ohne dich vorher wieder in die ursprüngliche Orientierung/Position zu bringen, falls „vorwärts“ zwar existierte, aber später fehlschlug und du zurückgekehrt bist (das machst du zwar mit `rückwärts(...)`, aber dadurch kann die Orientierung/Position für die folgenden Checks/Turns trotzdem leicht inkonsistent werden, je nachdem, in welchem Zweig du gerade warst). Dadurch kann es passieren, dass du „links“/„rechts“ relativ zu einer anderen Richtung prüfst/gehst als beabsichtigt.\n- In `BacktrackingAlgorithmWithMemory` markierst du eine Position als besucht unabhängig von der Blickrichtung. In Labyrinthen kann es Fälle geben, wo dieselbe Zelle mit anderer Orientierung erneut sinnvoll ist; mit deiner Speicherstrategie könntest du gültige Wege zu früh abschneiden.\n- In `LabyrinthApp` hast du die vorgegebenen `MAPS` auskommentiert und durch eigene ersetzt; damit erfüllst du die Aufgabe „mit diesem Algorithmus solltest du die Levels schaffen“ bezogen auf die mitgelieferten Levels nicht mehr.\n\n### Suggestion\n- Bei `TryStraightFirst`: Überlege, was in einem Iterationsschritt konkret passieren soll, wenn vorne zu ist, aber links frei ist. Reicht „nur drehen“ oder musst du danach auch die Aktion ausführen, die dich wirklich in die neue Zelle bringt?\n- Beim Backtracking: Achte darauf, dass nach jedem erfolglosen Versuch der Zustand (Position **und** Richtung) wieder exakt so ist wie vor dem Versuch, bevor du den nächsten Ast ausprobierst. Prüfe deine Rückwärts-Hilfsmethoden darauf, ob sie diesen Zustand wirklich immer herstellen.\n- Memory-Variante: Wenn du „visited“ benutzt, frage dich, ob „Zustand“ im Suchbaum nur aus `(row,col)` besteht oder ob `dir()` dazugehören könnte. Teste gezielt ein Labyrinth, wo man in dieselbe Zelle zurückkommt und nur mit anderer Blickrichtung weiterkommt.\n- Für die Abgabe/Tests: Lass die originalen `MAPS` drin und tausche nur den Algorithmus an der `TODO`-Stelle aus, damit du wirklich gegen die vorgesehenen Levels läufst.\n\n### Code Style\n- Du hast zwei Backtracking-Klassen (`BacktrackingAlgorithm` und `BacktrackingAlgorithmWithMemory`) mit sehr viel dupliziertem Code; entscheide dich für eine Variante oder extrahiere gemeinsame Logik, damit du nicht zweimal dieselben Fehler korrigieren musst.\n- Methoden- und Variablennamen mit Umlauten wie `rückwärts` sind in Java zwar möglich, aber unüblich und können in Tooling/Encoding Stress machen; bleib besser bei ASCII-Namen.\n- In `BacktrackingAlgorithmWithMemory` sind Parameter wie `currPos` und `visited` in den Rückwärtsmethoden aktuell effektiv ungenutzt (ausser auskommentierte Zeilen); entweder entfernen oder die Idee sauber umsetzen.\n- In `LabyrinthApp` ist sehr viel auskommentierter Code (die alten Maps); das macht das Projekt unnötig unübersichtlich.\n\n\n# Exercise: swissmap\n\n### Correctness\n- In `SwissMapApp` ist die `main`-Methode als `void main()` deklariert; so wird sie von Java nicht als Programmeinstieg erkannt (üblich ist eine `public static void main(String[] args)`-Signatur).\n- In `Mountain.draw` verwendest du einen absoluten Dateipfad zu `mountain.png`; das verletzt die Vorgabe, die Ressourcen aus dem `resources`-Ordner per Ressourcenpfad zu laden (und wird auf anderen Rechnern nicht funktionieren).\n- In `City.getInteractiveArea`, `Lake.getInteractiveArea` und `Mountain.getInteractiveArea` liegt das Rechteck nicht um das gezeichnete Objekt zentriert (du startest bei `(x,y)` statt z. B. um den Marker herum). Dadurch reagiert Hover an einer “falschen” Stelle relativ zur Darstellung.\n- In `City.draw` zeichnest du den Punkt, bevor du eine Farbe setzt; je nach GUI-Default kann der Punkt dadurch unsichtbar/unerwartet aussehen (die Aufgabe verlangt zwar keine konkrete Farbe, aber “Objekte wie dargestellt” setzt normalerweise sichtbare Marker voraus).\n\n### Suggestion\n- Schau dir die erwartete Signatur einer Java-Startmethode an und passe die Deklaration in `SwissMapApp` so an, dass die Klasse direkt ausführbar ist.\n- Verwende bei Bildern denselben Ressourcenpfad-Mechanismus wie bei `Lake` (und wie in `SwissMap.draw`): also einen relativen Pfad innerhalb von `resources` statt einen lokalen Dateisystempfad.\n- Überlege bei `getInteractiveArea`, wo dein Objekt tatsächlich gezeichnet wird (z. B. Punkt mit Radius 3 bzw. Icon-Grösse). Setze dann das Rechteck so, dass es den Marker/ das Bild wirklich umschliesst (Offset nach links/oben einrechnen).\n- Wenn du sicherstellen willst, dass Marker sichtbar sind, setze vor dem Zeichnen explizit eine passende Farbe (und ggf. danach wieder zurück, falls andere Komponenten betroffen sind).\n\n### Code Style\n- Entferne unbenutzte Imports: z. B. `java.awt.*` in `City`, `javax.swing.*` und `java.awt.*` in `ModeButton`, sowie doppelte/unnötige `Rectangle`/`Shape`-Imports in `ModeButton`.\n- Felder in `ModeButton` sollten gekapselt werden (`private`) und der Konstruktor sollte ebenfalls ein sinnvolles Sichtbarkeitslevel haben (z. B. `public`), damit klar ist, wie die Klasse verwendet werden soll.\n- Magische Zahlen wie `50,50,150,50` und Hover-Flächen `50x50` könntest du als Konstanten benennen, damit klar ist, was Button-Position/Grösse bzw. Hitbox-Grösse ist.\n\n\n# Exercise: visualizer\n\n### Correctness\n- Im `DataPoint`-Interface fehlen die geforderten Javadoc-Kommentare zur Dokumentation des erwarteten Verhaltens der Methoden.\n- Prozessor-Datensatz: Für die _y_-Achse soll laut Aufgabe die effektive Rechengeschwindigkeit (`clockRate * cores`) verwendet werden und die logarithmische Darstellung soll über eine logarithmische _y_-Achse passieren; in deinem `Processor.getY()` gibst du aber bereits den Logarithmus zurück (damit ist nicht mehr die effektive Geschwindigkeit selbst auf der y-Achse).\n- Prozessor-Datensatz: Die Detailbeschreibung soll die Taktfrequenz in eine geeignete Einheit (kHz/MHz/GHz) umrechnen und passend formatieren; in `Processor.getText()` gibst du `clockRateKhz` roh aus, ohne Einheit/Umrechnung/Format.\n- Film-Datensatz: In den Screenshots ist die Gruppierung/Legende nicht nach Jahr, sondern nach einem sinnvollen Kategorie-Merkmal gedacht (bei Filmen typischerweise nicht das Jahr als Legendeneintrag); `Movie.getLegend()` liefert bei dir das Jahr als String, wodurch extrem viele Legendeneinträge entstehen können und die Legende ihren Zweck verfehlt.\n\n### Suggestion\n- Ergänze bei jeder Methode im `DataPoint`-Interface kurz per Javadoc, **was** zurückgegeben werden soll (z.B. Bedeutung von x/y, was `getLegend()` bei `null` bedeutet, wie `getText()` formatiert ist, etc.).\n- Überlege beim Prozessor-Plot, wo die Log-Skalierung hingehört: Entweder liefert `getY()` die „echte“ Geschwindigkeit und die Skalierung passiert erst bei der Umrechnung ins GUI-Koordinatensystem, oder du definierst im Interface explizit, dass `getY()` bereits transformiert sein darf. Schau, was die Aufgabenstellung wörtlich verlangt.\n- Für die Prozessor-Taktfrequenz: Nimm den kHz-Wert und leite daraus abhängig von der Größenordnung kHz/MHz/GHz ab; achte dabei auch auf die Ausgabe als ganze Zahl vs. Dezimalzahl (wie in den Tipps beschrieben). Bau diese Darstellung in den Text für den Hover ein.\n- Für die Film-Legende: Prüfe anhand der Screenshots, welches Feld dort als Gruppierung dient (und wie viele verschiedene Gruppen sinnvoll sind). Wenn zu viele Gruppen entstehen, wird die Legende unbrauchbar – wähle ein Attribut, das wenige, wiederkehrende Kategorien ergibt.\n\n### Code Style\n- Entferne in `Visualizer` die unbenutzten Konstanten `DUMMY_DOUBLE`/`DUMMY_STRING`, sobald alles ersetzt ist (aktuell sind sie nur noch Altlasten).\n- In `Movie`, `Country`, `Processor`: Du hast weiterhin die ursprünglichen Getter (`getTitle()`, `getYear()`, …) plus die `DataPoint`-Methoden; das ist ok, aber wenn du sie nirgends mehr brauchst, könntest du überlegen, ob alle öffentlichen Getter wirklich noch notwendig sind (reduziert API-Oberfläche).\n- In `Processor.getText()`: Achte auf konsistente Formatierung (Zeilenumbrüche, Einheiten, ggf. Tausendertrennzeichen), damit der Hover-Text gut lesbar bleibt.\n",
    "status" : "SUCCESS"
  }
}