Python: warum Iterable/iter in diesem Craps Beispiel?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet

Das scheint mir recht anspruchsvoll nach drei Monaten. In dem kurzen Programm stecken einige Themen für Fortgeschrittene. Type hints, Iterable, Assertions, funktionale Programmierung mit Generatoren, List Comprehensions...

Craps ist ein beliebtes Beispiel für solche Programmieraufgaben. Das Spiel ist sehr einfach, aber 1) vom Zufall abhängig und 2) die Zahl der "Würfe" hängt von den Würfen davor ab. Es kann schon nach 2 Würfen vorbei sein oder theoretisch endlos weitergehen.

Warum also macht man die Zufallswürfe nicht direkt im craps() mit random.randint()? Naja, weil dann die ganze Funktion vom Zufall abhängt. Damit wird es unmöglich sie auf Korrektheit zu testen, man weiß auch gar nicht was drin passiert. Also ist es schon praktisch, wenn man Würfe von außen übergeben kann und dann prüfen, ob dafür das Richtige rauskommt ("some tests").

Zu deiner Frage:

Warum nicht einfach eine Liste von Zahlen in die Funktion ?

Ist doch so. Man kann ja eine Liste übergeben, wie du siehst. Aber nicht nur eine Liste, sondern alles was iterierbar ist (und Würfelzahlen hergibt). Wie gesagt, das Problem ist ja dass man (bei Zufallszahlen) vorher nicht weiß wieviele Zahlen gebraucht werden. Es könnten 2 oder 200000 sein.

Was heißt Iterable? In Python ist ein Iterable etwas, von dem ich einen Iterator bekomme (mit iter()). Ein Iterator ist wiederum etwas, das auf Anfrage einen nächsten Wert liefert. So ähnlich wie diese Automaten zum Nummernziehen, wo man sonst Schlange stehen müsste. Du drückst drauf und kriegst ein Stück Papier mit Nummer raus.

Listen sind Iterable, aber begrenzt (wenn man am Ende angelangt ist, gibt es keinen Wert mehr - das Nummernpapier ist aus!). Für den echten, zufälligen Würfel wird hier ein Generator verwendet. Das ist eine spezielle Art von Funktion, die einen Iterator liefert. In diesem Fall ist der unbegrenzt, für jeden Aufruf kommt eine Zahl raus, Zufallszahlen gibt es in beliebiger Menge.

Also ist die Lösung schon clever, weil der Aufrufer ganz einfach vorgeben kann, woher die Würfelzahlen kommen: aus echtem Zufall oder einer Liste von fixen Werten, oder vielleicht sogar anders (z.B. könnte man einen gezinkten Würfel simulieren).

Ach ja, noch ein Vorteil ist, dass der Generator die Zahlen auf Wunsch z.B. per print() ausgeben könnte. Du kannst damit also in jeder Runde nachvollziehen, welche Zufallszahlen generiert werden.