AutoFeedback API

Result 005add94-4552-4a86-8a5d-5297cab55f9f

{
  "llm" : {
    "feedback" : "# Exercise: address\n\n### Correctness\n- `getCity()` wirft eine `IllegalArgumentException`, wenn `city` leer ist; Getter sollten gemäss Aufgabe nur Werte liefern, während die Validierung/Fehlerbehandlung im Konstruktor und in den Settern stattfinden soll.\n- `getCity()` prüft nur `isEmpty()`, aber nicht `city == null`; falls `city` jemals `null` wäre, würde hier eine `NullPointerException` statt der geforderten `IllegalArgumentException` entstehen.\n\n### Suggestion\n- Verschiebe die Validierung von `city` vollständig in Konstruktor und `setCity(...)` und lass den Getter einfach den gespeicherten Wert zurückgeben.\n- Wenn du irgendwo `isEmpty()` auf einem String nutzt, überlege immer zuerst, ob der String auch `null` sein könnte, und wie du dann die geforderte Exception-Art sicherstellst.\n\n### Code Style\n- Du hast die gleichen Validierungschecks mehrfach (Konstruktor + Setter). Überlege, ob du diese Prüfungen an einer Stelle zentralisieren kannst, um Duplikate zu vermeiden.\n- Die Fehlermeldung bei `zipCode` ist etwas irreführend („muss positiv sein“), obwohl du eigentlich „vierstellig“ prüfst; benenne Meldungen so, dass sie zur tatsächlichen Regel passen.\n- In `getStreet()` ist eine Leerzeile direkt nach der Methodensignatur; halte die Formatierung konsistent.\n\n\n# Exercise: timespan\n\n### Correctness\n- Im Konstruktor werden keine Preconditions für negative Eingaben durchgesetzt: `add(hours, minutes)` akzeptiert aktuell auch negative Werte, weil deine Negative-Prüfung `if (totalMinutes() < 0)` nur den *aktuellen* Zustand prüft (der am Anfang 0 ist), nicht die Parameter.\n- In `add(...)` setzt du die Invariante „Zeitspannen können nur verlängert werden“ nicht korrekt um: Du vergleichst `totalMinutes() >= this.minutes` (Minutenfeld) statt den neuen Gesamtwert mit dem alten Gesamtwert; damit kann die Zeitspanne trotzdem verkürzt werden.\n- Die Invariante `0 ≤ getMinutes ≤ 59` ist nicht in allen Fällen garantiert: Wenn `minutes` stark negativ wird, korrigiert `checkMinutes()` das nicht zuverlässig zurück in den gültigen Bereich.\n- `add(...)` kann eine Zeitspanne verkürzen (z.B. durch negative Parameter), obwohl das laut Aufgabe über Preconditions verhindert werden muss (IllegalArgumentException).\n\n### Suggestion\n- Prüfe im Konstruktor und in `add(...)` nicht den aktuellen `totalMinutes()`, sondern formuliere Preconditions anhand der *übergebenen Werte* bzw. anhand des *resultierenden* neuen Gesamtwerts (alter Gesamtwert vs. neuer Gesamtwert).\n- Für „nur verlängern“: Berechne gedanklich/konzeptionell den neuen Gesamtminutenwert aus aktuellem Zustand + Parametern und vergleiche ihn mit dem alten Gesamtminutenwert; wenn kleiner, Exception.\n- Sorge dafür, dass die Normalisierung der Minuten (Übertrag in Stunden) so gestaltet ist, dass danach garantiert `getMinutes()` immer im Bereich 0..59 liegt—insbesondere auch dann, wenn die Parameter ungültig sind (wobei die dann idealerweise schon vorher abgefangen werden).\n- Überlege, ob du `checkMinutes()` überhaupt für negative Minuten unterstützen willst: Laut Aufgabenstellung sollen negative Zeitspannen/Verkürzungen per Preconditions verhindert werden, dann brauchst du dort keine „Reparatur“ negativer Werte.\n\n### Code Style\n- `this.totalMinutes();` in `add(...)` hat keinen Effekt (Rückgabewert wird nicht verwendet) und wirkt wie „toter Code“.\n- Die Bedingung `if(totalMinutes() >=  this.minutes)` ist schwer verständlich (Vergleich Gesamtminuten vs. Minutenfeld); selbst wenn die Logik korrekt wäre, sollte die Vergleichsgröße klar benannt/strukturiert sein.\n- `checkMinutes()` mischt Korrektur für `>=60` und `<0`, wobei der `<0`-Teil unvollständig/unklar ist (ändert `minutes` nicht). Das macht die Methode schwer wartbar.\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)` findet nicht zuverlässig den *ersten* gemeinsamen Vorgesetzten: Du läufst mit `superior` (Kette von `other`) und `commonSuperior` (Kette von `this`) gleichzeitig nach oben, aber gemeinsame Vorgesetzte liegen oft auf unterschiedlichen “Höhen”; dadurch kannst du den gemeinsamen Knoten verpassen oder zu früh `null` liefern.\n- `findCommonSuperiorWith(other)` berücksichtigt den Fall “jede Person ist ihre eigene Vorgesetzte” nicht allgemein: Du startest bei `other.getBoss()` bzw. `this.getBoss()` und prüfst damit in vielen Fällen weder `other` noch `this` selbst als mögliche gemeinsame Vorgesetzte (außer beim Spezialfall `this == other`).\n- `findCommonSuperiorWith(other)` kann eine `NullPointerException` werfen: Wenn `commonSuperior` `null` wird, setzt du es auf `this`, und direkt danach rufst du später in der Schleife `commonSuperior = commonSuperior.getBoss()` auf; je nach Verlauf kann `commonSuperior` dabei wieder `null` werden, bevor die Schleife endet.\n\n### Suggestion\n- Überlege dir für `findCommonSuperiorWith`: “Gemeinsamer Vorgesetzter” bedeutet: Ein Knoten, der in *beiden* Boss-Ketten vorkommt. Eine robuste Strategie ist, zuerst die gesamte Boss-Kette der einen Person zu “merken” (z.B. als Menge/Liste), und dann die andere Kette von unten nach oben durchzugehen und den ersten Treffer zu nehmen.\n- Achte darauf, dass “Person ist Vorgesetzte von sich selbst” bedeutet: Deine Suche sollte bei `this` bzw. `other` selbst starten (nicht erst bei deren Boss), sonst verpasst du Fälle wie `sara.findCommonSuperiorWith(headOfSales)`.\n- Prüfe deine Schleifenbedingung/Schleifenfortschritte so, dass du niemals `getBoss()` auf `null` aufrufst; geh im Kopf ein paar Randfälle durch (CEO ohne Boss, eine Person direkt unter CEO, unterschiedliche Firmen → endet in `null`).\n\n### Code Style\n- In `findCommonSuperiorWith` mischst du Referenzvergleich (`==`) und `.equals(...)`. Da `Employee` kein `equals` überschreibt, ist `.equals` aktuell identisch zu `==`, aber das ist verwirrend; entscheide dich konsistent für eines (typisch: Identität per `==`).\n- Variablennamen wie `superior` und `commonSuperior` sind ok, aber in `findCommonSuperiorWith` ist `commonSuperior` tatsächlich einfach “aktueller Kandidat aus this-Kette”; ein präziserer Name würde die Logik lesbarer machen.\n- Wiederholte Aufrufe von `getBoss()` in enger Folge kann man oft durch klare “cursor”-Variablen strukturieren (z.B. `Employee cursor = ...; cursor = cursor.getBoss();`) um den Traversal besser nachvollziehbar zu machen.\n\n\n# Exercise: smarthome\n\n### Correctness\n- `turnNextRoomBright`: Du hellst aktuell potentiell mehrere/alle Räume auf, statt nur **den ersten** Raum zu finden, der nicht komplett “an und 1.0” ist, und **nur diesen einen** anzupassen; außerdem läuft bei dir eine innere Schleife über `rooms.length`, obwohl du schon in einem `for (Room room : rooms)` bist.\n- `saveEnergy`: Du schaltest/setzt die minimale Lampe bereits **während** du noch am Suchen bist; dadurch kann am Ende nicht garantiert sein, dass wirklich nur die Lampe mit dem kleinsten Verbrauch an bleibt und die anderen aus sind (Reihenfolge-/Zwischenzustand-Problem).\n- `findBedrooms`: Du erzeugst `bedrooms` innerhalb der Schleife immer wieder neu (damit “vergisst” du vorher gefundene Bedrooms) und du `return`st innerhalb der ersten Iteration direkt; dadurch bekommst du nicht alle Bedroom-Räume zurück. Außerdem gibst du am Ende im `return rooms;` u.U. einfach alle Räume zurück, was die Anforderung verletzt.\n- `nightMode`: Nicht implementiert, gehört aber zu den “restlichen Methoden”, die implementiert werden müssen.\n\n### Suggestion\n- `turnNextRoomBright`: Überlege dir eine Logik in zwei Schritten: (1) Prüfen, ob ein Raum “nicht komplett hell/an” ist (dafür brauchst du eine Variable/Flag pro Raum), (2) sobald du den **ersten** solchen Raum gefunden hast, genau diesen auf “alle Lampen an + brightness 1.0” setzen und danach keine weiteren Räume mehr verändern (ohne `break`/early return geht das typischerweise mit einer zusätzlichen Boolean-Variable, die ab dann “erledigt” markiert).\n- `saveEnergy`: Trenne “Minimum finden” und “Zustände setzen”: zuerst pro Raum die Lampe mit minimalem Verbrauch bestimmen (nur vergleichen, nichts schalten), danach in einem zweiten Durchlauf in diesem Raum genau diese Lampe einschalten/brightness setzen und alle anderen ausschalten.\n- `findBedrooms`: Lege das Ergebnis-Array **einmal** vor der Schleife an (maximal `rooms.length`) und fülle es beim Durchlaufen der `rooms` an der nächsten freien Position (Index mitzählen). Gib das Array erst **nach** der Schleife zurück.\n- `nightMode`: Nutze wirklich `findHallway()` und `findBedrooms()`: zuerst alles ausschalten, dann in Hallway und in jedem Bedroom genau **eine beliebige** Lampe einschalten und auf 0.3 setzen (z.B. “erste Lampe” als “beliebige” Wahl, aber ohne Annahmen über Anzahl Räume/Lampen).\n\n### Code Style\n- In `randomize` erzeugst du für jede Lampe ein neues `Random`-Objekt (`Random r = new Random();` im Lampen-Loop). Nimm stattdessen einen Generator und verwende ihn überall; das macht den Code klarer und vermeidet unnötige Objekte.\n- Mehrfach prüfst du `if (room.getLamps() != null)`: in der Vorlage ist sehr wahrscheinlich garantiert, dass `lamps` nicht `null` ist. Diese Checks machen den Code schwerer lesbar (und verstecken eher echte Fehler).\n- `findBedrooms`: Du erstellst neue `Room`-Objekte (`new Room(room.getName(), room.getLamps())`), obwohl du eigentlich bestehende Räume zurückgeben sollst. Das ist unnötig und verwirrend, weil du keine “Kopie” brauchst.\n- Teilweise inkonsistente Einrückung/Klammerung (z.B. `saveEnergy`) erschwert das Nachvollziehen der Blockstruktur; besser sauber formatieren, damit man die Schleifenebenen klar sieht.\n",
    "status" : "SUCCESS"
  }
}