AutoFeedback API

Result ae9d258a-a4b6-4ffc-9c30-313b63a7d3b7

{
  "llm" : {
    "feedback" : "# Exercise: address\n\n### Correctness\n- `getCity()` wirft eine `IllegalArgumentException`, wenn `city` leer ist; laut Aufgabe sollen aber Konstruktor und Setter bei ungültigen Argumenten werfen (Getter nicht).\n- `getCity()` prüft nur `isEmpty()`, aber nicht auf `null`; wenn `city` (z.B. durch zukünftige Änderungen/Refactoring) doch mal `null` wäre, gäbe es hier eine `NullPointerException` statt der geforderten sauberen Invariante/Exception-Strategie.\n\n### Suggestion\n- Überlege, wo die Invarianten laut Aufgabenstellung erzwungen werden sollen: Eingaben beim Setzen/Konstruieren validieren und danach beim Lesen einfach zurückgeben.\n- Wenn du dennoch im Getter validieren willst, dann konsistent mit den Invarianten prüfen (inkl. `null`) und dir bewusst machen, ob das wirklich zur geforderten API passt.\n\n### Code Style\n- Du hast dieselben Validierungsblöcke mehrfach (Konstruktor + Setter). Das lässt sich besser wartbar machen, indem du die Checks zentralisierst (z.B. private Hilfsmethoden oder Konstruktor nutzt Setter intern).\n- Fehlermeldungen bei `zipCode` sind etwas ungenau: du prüfst „vierstellig“, aber die Message sagt nur „muss positiv sein“ (besser wäre eine Nachricht, die genau den Grund nennt).\n\n\n# Exercise: timespan\n\n### Correctness\n- In `add(...)` wird die Invariante „Zeitspanannen können nur verlängert werden“ nicht korrekt geprüft: `if(totalMinutes() >= this.minutes)` vergleicht den aktuellen Gesamtzustand mit den aktuellen Minuten (`this.minutes`) statt sicherzustellen, dass der neue Zustand nicht kleiner als der alte wird. Damit kann Verkürzen weiterhin passieren (z.B. durch negative Werte – die du zwar verbietest – aber auch, weil die Bedingung praktisch immer true ist).\n- Die Precondition für „nicht verkürzen“ fehlt inhaltlich: Du wirfst nur bei negativen Parametern eine Exception, aber du prüfst nicht explizit, dass `totalMinutes` nach dem Addieren mindestens so gross ist wie vorher (old(totalMinutes)).\n- `checkMinutes()` stellt die Invariante `0 ≤ getMinutes ≤ 59` nicht vollständig sicher: Wenn `this.minutes` nach einer Addition negativ wäre (z.B. falls doch mal ein falscher Zustand entsteht), wird das nicht korrigiert. (Auch wenn du negative Eingaben verbietest, sollte die Invariante ohne Preconditions gelten.)\n- Der Konstruktor setzt `hours/minutes` direkt und normalisiert erst danach. Dadurch ist `totalMinutes()` zwar nicht negativ (wegen deiner Prüfung), aber die Anforderung formuliert die Invarianten aus Client-Sicht; es ist sauberer, wenn der Zustand gar nie „unnormalisiert“ beobachtbar ist (z.B. falls später weitere Methoden dazukommen, die im Konstruktor zwischenzeitlich genutzt würden).\n\n### Suggestion\n- Für die „nicht verkürzen“-Bedingung: Speichere vor der Änderung den alten Gesamtwert und vergleiche ihn mit dem Gesamtwert, der nach dem geplanten Addieren entstehen würde (ohne den Zustand schon zu verändern). Wenn der neue kleiner wäre, dann Exception.\n- Die Bedingung `totalMinutes() >= this.minutes` ist verdächtig: Überlege dir, welche Grössen hier sinnvoll vergleichbar sind (alt vs. neu) und welche Einheiten (Minuten vs. Gesamtminuten) du tatsächlich vergleichen willst.\n- Für `getMinutes`-Invariante: Stell sicher, dass die Normalisierung wirklich immer greift und auch dann korrekt ist, wenn `minutes` sehr gross ist (mehrere Stunden) — das machst du im Prinzip schon mit `/60`, aber achte darauf, dass der Rest wirklich aus dem aktuellen Feld berechnet wird (keine Verwechslung von `minutes` und `this.minutes`).\n\n### Code Style\n- Exception-Message `\"negativ\"` ist sehr knapp; eine klarere Nachricht (z.B. welche Werte nicht erlaubt sind) erleichtert Debugging.\n- In `checkMinutes()` nutzt du gemischt `this.minutes` und `minutes` (ohne `this`) in der Rechnung (`this.minutes = minutes - ...`). Das ist zwar aktuell dasselbe Feld, wirkt aber leicht fehleranfällig/unklar; bleib konsistent bei `this.minutes`.\n- `checkMinutes()` ist ein guter Ansatz, aber benenne Variablen wie `divide` etwas sprechender (z.B. was da eigentlich berechnet wird), damit die Logik schneller verständlich ist.\n\n\n# Exercise: asteroids\n\nLlm Evaluation ist für diese Aufgabe deaktiviert. Entferne die .llmignore Datei vom Package der Aufgabe.\n\n\n# Exercise: smarthome\n\n### Correctness\n- `turnNextRoomBright` hellt nicht nur den *ersten* passenden Raum auf, sondern läuft über alle Räume und verändert dabei potenziell mehrere/alle Räume.\n- `turnNextRoomBright` prüft die Bedingung “nicht alle Lampen sind an und auf 1.0” nicht auf Raum-Ebene, sondern schaltet/ändert Lampen teilweise unabhängig davon; dadurch kann das Verhalten von der Aufgabenbeschreibung abweichen.\n- `saveEnergy` schaltet die “günstigste” Lampe nicht zuverlässig erst *nach* dem Finden ein und alle anderen aus: Du schaltest `minLamp`/Brightness bereits innerhalb der Suchschleife und schaltest andere Lampen nur aus, wenn sie gerade `isOn()` sind (Anforderung: “alle anderen Lampen werden ausgeschaltet”).\n- `findBedrooms` baut das Ergebnis-Array falsch auf: `bedrooms` wird in jeder Iteration neu als leeres Array erstellt, du gibst sehr früh (innerhalb der Schleife über `rooms`) zurück, und bei `bedrooms.length == 0` wird das Kopieren/Anhängen gar nie ausgeführt → Ergebnis enthält i.d.R. keine Bedrooms oder ist falsch.\n- `findBedrooms` gibt im “kein Treffer”-Fall am Schluss `rooms` zurück; gefordert ist ein Array mit (nur) Bedroom-Räumen (darf größer sein und nulls enthalten), aber nicht einfach alle Räume.\n- `nightMode` ist nicht implementiert.\n\n### Suggestion\n- Für `turnNextRoomBright`: Überlege dir eine Variable/Logik, mit der du pro Raum zuerst feststellst, ob der Raum “noch nicht komplett hell” ist, und dann nur diesen ersten Raum veränderst (danach keine weiteren Räume mehr anfassen).\n- Für `saveEnergy`: Trenne die Aufgabe in zwei Schritte: (1) Minimum-Lampe im Raum bestimmen, ohne dabei Zustände zu ändern, (2) danach in einer zweiten Runde im selben Raum Zustände setzen (Minimum an + 0.8, alle anderen aus), unabhängig davon, ob sie vorher an waren.\n- Für `findBedrooms`: Erzeuge das Ergebnis-Array einmal (maximale Größe = `rooms.length`) und fülle es beim Durchlaufen der Räume fortlaufend (z.B. mit einem Index/Zähler). Achte darauf, dass das `return` erst nach der Schleife kommt.\n- Für `nightMode`: Nutze wirklich `findHallway()` und `findBedrooms()`, schalte zuerst global alles aus, und schalte dann gezielt in Hallway und jedem Bedroom genau *eine* Lampe ein (beliebige, z.B. die erste), jeweils mit Brightness 0.3.\n\n### Code Style\n- In `randomize` erzeugst du in der inneren Lampen-Schleife jedes Mal ein neues `Random`-Objekt; besser ein einziges `Random` verwenden.\n- Mehrfaches `if (room.getLamps() != null)` ist wahrscheinlich unnötig, da laut Vorlage `lamps` beim `Room`-Konstruktor gesetzt wird; das macht den Code schwerer lesbar.\n- In `turnNextRoomBright` ist die zusätzliche Schleife `for(int i = 0; i < rooms.length; i++)` innerhalb eines einzelnen Raums sehr verwirrend und wirkt wie ein Versehen (du iterierst über `rooms.length`, benutzt `i` aber nicht).\n- `findBedrooms` erstellt neue `Room`-Objekte (`new Room(...)`), obwohl du nur existierende Räume sammeln sollst; das erschwert Debugging und ist unnötige Arbeit.\n- Unnötiger Import/Verwendung: `Objects.equals` ist ok, aber bei konstantem String-Vergleich wäre auch `\"Hallway\".equals(room.getName())` üblich und spart den Import.\n\n\n# Exercise: bosses\n\nLlm Evaluation ist für diese Aufgabe deaktiviert. Entferne die .llmignore Datei vom Package der Aufgabe.\n",
    "status" : "SUCCESS"
  }
}