{
"llm" : {
"feedback" : "# Exercise: textanalysis\n\n### Correctness\n- In der Zusatzfunktion interpretierst du `topWordK(42)` als “Wörter, die **genau 42-mal** vorkommen”. In der Aufgabenstellung bedeutet `topWordK(int k)` aber “das **k-häufigste** Wort” (also Rang 42 in der Häufigkeitsliste) bzw. alternativ “die **k häufigsten** Wörter”.\n- Die Zusatzfunktion `topWordK` ist nicht `public` und hat damit nicht die geforderte Signatur aus der Aufgabenbeschreibung (`String topWordK(int k)`), falls diese Variante umgesetzt werden soll.\n- Dein `TextAnalyzer` verwendet `topWordK(42)` und gibt “Words that appear 42 times” aus – das passt nicht zur geforderten Bedeutung von `topWordK(k)` als *k-häufigstes* Wort bzw. *Top-k-Liste*.\n\n### Suggestion\n- Überlege dir für `topWordK(k)`, ob `k` ein **Rang** (1.=häufigstes, 2.=zweithäufigstes, …) sein soll oder eine **Anzahl** (Top-k-Wörter). Deine aktuelle Implementierung nutzt `k` als **exakte Häufigkeit**; das ist eine andere Aufgabe.\n- Wenn du “k-häufigstes Wort” umsetzen willst: Du brauchst eine Möglichkeit, die Wörter nach ihrer gespeicherten Häufigkeit zu **vergleichen und zu ordnen** (oder schrittweise das k-te Maximum zu bestimmen), statt nur `== k` zu prüfen.\n- Wenn du “k häufigste Wörter” zurückgeben willst: Überlege, welche Datenstruktur/Strategie dir erlaubt, die **besten k** Kandidaten zu behalten, ohne alles falsch zu interpretieren als “kommt k-mal vor”.\n- Passe die Methode(n)-Signatur an die Variante an, die du implementieren willst (entweder genau `String topWordK(int k)` oder explizit ein Array/Collection für die Top-k-Wörter).\n\n### Code Style\n- Kapselung: `HashMap<String, Integer> words` sollte `private` sein, damit niemand von außen die interne Struktur manipuliert.\n- Benennung: Variablennamen wie `x`, `y` sind wenig aussagekräftig; sprechende Namen erleichtern das Verständnis (z.B. `maxCount`, `candidateWord`).\n- Annotation/Visibility: Wenn `topWordK` Teil der öffentlichen API sein soll, mach sie `public` und dokumentiere kurz, was `k` bedeutet (Rang vs. Anzahl vs. Häufigkeit).\n- In `TextAnalyzer` ist zusätzliche Ausgabe/Logik eingebaut, die nicht zur Grundaufgabe gehört; fürs Testen ok, aber für die Abgabe ggf. wieder entfernen oder zumindest so umbauen, dass sie zur tatsächlichen `topWordK`-Bedeutung passt.\n\n\n# Exercise: lotto\n\n### Correctness\n- In `Lottery.buyTicket` prüfst du nicht explizit, dass **genau 6 Zahlen übergeben** wurden (du verwendest nur `HashSet`-Size==6). Bei Eingaben mit z. B. 7 Zahlen (alle verschieden) würde dein Code aktuell trotzdem ein Ticket akzeptieren, obwohl „genau 6“ verlangt ist.\n- In `Lottery.draw` verwendest du feste Grenzen `r.nextInt(1, 43)` statt **`maxNumber`**. Damit funktioniert die Lotterie nicht korrekt für andere `maxNumber`-Werte als 42.\n- In `Lottery.draw` ist die Schleifenbedingung `while (wNumbers.size() != 6)` ungünstig: sie erfüllt zwar meistens ihren Zweck, aber die Anforderung ist „solange < 6, weiter ziehen“ (bei `!=` ist die Logik weniger robust, falls sich der Code mal ändert).\n\n### Suggestion\n- Überlege dir in `buyTicket`, welche zwei getrennten Bedingungen du brauchst: (1) **Länge des Arrays** muss 6 sein, und (2) **alle 6 müssen verschieden** sein. Dein `HashSet`-Check deckt nur (2) sicher ab.\n- Mach in `draw` die Obergrenze dynamisch: nutze bei der Zufallszahl-Generierung direkt `maxNumber`, sodass `new Lottery(10)` auch korrekt 1..10 zieht.\n- Passe die Zieh-Schleife so an, dass sie eindeutig „ziehe weiter, bis 6 verschiedene drin sind“ ausdrückt (das entspricht auch am klarsten der Aufgabenbeschreibung).\n\n### Code Style\n- `import ch.fhnw.prog1.exercise.lotto.LotteryApp;` in `Lottery.java` ist unbenutzt und kann weg.\n- In `Ticket` könnte `numbers` als `final` deklariert werden (du weist es nur im Konstruktor zu); das macht klarer, dass sich die Referenz nicht mehr ändern soll.\n- Du verwendest in `getPrize` die Literalwerte `5` und `20` statt `Lottery.BASE_PRIZE` und `Lottery.MULTIPLIER`. Das ist nicht falsch, aber weniger wartbar, falls sich die Konstanten ändern.\n",
"status" : "SUCCESS"
},
"unitTest" : {
"tests" : [ {
"name" : "buyTicketIds()",
"status" : "FAILED",
"message" : "Connection refused to host: 172.25.0.18; nested exception is: \n\tjava.net.ConnectException: Connection refused"
}, {
"name" : "buyTicketsIllegalNumbers()",
"status" : "PASSED",
"message" : null
}, {
"name" : "draw()",
"status" : "PASSED",
"message" : null
}, {
"name" : "drawNoDuplicates()",
"status" : "FAILED",
"message" : "expected: <true> but was: <false>"
}, {
"name" : "drawRandom()",
"status" : "FAILED",
"message" : "expected: <true> but was: <false>"
}, {
"name" : "drawAlreadyDrawn()",
"status" : "FAILED",
"message" : "Unexpected exception type thrown, expected: <java.lang.IllegalStateException> but was: <java.lang.reflect.UndeclaredThrowableException>"
}, {
"name" : "getWinningNumbersNotDrawnYet()",
"status" : "FAILED",
"message" : "Unexpected exception type thrown, expected: <java.lang.IllegalStateException> but was: <java.lang.reflect.UndeclaredThrowableException>"
}, {
"name" : "buyTicketAlreadyDrawn()",
"status" : "FAILED",
"message" : null
} ]
}
}