Update draw function to take n years of history in account
This commit is contained in:
parent
0d9f5264d4
commit
598bae34ba
66
src/draw.py
66
src/draw.py
@ -1,41 +1,51 @@
|
|||||||
from random import choice
|
from random import choice
|
||||||
|
|
||||||
def draw_names(previous_draw, draws_per_person):
|
def draw_names(current_participants, history_data, draws_per_person, max_attempts=5):
|
||||||
"""
|
"""
|
||||||
Perform the Secret Santa draw considering past draws.
|
Perform the Secret Santa draw considering past years' draws.
|
||||||
:param previous_draw: Last year's draw data (list of participants and recipients).
|
:param current_participants: This year's participant list.
|
||||||
|
:param history_data: Historical draw data to avoid repeats.
|
||||||
:param draws_per_person: Number of people each participant should give gifts to.
|
:param draws_per_person: Number of people each participant should give gifts to.
|
||||||
|
:param max_attempts: Maximum number of retry attempts before loosening exclusions. by default : 5.
|
||||||
:return: The new draw results.
|
:return: The new draw results.
|
||||||
"""
|
"""
|
||||||
participants = [a[0] for a in previous_draw] # Get participant names
|
participants = [p[0] for p in current_participants] # Get participant names
|
||||||
already_drawn = [] # Track who has been drawn
|
already_drawn = [] # Track who has been drawn
|
||||||
new_draw = [] # Store new draw results
|
new_draw = [] # Store new draw results
|
||||||
|
|
||||||
for i in range(len(participants)):
|
for attempt in range(max_attempts):
|
||||||
giver = previous_draw[i][0]
|
new_draw.clear()
|
||||||
email = previous_draw[i][1]
|
already_drawn.clear()
|
||||||
print(email)
|
success = True # Track if draw is successful in this attempt
|
||||||
last_year_r1 = previous_draw[i][2]
|
|
||||||
last_year_r2 = previous_draw[i][3]
|
|
||||||
|
|
||||||
available_participants = participants.copy()
|
for i, giver in enumerate(participants):
|
||||||
try:
|
email = current_participants[i][1]
|
||||||
available_participants.remove(giver)
|
# Collect previous recipients to avoid drawing the same person again
|
||||||
available_participants.remove(last_year_r1)
|
previous_recipients = {recipient for record in history_data if record[0] == giver for recipient in record[2:]}
|
||||||
available_participants.remove(last_year_r2)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
new_recipients = []
|
# Create a set of available participants excluding the giver and previous recipients
|
||||||
while len(new_recipients) < draws_per_person:
|
available_participants = set(participants) - {giver} - previous_recipients
|
||||||
selected = choice(available_participants)
|
new_recipients = []
|
||||||
if already_drawn.count(selected) >= draws_per_person:
|
|
||||||
available_participants.remove(selected)
|
|
||||||
else:
|
|
||||||
new_recipients.append(selected)
|
|
||||||
already_drawn.append(selected)
|
|
||||||
available_participants.remove(selected)
|
|
||||||
|
|
||||||
new_draw.append([giver, email] + new_recipients)
|
# Ensure there are enough available participants for the draw
|
||||||
|
if len(available_participants) < draws_per_person:
|
||||||
|
success = False
|
||||||
|
break
|
||||||
|
|
||||||
return new_draw
|
# Select recipients for the current giver
|
||||||
|
while len(new_recipients) < draws_per_person:
|
||||||
|
selected = choice(list(available_participants))
|
||||||
|
if already_drawn.count(selected) < draws_per_person:
|
||||||
|
new_recipients.append(selected)
|
||||||
|
already_drawn.append(selected)
|
||||||
|
available_participants.discard(selected)
|
||||||
|
|
||||||
|
new_draw.append([giver, email] + new_recipients)
|
||||||
|
|
||||||
|
# If the draw was successful, break out of attempts
|
||||||
|
if success:
|
||||||
|
return new_draw
|
||||||
|
print(f"Attempt {attempt + 1} failed, retrying...")
|
||||||
|
|
||||||
|
# If all attempts fail, raise an error
|
||||||
|
raise ValueError("Unable to complete a valid draw after maximum attempts.")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user