{
"llm" : {
"feedback" : "# Exercise: address\n\n### Correctness\n- In `getCity()` wirfst du eine `IllegalArgumentException`, wenn `city` leer ist. Laut Aufgabenstellung sollen aber **Konstruktor und Setter** bei ungültigen Argumenten werfen; ein Getter soll in der Regel keinen Validierungsfehler für den internen Zustand auslösen (zumal der Zustand durch deine Setter/Konstruktoren schon abgesichert sein sollte).\n- In `getCity()` prüfst du nur `city.isEmpty()`, aber nicht `city == null`. Falls `city` aus irgendeinem Grund doch `null` wäre, führt das zu einer `NullPointerException` statt zur geforderten `IllegalArgumentException`.\n\n### Suggestion\n- Überlege, wo Validierung laut Aufgabe hingehört: Wenn du die Invarianten konsequent in Konstruktor und Settern sicherstellst, braucht ein Getter keine Exception-Logik mehr und kann einfach den gespeicherten Wert zurückgeben.\n- Falls du in einem Getter trotzdem defensiv prüfen willst, dann achte darauf, dass du **dieselbe Art von Fehler** wie gefordert auslöst (und keine `NullPointerException` riskierst).\n\n### Code Style\n- Du wiederholst dieselben Validierungschecks und Fehlermeldungen in Konstruktor und Settern; das lässt sich sauberer lösen, indem du die Prüfungen zentralisierst (z.B. über private Hilfsmethoden oder indem der Konstruktor die Setter nutzt).\n- In den Fehlermeldungen für `zipCode` ist der Text etwas ungenau (du prüfst vierstellig, die Meldung sagt nur „positiv“); konsistente, präzise Messages helfen beim Debuggen.\n\n\n# Exercise: timespan\n\n### Correctness\n- Im Konstruktor werden keine Preconditions für negative Eingaben durchgesetzt: `add(hours, minutes)` wird mit negativen Werten aufgerufen, ohne dass diese zuverlässig abgefangen werden.\n- Die Negativ-Prüfung in `add` ist falsch platziert/ineffektiv: `if (totalMinutes() < 0)` prüft den *alten* Zustand vor dem Addieren, nicht die übergebenen Parameter oder den neuen Zustand.\n- Die Precondition “Zeitspannen können nur verlängert werden (totalMinutes ≥ old(totalMinutes))” wird nicht korrekt geprüft: `if (totalMinutes() >= this.minutes)` vergleicht Minuten mit Gesamtminuten und benutzt nicht die geplante Bedingung “neu ≥ alt”.\n- Wenn die (falsche) Bedingung im `if` nicht erfüllt ist, wird die Zeitspanne einfach nicht verändert, aber es wird auch keine `IllegalArgumentException` geworfen, obwohl laut Aufgabe eine Verletzung der Preconditions per Exception signalisiert werden soll.\n- Die Invariante `0 ≤ getMinutes ≤ 59` ist nicht immer garantiert: Nach `add` kann `minutes` negativ werden und `checkMinutes()` korrigiert das nicht zuverlässig (insbesondere im `minutes < 0`-Zweig bleibt `minutes` negativ oder wird nicht in den Bereich 0–59 gebracht).\n\n### Suggestion\n- Überlege, welche Werte du in `add(...)` und im Konstruktor wirklich prüfen musst: Es geht um die *Parameter* (keine negativen Stunden/Minuten) und darum, dass die neue Zeitspanne nicht kleiner wird als vorher.\n- Für die “nur verlängern”-Regel hilft es, vor dem Ändern den alten Gesamtwert zu speichern und nach dem Rechnen den neuen Gesamtwert zu vergleichen; bei Verletzung solltest du eine Exception werfen statt “einfach nichts zu tun”.\n- Für `0..59` Minuten: Denke daran, dass du Minuten-Überträge (≥60) und auch negative Minuten (falls sie überhaupt erlaubt wären) konsistent normalisieren musst, sodass `getMinutes()` am Ende immer im erlaubten Bereich liegt.\n\n### Code Style\n- `this.totalMinutes();` in `add()` hat keinen Effekt (Rückgabewert wird ignoriert) und kann entfernt werden.\n- Benenne Exceptions/Fehlermeldungen aussagekräftiger (z.B. nicht nur `\"negativ\"`), damit klar ist, welche Precondition verletzt wurde.\n- `checkMinutes()` mischt Logik für positive und negative Minuten, ist aber schwer nachvollziehbar; eine klarere, einheitliche Normalisierung (und nur für den tatsächlich erlaubten Eingaberaum) macht den Code wartbarer.\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: bosses\n\n### Correctness\n- `findCommonSuperiorWith(other)` liefert für den Fall, dass `this` der/die Vorgesetzte von `other` ist, nicht das erwartete Ergebnis (z.B. `headOfSales` mit `sara`): du startest bei `other.getBoss()` und nimmst damit `other` selbst aus der Kandidatenmenge heraus, obwohl laut Aufgabenstellung jede Person auch ihre eigene Vorgesetzte ist.\n- `findCommonSuperiorWith(other)` kann auch dann `null` zurückgeben, wenn es einen gemeinsamen Vorgesetzten gibt, wenn dieser gemeinsame Vorgesetzte genau `other` ist (z.B. `this` ist irgendein Untergebener von `other`): auch hier, weil `other` nie in deiner `bosses`-Liste landet.\n- `findCommonSuperiorWith(other)` vergleicht an einer Stelle mit `equals` (`commonSuperior.equals(superior)`), sonst aber per Identität/Referenz (`==`) bzw. `contains` (das intern `equals` nutzt). Da `Employee` kein eigenes `equals` überschreibt, ist das zwar aktuell zufällig konsistent, aber logisch ist es gemischt und kann bei späteren Änderungen zu falschen Resultaten führen.\n\n### Suggestion\n- Überlege dir für `findCommonSuperiorWith`: Welche Menge an “Vorgesetzten” soll für eine Person betrachtet werden, wenn “jede Person auch Vorgesetzte von sich selbst ist”? Starte die Kette entsprechend nicht erst bei `getBoss()`, sondern so, dass die Person selbst als Kandidat enthalten ist.\n- Prüfe die Symmetrie an Beispielen: Was sollte bei `(A.findCommonSuperiorWith(B))` herauskommen, wenn `A` über `B` steht bzw. `B` über `A` steht? Teste beide Richtungen und passe deine Sammellogik so an, dass beide Fälle funktionieren.\n- Entscheide dich in der Methode konsequent für eine Vergleichsstrategie (Referenzgleichheit oder logische Gleichheit) und wende sie überall gleich an, damit du nicht von der aktuellen `equals`-Implementierung abhängig bist.\n\n### Code Style\n- `import java.util.ArrayList;` ist nur für deine aktuelle Lösung nötig; grundsätzlich ok, aber für diese Aufgabe wäre auch eine Lösung ohne zusätzliche Collections möglich (weniger Overhead).\n- Verwende konsequent entweder `==` oder `equals(...)` (und dann idealerweise mit einem klar definierten `equals` in `Employee`), statt beides gemischt zu verwenden; das macht den Code leichter nachvollziehbar.\n- Variablennamen wie `superior` und `commonSuperior` sind teilweise irreführend (z.B. ist `commonSuperior` am Anfang nur der Boss von `this`); klarere Namen helfen beim Lesen und Debuggen.\n\n\n# Exercise: smarthome\n\n### Correctness\n- `turnNextRoomBright`: Du schaltest aktuell (durch die Struktur deiner Schleifen) effektiv in *allen* Räumen alle Lampen auf `on` und setzt die Helligkeit auf `1.0` (anstatt nur im **ersten** Raum, der die Bedingung nicht erfüllt).\n- `turnNextRoomBright`: Die zusätzliche Schleife `for(int i = 0; i < rooms.length; i++)` nutzt `i` gar nicht und führt dazu, dass du Aktionen unnötig oft wiederholst (dadurch wird die Logik “erster Raum” komplett verfälscht).\n- `saveEnergy`: Du schaltest/konfigurierst `minLamp` bereits innerhalb der Suche-Schleife; dadurch werden je nach Iteration Lampen zu früh ein-/ausgeschaltet und das Ergebnis ist nicht zuverlässig “genau die mit kleinstem Verbrauch bleibt an, alle anderen aus”.\n- `findBedrooms`: Du initialisierst `bedrooms` **in jeder** Iteration neu als leeres Array und gibst bereits **innerhalb der Room-Schleife** zurück → dadurch bekommst du höchstens ein Ergebnis aus dem ersten Raum bzw. meistens ein leeres Array.\n- `findBedrooms`: Wenn kein Bedroom im ersten Durchlauf gefunden wird, gibst du am Ende `rooms` zurück; das widerspricht der Anforderung (es sollen nur Bedrooms im Rückgabe-Array sein, nicht alle Räume).\n- `nightMode`: Nicht implementiert, obwohl in der Aufgabe verlangt (und es soll explizit `findHallway` und `findBedrooms` verwenden).\n\n### Suggestion\n- `turnNextRoomBright`: Überlege dir, wie du **zuerst** pro Raum prüfen kannst, ob *alle* Lampen `on` **und** `brightness == 1.0` sind, und **nur beim ersten Raum**, bei dem das nicht stimmt, dann alle Lampen dort korrigierst. Du brauchst dafür typischerweise eine “Status”-Variable pro Raum (z.B. “roomIsAlreadyBright”).\n- `turnNextRoomBright`: Achte darauf, dass du die Räume **nacheinander** abarbeitest und nach dem ersten passenden Raum **keine weiteren Räume mehr veränderst** (ohne `break` geht das z.B. über eine bool-Variable, die merkt, ob du schon “fertig” bist).\n- `saveEnergy`: Trenne die Aufgabe in zwei Phasen: (1) kleinste Lampe in diesem Raum finden, (2) danach in einer zweiten Runde alle Lampen passend schalten (min an mit 0.8, alle anderen aus).\n- `findBedrooms`: Lege das Ergebnis-Array **einmal** vor der Schleife an (maximal `rooms.length`) und fülle es mit einem separaten Index, den du bei jedem gefundenen Bedroom erhöhst. Gib erst **nach** der Schleife zurück.\n- `nightMode`: Vorgehen: erst alles ausschalten (oder konsequent “nicht ausgewählte” Lampen ausschalten), dann in Hallway + jedem Bedroom genau **eine** Lampe auswählen und auf `on` + `brightness 0.3` setzen. Nutze dazu die Arrays aus `findHallway()` und `findBedrooms()`; bei `findBedrooms()` musst du die `null`-Einträge berücksichtigen.\n\n### Code Style\n- In `randomize()` erstellst du innerhalb der Lampen-Schleife jedes Mal ein neues `Random`-Objekt (`Random r = new Random();`); besser ein einziges `Random` wiederverwenden.\n- Viele `if(room.getLamps() != null)` Checks sind vermutlich unnötig, da laut Vorlage Räume mit Lampenarrays erstellt werden; das macht den Code länger und unübersichtlicher.\n- `findBedrooms()` erzeugt neue `Room`-Objekte (`new Room(...)`), obwohl du einfach die vorhandenen `Room`-Referenzen sammeln kannst; das ist zusätzlicher Ballast und erschwert das Verständnis.\n- Imports: `Random` und `Objects` werden zwar genutzt, aber die Struktur könnte insgesamt klarer werden, wenn du doppelte Logik (z.B. “alle Lampen ausschalten”) als kleine Hilfsmethode kapselst.\n",
"status" : "SUCCESS"
}
}