AutoFeedback API

Result e66f556b-a795-4502-9917-498a86728694

{
  "llm" : {
    "feedback" : "# Exercise: textanalysis\n\n### Correctness\n- Deine interne Datenstruktur sammelt nicht direkt die „relevante Information“ (Häufigkeiten), sondern speichert nur alle Wörter in einer Liste und berechnet die Häufigkeiten erst in `topWord()`. Damit erfüllst du die Anforderung „geeignete interne Datenstruktur … um die relevante Information zu sammeln“ nur teilweise bzw. nicht im Sinne der Aufgabe (Zählen beim Hinzufügen).\n- Durch das aktuelle Vorgehen hängt `topWord()` davon ab, dass *alle* Wörter jemals in `words` gespeichert wurden; bei „grösserem Text“ ist das konzeptionell nicht das, was die Aufgabe mit „intern relevante Information sammeln“ nahelegt (sie erwartet typischerweise, dass `add` die Zählstruktur pflegt).\n\n### Suggestion\n- Überlege, welche Information du wirklich brauchst, um das häufigste Wort zu bestimmen (du brauchst nicht die komplette Wortliste, sondern nur Zähler pro Wort). Baue deine Datenstruktur so, dass `add(word)` diese Information sofort aktualisiert.\n- Denke daran, dass `topWord()` dann nur noch über die bereits gepflegten Häufigkeiten iterieren muss, statt jedes Mal alles neu auszuzählen.\n\n### Code Style\n- Unnötiger Import: `import java.security.Key;` wird nicht verwendet.\n- `import java.util.*;` ist sehr breit; in der Regel ist es besser, nur die tatsächlich verwendeten Klassen zu importieren.\n- `topWord()` erzeugt bei jedem Aufruf eine neue `HashMap` und zählt alles neu; auch wenn das funktional ist, ist das für Performance/Lesbarkeit ungünstig im Vergleich zu einer dauerhaft gepflegten Struktur als Feld.\n\n\n# Exercise: lotto\n\n### Correctness\n- `buyTicket`: Du prüfst nicht, ob nach der Ziehung noch Lose gekauft werden (muss dann `IllegalStateException` werfen).\n- `buyTicket`: Die Bereichsprüfung ist logisch falsch: `if(numbers[i] < 1 && numbers[i] > maxNumber)` kann nie true sein; dadurch werden ungültige Zahlen nicht korrekt erkannt (und du wirfst/returnst auch nicht wie gefordert).\n- `buyTicket`: Ticket-IDs starten bei dir bei 0 (`id++`), gefordert ist Start bei 1.\n- `buyTicket`: Du erhöhst `soldTickets` nie, obwohl `getSoldTickets()` das widerspiegeln soll und die ID-Vergabe daran gekoppelt sein soll.\n- `draw`: Du verhinderst nicht, dass `draw()` nach einer bereits erfolgten Ziehung nochmals aufgerufen wird (muss dann `IllegalStateException` werfen).\n- `draw`: Du erzeugst Zahlen im falschen Bereich (`rand.nextInt((maxNumber)+1)` liefert auch 0); erlaubt sind nur 1..maxNumber.\n- `draw`: Wenn eine gezogene Zahl bereits vorhanden ist, machst du `return;` und brichst die Ziehung sofort ab → damit werden oft weniger als 6 Gewinnzahlen gespeichert.\n- `getWinningNumbers`: Du koppelst die Erlaubnis an dein eigenes `state`-Flag statt an den eigentlichen Zustand `winningNumbers != null`; dadurch kann es inkonsistent werden (z.B. wenn `winningNumbers` gesetzt ist, `state` aber noch nicht).\n- `Ticket.getNumbers`: Gibt immer `null` zurück (und hat eine Endlosschleife ohne Effekt) → muss die 6 Zahlen (als Kopie) liefern.\n- `Ticket.getCorrectNumbers`: Ruft `lottery.draw()` auf; das ist fachlich falsch, weil `getCorrectNumbers()` nur nach einer Ziehung arbeiten darf und keine Ziehung auslösen soll.\n- `Ticket.getCorrectNumbers`: Liefert aktuell einfach alle Gewinnzahlen zurück (als ArrayList aus `getWinningNumbers()`), nicht die Schnittmenge aus Ticket-Zahlen und Gewinnzahlen.\n- `Ticket.getCorrectNumbers` / `getPrize`: Die geforderte `IllegalStateException` vor der Ziehung wird so nicht korrekt umgesetzt (aktuell erzwingst du sogar eine Ziehung).\n- `Ticket.getPrize`: Immer 0 → Preislogik fehlt komplett (0 richtig => 0, 1 richtig => 5, jede weitere *20).\n\n### Suggestion\n- Für den “Zustand” der Lotterie: Überlege, welche Variable den Zustand bereits ausdrückt (vor/nach Ziehung) und nutze diese konsistent in `buyTicket`, `draw`, `getWinningNumbers`.\n- Bei der Bereichsprüfung in `buyTicket`: Formuliere die Bedingung so, dass sie “außerhalb des erlaubten Bereichs” erkennt, und wirf dann wie gefordert eine Exception (statt `null` zu returnen).\n- Für unterschiedliche Ticket-Nummern: Nutze einen einzigen Zähler, der bei 1 startet, und erhöhe ihn genau dann, wenn ein Ticket erfolgreich verkauft wurde.\n- Für `draw()`: Ziehe so lange weiter, bis du wirklich 6 *verschiedene* Zahlen hast; bei einer Doppelung solltest du nicht die Methode beenden, sondern einfach erneut ziehen.\n- Für den Zufallsbereich: Prüfe, wie `nextInt(n)` funktioniert, und wie du daraus Werte von 1..maxNumber erzeugst.\n- Für `Ticket.getNumbers()`: Gib eine Kopie der gespeicherten Zahlen zurück; vermeide `null`, weil `toString()` und die App das direkt benutzen.\n- Für `getCorrectNumbers()`: Denke an “Schnittmenge”: Welche Gewinnzahlen kommen auch auf deinem Ticket vor? Du kannst dafür mit Collections arbeiten, ohne die internen Daten zu verändern.\n- Für die “nur nach Ziehung”-Regel in `Ticket`: Frag den Ziehungszustand über die Lottery ab (oder rufe eine Methode auf, die dann automatisch `IllegalStateException` wirft), statt selbst zu ziehen.\n- Für `getPrize()`: Starte bei 0 richtigen Zahlen mit 0; bei mindestens 1 richtiger Zahl starte mit dem Basispreis und multipliziere dann pro weiterer richtiger Zahl.\n\n### Code Style\n- In `draw()` und `getCorrectNumbers()` sind viele `System.out.println` Debug-Ausgaben; die sollten raus, damit die Klassen nur ihre Aufgabe erfüllen.\n- `Lottery` hat mehrere unnötige Imports (`Arrays`) und redundante Zustandsvariable (`state`), was die Logik schwerer nachvollziehbar macht.\n- `Ticket.getNumbers()` enthält eine leere `while`-Schleife; solche Konstrukte verwirren und sollten entfernt werden.\n- `buyTicket` nutzt eine verschachtelte Doppelschleife zur Duplikatprüfung; mit einer passenden Collection (Set) wird das einfacher und besser lesbar.\n",
    "status" : "SUCCESS"
  },
  "unitTest" : {
    "tests" : [ {
      "name" : "buyTicketIds()",
      "status" : "FAILED",
      "message" : "expected: <1> but was: <0>"
    }, {
      "name" : "buyTicketsIllegalNumbers()",
      "status" : "FAILED",
      "message" : "Expected java.lang.Exception to be thrown, but nothing was thrown."
    }, {
      "name" : "draw()",
      "status" : "FAILED",
      "message" : "expected: <true> but was: <false>"
    }, {
      "name" : "drawNoDuplicates()",
      "status" : "FAILED",
      "message" : null
    }, {
      "name" : "drawRandom()",
      "status" : "FAILED",
      "message" : null
    }, {
      "name" : "drawAlreadyDrawn()",
      "status" : "FAILED",
      "message" : "Expected java.lang.Exception to be thrown, but nothing was thrown."
    }, {
      "name" : "getWinningNumbersNotDrawnYet()",
      "status" : "FAILED",
      "message" : null
    }, {
      "name" : "buyTicketAlreadyDrawn()",
      "status" : "FAILED",
      "message" : "Expected java.lang.Exception to be thrown, but nothing was thrown."
    } ]
  }
}