{
"llm" : {
"feedback" : "# Exercise: todo\n\n### Correctness\n- Die drei geforderten Methoden `listTasks(boolean all)`, `addTask(String description)` und `markTaskDone(int id)` sind noch nicht implementiert, dadurch kann die App keine Tasks speichern, ausgeben oder als erledigt markieren.\n- Es fehlt das geforderte `Task`-Modell (Klasse `Task` mit mindestens ID, Beschreibung, done-Status und `toString()`), daher kann `IO.println(task)` wie verlangt nicht funktionieren.\n- Es fehlt das geforderte Array für `Task`-Objekte in `ToDoApp`, damit gibt es keinen Speicher für bis zu mehreren Tasks und keine Grundlage für die ID=Index-Logik.\n\n### Suggestion\n- Lege zuerst eine `Task`-Klasse an, die die Informationen enthält, die in der Ausgabe vorkommen (ID/Index, Beschreibung, erledigt ja/nein) und implementiere `toString()` so, dass die Konsolenausgabe pro Task passt.\n- Erstelle dann in `ToDoApp` ein Array für `Task`-Objekte und eine Variable, mit der du verfolgen kannst, wie viele Plätze bereits belegt sind bzw. wo der nächste freie Platz ist (oder alternativ: suche jeweils den ersten `null`-Eintrag).\n- Für `addTask`: Bestimme den ersten freien Index im Array (das ist die Task-ID), erzeuge ein neues `Task`-Objekt mit dieser ID und speichere es genau an diesem Index.\n- Für `markTaskDone`: Prüfe zuerst, ob die ID überhaupt auf einen existierenden Task zeigt (Index im Array und an der Stelle nicht `null`), sonst genau die geforderte Meldung ausgeben; falls vorhanden, setze den done-Status des Tasks.\n- Für `listTasks`: Iteriere über die gespeicherten Tasks und gib je nach Parameter `all` entweder alle oder nur die nicht erledigten aus; merke dir, ob du mindestens einen Task ausgegeben hast, um sonst `\"(No tasks)\"` auszugeben.\n\n### Code Style\n- In der Abgabe steht aktuell nur das vorgegebene Grundgerüst mit `// TODO`; ergänze die fehlenden Teile (Task-Klasse, Task-Array/Felder, Methodenimplementierungen), sonst ist der Code unvollständig und nicht testbar.\n\n\n# Exercise: energymeter\n\n### Correctness\n- `percentFull()` liefert bei `level == 0` und `capacity > 0` den Wert `0` (wegen `return level;`) – gefordert ist aber ein Prozentwert (also `0%`), nicht einfach der rohe Level-Wert (auch wenn’s hier zufällig 0 ist, ist die Logik inkonsistent mit dem Rest).\n- `percentFull()` berechnet bei `capacity == 0` und `level > 0` `100 / (capacity / level)` und verursacht damit eine Division durch 0 (Infinity/NaN statt 100).\n- In `percentFull()` ist der Sonderfall, der abgefangen werden muss, an die falsche Variable gekoppelt: Entscheidend ist `capacity == 0`, nicht ob `level == 0`.\n\n### Suggestion\n- Überlege dir bei `percentFull()`: Welche Variable steht im Nenner der Prozentformel, und wann wird dieser Nenner problematisch? Baue die Sonderfall-Behandlung genau darauf auf.\n- Formuliere die Prozent-Berechnung so, dass sie für alle Kombinationen aus `capacity` und `level` funktioniert (insbesondere wenn `capacity == 0`), ohne dass eine Division durch 0 passieren kann.\n- Prüfe, ob du in `percentFull()` wirklich unterschiedliche Wege für `level == 0` brauchst, oder ob ein klarer Sonderfall + eine einheitliche Formel reicht.\n\n### Code Style\n- Methoden-/Parameternamen sind uneinheitlich bzw. haben Tippfehler (`energie`, `durance`) und kollidieren semantisch mit Attributnamen (`consume(double capacity, ...)` heißt wie das Feld `capacity`) – das macht den Code schwerer lesbar.\n- Die Fehlermeldungen in Exceptions sind uneinheitlich (Deutsch/Englisch, “positive” obwohl `0` erlaubt ist, etc.); in vielen Aufgaben reichen auch Exceptions ohne Message.\n- Die Attribute sind `public`; üblich wäre hier, sie zu kapseln (z. B. `private`) und über Methoden zu arbeiten, damit der Zustand nicht von außen beliebig verändert werden kann.\n\n\n# Exercise: pong\n\n### Correctness\n- In `Player` fehlt der geforderte Punktestand (und damit auch das Hochzählen), und in `PongGame` wird beim Verlassen links/rechts kein Punkt für den gegenüberliegenden Player vergeben.\n- Die Startgeschwindigkeit des Balls ist nicht zufällig, sondern immer `(4,4)` (auch nach dem Reset), obwohl eine zufällige Anfangsgeschwindigkeit verlangt ist.\n- Wenn der Ball oben/unten abprallt, wird nur `vy` invertiert, aber die Position nicht korrigiert; dadurch kann der Ball je nach Schrittweite kurz “in” der Wand stecken und in aufeinanderfolgenden Frames mehrfach flippen.\n- Beim Verlassen des Spielfelds soll der Ball neu in der Mitte starten *und* es soll ein Punkt vergeben werden; aktuell wird zwar zurückgesetzt, aber ohne Punkte und ohne “gegenüberliegenden Player” zu berücksichtigen.\n- Die Erweiterung auf mehrere Bälle (Array mit max. Anzahl, periodisches Hinzufügen, Entfernen beim Verlassen) ist nicht umgesetzt.\n\n### Suggestion\n- Ergänze im `Player`-Objekt ein Feld für den Score und überlege dir eine kleine Methode, um ihn zu erhöhen; dann entscheide in `PongGame` anhand der Seite, welche Spieler:in den Punkt bekommt.\n- Für die zufällige Startgeschwindigkeit: denk an eine zufällige Richtung (Vorzeichen) und eine zufällige (sinnvolle) Betragsspanne, damit der Ball nicht immer gleich startet.\n- Beim Wand-Bounce oben/unten: setze nach dem Invertieren von `vy` die `y`-Position so, dass der Ball genau wieder innerhalb des Spielfelds liegt (z.B. auf `radius` bzw. `HEIGHT - radius`), damit es nicht zum “Dauer-Flippen” kommt.\n- Beim Reset links/rechts: prüfe, ob du die Bedingung mit `ball.x ± radius` formulieren willst (statt nur `ball.x`), damit “Berühren/Verlassen” konsistent zur Kollisionslogik ist.\n- Für mehrere Bälle: überlege eine Invariante wie „alle aktiven Bälle liegen in den ersten `n` Feldern des Arrays“, dann kannst du beim Entfernen effizient den letzten aktiven Ball nach vorne tauschen und `n` reduzieren; ein Countdown-Timer (Frames) hilft fürs periodische Hinzufügen.\n\n### Code Style\n- Viele Felder in `Ball` und `Player` sind `public`; kapsle Daten eher und biete gezielte Methoden an (z.B. `move`, `bounce`, `addPoint`), damit nicht überall direkt an Zuständen “herumgeschrieben” wird.\n- Magische Zahlen wie `20`, `150`, `4`, `5`, `30` sind verstreut; nutze Konstanten (z.B. Paddle-Abstand, Paddle-Länge, Ball-Radius, Start-Speed), dann wird das Tuning einfacher.\n- In `PongGame` wird direkt auf `p1.y`/`p2.y` zugegriffen, um zu clampen; sauberer ist es, die Begrenzung in die `Player`-Bewegungsmethoden zu integrieren, damit die Klasse selbst ihre Invarianten einhält.\n\n\n# Exercise: stepstats\n\n### Correctness\n- `StepStatistics` ist nicht objektorientiert umgeschrieben: Es gibt keinen Konstruktor `StepStatistics(int[] steps, int goal)` und keine Attribute (`successDays`, `averageSteps/avgSteps`, `minSteps`, `maxSteps`), auf die man nachher direkt zugreifen kann.\n- Die geforderte Verwendung `new StepStatistics(steps, goal)` funktioniert mit deiner aktuellen Implementierung nicht, weil du weiterhin nur die statische Methode `computeStatistics(...)` anbietest.\n- `StepTracker` wurde nicht angepasst: Der Client-Code verwendet weiterhin `StepStatistics.computeStatistics(...)` und greift auf ein `double[]` zu, statt auf Objekt-Attribute.\n\n### Suggestion\n- Überlege dir, welche Werte bisher in deinem `double[]` stecken, und mache daraus Felder der Klasse (z. B. `int`/`double` Attribute), die nach dem Konstruktor-Aufruf befüllt sind.\n- Verschiebe die komplette Schleifen-Logik aus `computeStatistics(...)` in den Konstruktor, sodass beim Erzeugen des Objekts alles berechnet wird.\n- Passe dann `StepTracker` so an, dass du statt des Arrays ein `StepStatistics`-Objekt erzeugst und beim Ausgeben direkt die Felder verwendest (keine Array-Indizes mehr).\n\n### Code Style\n- Das `double[]` als Rückgabewert ist wenig selbsterklärend (magische Indizes wie `stats[2]`); genau dafür ist in der Aufgabe die OO-Variante mit benannten Attributen gedacht.\n- In `StepTracker` fehlt in deinem Attempt sichtbar das `package`-Statement und auch `Scanner` wird verwendet ohne passenden Import (falls das nicht durch die Vorlage “magisch” vorhanden ist).\n",
"status" : "SUCCESS"
}
}