AutoFeedback API

Result 3739ca6f-db0f-4082-86fd-28625fa013ad

{
  "llm" : {
    "feedback" : "# Exercise: parking\n\n### Correctness\n- In `GroupCard` ist `HOURLY_RATE` als `static` definiert. Dadurch teilen sich alle `GroupCard`-Objekte denselben Tarif, und der zuletzt erstellte `GroupCard` kann den Tarif aller anderen Gruppenkarten überschreiben. Das verletzt die Anforderung, dass der Tarif **pro Karte** von der Personenanzahl (Konstruktorparameter) abhängt.\n\n### Suggestion\n- Überlege dir, ob der Stundentarif wirklich eine **Klassenvariable** sein soll oder ob jede `GroupCard` ihren **eigenen** (vom Konstruktor berechneten) Tarif speichern sollte. Teste das z.B., indem du zwei `GroupCard`s mit unterschiedlicher Personenanzahl registrierst und beide parkst: Bekommen beide sicher ihren korrekten Tarif?\n\n### Code Style\n- In `FlatRateCard` speicherst du `totalTime` und addierst in `park(...)` Minuten, obwohl `cost()` immer 150 zurückgibt. Das ist verwirrend, weil der Zustand hier keinen Einfluss auf die Kosten hat.\n- In `GroupCard` sind Feldnamen wie `PersonenAnzahl` (Großbuchstabe am Anfang) unüblich für Java-Instanzfelder; verwende konsistente Java-Konventionen (camelCase).\n- `HOURLY_RATE` in `GroupCard` ist nicht konstant (wird zur Laufzeit gesetzt), der Name wirkt aber wie eine Konstante. Das erschwert das Verständnis.\n\n\n# Exercise: labyrinth\n\n### Correctness\n- `TryStraightFirst`: Wenn links oder rechts frei ist, drehst du nur, machst aber in diesem Schleifendurchlauf keinen Schritt nach vorne; gefordert ist, dass in dem Fall auch gegangen wird (ansonsten kann die Figur je nach Situation unnötig „auf der Stelle“ drehen).\n- `BacktrackingAlgorithm`/`BacktrackingAlgorithmWithMemory`: Ohne „visited“-Logik kann dein rekursives Backtracking in Zyklen geraten (z.B. bei Schleifen im Labyrinth) und dadurch nicht terminieren bzw. sehr lange laufen; die Aufgabe verlangt einen allgemeinen Algorithmus für alle Labyrinthe.\n- `BacktrackingAlgorithmWithMemory`: Du hast zwar ein `visited`-Set, nutzt es aber nirgends – damit ist es faktisch kein Backtracking „mit Memory“ und löst das Zyklus-Problem nicht.\n- `Position`: Dein `hashCode()` ist nicht kompatibel zu `equals()` (du rufst `super.hashCode()`); damit kann ein `HashSet<Position>` gleiche Positionen nicht zuverlässig als „schon besucht“ erkennen.\n- `LabyrinthApp`: Du hast die vorgegebenen `MAPS` aus der Vorlage auskommentiert und durch eigene ersetzt; damit ist nicht sichergestellt, dass deine Lösung die geforderten Levels der Aufgabe schafft.\n\n### Suggestion\n- `TryStraightFirst`: Überlege dir, was pro Schleifeniteration passieren soll, wenn vorne blockiert ist, aber links/rechts frei ist: Reicht „nur drehen“ oder muss danach im selben Durchlauf auch eine Bewegung passieren?\n- Backtracking allgemein: Denke daran, dass „Backtracking“ in Labyrinthen ohne Gedächtnis bei Schleifen immer wieder in dieselben Zustände laufen kann. Überlege, welchen Zustand du als „besucht“ markierst (nur `(row,col)` oder auch die Blickrichtung?) und wann du ihn wieder entfernst (oder eben nicht).\n- `BacktrackingAlgorithmWithMemory`: Baue das `visited` so ein, dass du vor dem Rekursionsaufruf prüfst, ob der nächste Zustand schon besucht wurde, und ihn beim Betreten markierst.\n- `Position.hashCode()`: Recherchiere/überprüfe die Regel „equals/hashCode contract“ für Java-Collections und leite einen Hash aus denselben Feldern ab, die du in `equals` vergleichst.\n- `LabyrinthApp`: Teste am Ende unbedingt wieder mit den originalen Maps aus der Aufgabenstellung, sonst kannst du nicht verifizieren, ob dein Algorithmus wirklich „für alle diese Labyrinthe“ funktioniert.\n\n### Code Style\n- Methoden- und Variablennamen wie `rückwärtsLeft` enthalten Umlaute; das ist in Java zwar möglich, aber unüblich und kann in Tooling/Teams zu Problemen führen – besser ASCII-Namen verwenden.\n- `BacktrackingAlgorithmWithMemory`: `visited` ist aktuell unbenutzt (toter Code).\n- `LabyrinthApp`: Der Code zum Suchen von `startRow/startCol` berechnet Werte, die danach nie verwendet werden (toter Code).\n- `Position`: Felder könnten `final` sein, wenn sie sich nicht ändern; außerdem sind `r/c` kryptisch – sprechendere Namen erhöhen Lesbarkeit.\n\n\n# Exercise: swissmap\n\n### Correctness\n- In `SwissMapApp` ist die `main`-Methode als `void main()` deklariert; so wird sie in Java normalerweise 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`; damit wird das Bild in der Abgabe/bei anderen Rechnern sehr wahrscheinlich nicht gefunden (gefordert ist die Resource aus dem `resources`-Ordner per relativem Pfad wie bei `SwissMap`/`Lake`).\n- Die Hover-Beschreibung soll gemäss Aufgabe die **Beschreibung** anzeigen; du zeichnest bei City/Lake/Mountain nur den Namen (`this.name`/`name`) statt die Beschreibung (die du z.B. bereits über `toString()` hast).\n- `getInteractiveArea` ist bei City/Lake/Mountain nicht passend zur gezeichneten Form positioniert: Du zeichnest z.B. den City-Punkt um `(x-3, y-3)`, aber dein `Rectangle` startet bei `(x, y)` und deckt damit den Punkt nicht sauber ab (Hover kann “daneben” reagieren bzw. am Punkt evtl. gar nicht).\n\n### Suggestion\n- Prüfe, welche Methodensignatur Java als Einstiegspunkt erwartet, und passe die `main`-Methode entsprechend an, damit das Programm ohne Spezial-Runner startet.\n- Vergleiche deine Bildpfade mit dem Vorgehen in `SwissMap.draw`: Wenn `drawImage` Ressourcen lädt, sollte der Pfad relativ zum `resources`-Ordner sein (kein lokaler Benutzerpfad).\n- Überlege, welche Zeichenkette genau “Beschreibung” meint: Du hast in allen drei Klassen bereits eine Methode, die eine formatierte Beschreibung liefert.\n- Lass den interaktiven Bereich (Shape) geometrisch zur tatsächlich gezeichneten Grafik passen: gleicher Ursprung/Offset und eine realistische Breite/Höhe (z.B. um den Punkt/Icon herum statt ab der Koordinate nach rechts unten).\n\n### Code Style\n- Unnötige Imports: In `City` importierst du `java.awt.*`, nutzt davon aber nichts; in `ModeButton` sind `javax.swing.*` und `java.awt.*` ebenfalls unbenutzt.\n- Sichtbarkeiten/Konventionen: Felder wie `SwissMap map`, `boolean pressed`, `String text` und der `ModeButton`-Konstruktor sind package-private; üblich wäre hier explizit `private` für Felder und ein `public` Konstruktor (falls von aussen erstellbar).\n- In `ModeButton` sind `onMouseEnter/onMouseExit` leer, obwohl du `Hoverable` implementierst; entweder Hover-Verhalten wirklich nutzen (z.B. Highlight) oder das Interface weglassen, wenn es nicht gebraucht wird.\n\n\n# Exercise: visualizer\n\n### Correctness\n- Im `DataPoint`-Interface fehlen die verlangten Javadoc-Kommentare zur Dokumentation des erwarteten Verhaltens der Methoden.\n- Beim Prozessor-Datensatz wird die logarithmische y-Achse gefordert, aber du setzt den Logarithmus bereits in `Processor.getY()` um; damit ist die Achse nicht „logarithmisch“ im Sinne der Visualisierung, sondern du veränderst die Daten selbst (das kann zu falscher Interpretation führen, z.B. in der Detailanzeige).\n- In der Prozessor-Detailbeschreibung soll die Taktfrequenz in passende Einheiten (kHz/MHz/GHz) umgerechnet und formatiert werden; in `Processor.getText()` gibst du aktuell roh `clockRateKhz` aus.\n- Beim Film-Datensatz sollten die „restlichen Details“ der Hover-Anzeige/Legende den Screenshots entsprechen; mit `getLegend() = year` gruppierst du nach Jahr (sehr viele Gruppen), was sehr wahrscheinlich nicht der beabsichtigten Legende aus den Screenshots entspricht.\n\n### Suggestion\n- Ergänze zu jeder Methode in `DataPoint` eine kurze Javadoc-Beschreibung: Was bedeutet der Rückgabewert (x/y), wofür wird `getLegend()` genutzt (Gruppierung/Farbe), und wie sind `getHighlight()`/`getText()` für die Hover-Anzeige gedacht (z.B. Titel vs. mehrzeilige Details).\n- Überlege beim Prozessor-Plotten, wo die Log-Skalierung „hingehört“: eher als Darstellungs-/Skalierungsentscheidung im Visualizer (Mapping zur GUI) statt als Änderung des Messwerts im Datensatzpunkt. Prüfe dazu auch, was du in der Detailansicht anzeigen willst (typischerweise den echten Wert, nicht den geloggten).\n- Für die Taktfrequenz-Ausgabe: nutze `clockRateKhz` als Basis und leite daraus je nach Größe kHz/MHz/GHz ab; achte auf die geforderte Formatierung (kHz/MHz ohne Nachkommastellen, GHz mit Nachkommastelle(n)).\n- Schau dir nochmal die Screenshots an und leite daraus ab, welche Gruppierung/Farb-Legende für Movies plausibel ist (z.B. eher Kategorien wie „Studio/Genre/...“ falls vorhanden – oder evtl. gar keine Gruppierung → `null`). Deine aktuelle Wahl „Jahr“ erzeugt eine sehr lange Legende und kaum wiedererkennbare Gruppen.\n\n### Code Style\n- Entferne in `Visualizer` die nun ungenutzten Konstanten `DUMMY_DOUBLE` und `DUMMY_STRING` (und den TODO-Kommentar dazu), damit der Code nicht verwirrend bleibt.\n- Benennung im `DataPoint`: `getLegend()` ist semantisch etwas unscharf (liefert es den Gruppennamen?); wenn die Aufgabenstellung das offen lässt, ist es ok, aber dann sollte es zumindest per Javadoc eindeutig erklärt werden.\n- In `Processor.getText()` wäre eine klarere, einheitliche Formatierung (z.B. Labels pro Zeile) besser lesbar, besonders weil du später ohnehin Einheiten umrechnen musst.\n",
    "status" : "SUCCESS"
  }
}