@Stefsn: ich verstehe nicht, warum Du numpy überhaupt verwendest, weil Du nichts davon wirklich brauchst.
Unabhängig davon sollte `assignments` vom Typ `int` sein, damit das math.ceil überflüssig wird.
In `reset_probability` sind 100% der Strichpunkte überflüssig. Im Rest des Programms benutzt Du doch auch keine. Um die Bedingung bei if-Abfragen gehören keine Klammern. Über einen Index zu iterieren ist ein Anti-Pattern, entweder benutzt Du kein numpy sondern erzeugst Listen:
Code: Alles auswählen
def reset_probability(participants, amount_no_couples):
"""
input:
participants --> All participants
amount_no_couples --> amount of empty places (no partner)
output:
probability --> probability of being drawn
"""
probability = 1 / (len(participants) - amount_no_couples)
return [
0 if participant == "no_couple" else probability
for participant in participants
]
oder Du benutzt `numpy`:
Code: Alles auswählen
def reset_probability(participants, amount_no_couples):
"""
input:
participants --> All participants
amount_no_couples --> amount of empty places (no partner)
output:
probability --> probability of being drawn
"""
return (np.array(participants) == "no_couple") * (1 / (len(participants) - amount_no_couples))
In "main" wird probability definiert, nochmal mit 0 gefüllt, dann aber nie benutzt. Die anderen Variablen (bei Dir "Definitionen" genannt) sollten erst dann initialisiert werden, wenn sie gebraucht werden. Dann merk man auch, dass `count` nie gebraucht wird. `probability` wird auch einmal unnötigerweise berechnet, `assignments` unnötigerweise mit -1 gefüllt. Zum Zählen gibt es count.
Wenn Variablen an der richtigen Stelle initialisiert werden, merkt man, dass kaum etwas außerhalb der großen whd-for-Schleife gebraucht wird, und man damit die Schleife viel einfacher in Funktionen aufteilen kann, weil die viel zu lang ist.
Auch bei while-Bedingungen sind Klammern überflüssig. Wenn man einen Dummy-Wert braucht, damit eine while-Schleife losläuft, dann nimmt man eine while-True-Schleife, die mit passender Bedingung per break verlassen wird.
Wenn man tiefer hinein schaut, wird das Chaos noch deutlicher. Du reinitalisierst `count`, `assignments` und `probability` immer, wenn `lottery_done` auf True gesetzt wird, statt am anfang der while-Schleife, wo es hingehört. Damit wandern diese Variablen nocheinmal eine Ebene tiefer, was die Aufteilung in Funktionen nocheinmal vereinfacht.
Bei der dritten for-Schleife innerhalb der while-Schleife verstehe ich nicht, was in dem Fall passiert, wenn Du in der vorgehenden for-Schleife schon assignments resettet hast? Ich hoffe mal, dass Du den Fall gar nicht so behandeln willst, zumal alles, was in dieser Schleife passiert, dann eh unnötig ist, weil es überschrieben wird.
Warum wird weiter gemacht, solange lottery_done True ist? Der Leser würde das Gegenteil erwarten, dass weiter gemacht wird, solange etwas NICHT fertig ist.
Ich frage mich gerade, woher `pruefung` kommt, das heißt aber weiter oben wahrscheinlich `checks´.
Umwandlung in Prozent macht man mit Array-Operationen statt mit for-Schleifen.
Ein Zwischenstand könnte so aussehen (ungetestet):
Code: Alles auswählen
import numpy as np
import math
import Dice_Beispiel
def reset_probability(participants, amount_no_couples):
"""
input:
participants --> All participants
amount_no_couples --> amount of empty places (no partner)
output:
probability --> probability of being drawn
"""
return (np.array(participants) != "no_couple") * (1 / (len(participants) - amount_no_couples))
def generate_assignments(faces, participants, amount_no_couples):
while True:
probability = reset_probability(participants, amount_no_couples)
# Lose ziehen
assignments = []
count = 0
for participant in participants:
if participant != "no_couple":
val = weighted_sections(faces, probability)
count += 1
assignments.append(math.ceil(val))
probability[val] = 0
probability[probability != 0] = 1 / (len(participants) - amount_no_couples - count)
# Check if someone has drawn themselves
if any(faces==assignments):
# Check if couples draw each other
lottery_done == True
diff = faces - assignments
for participant1, participant2, diffm1, diff1 in zip(participants[::2], participants[1::2], diff[::2], diff[1::2]):
if participant1 != "no_couple" and participant2 != "no_couple":
if diff1 == 1 or diffm1 == -1:
#print("couples draw each other")
lottery_done = False
break
if lottery_done:
break
return assignments
def main():
participants = ["Lukas","no_couple","Stefan","Michelle","Paul","Gera"];
amount_no_couples = len(participants) - participants.count("no_couple")
faces = np.arange(0, len(participants)) # For checking draw couples
pruefung = np.zeros((len(participants),len(participants))) # Chefcl-Array to check distribution of being drawn
wdhs = 10**0 # For testing the distribution of being drawn how often
for _ in range(wdhs):
assignments = generate_assignments(faces, participants, amount_no_couples)
for element, assignment in zip(pruefung, assignments):
if assignment != -1:
element[assignment] += 1
# Umwandlung in Prozent
pruefung = np.ceil(pruefung / wdhs * 100)
print("****** lottery_done ******")
for participant, assignment in zip(participants, assignments):
if assignment != -1:
print(participant, "zieht", participants[assignment])
if __name__ == "__main__":
main()