I have created a function in Python to generate a roster by selecting a pair of inspectors each for two teams (team A and B) each week for the whole year. The function accepts two lists, one list is optional. A pair cannot be formed exclusively from list2, the optional list. The count of each person in each team should be almost the same.
The function works except that there is little variety in the selection process. I want different pairs to be selected for the same team until all possible pairs are exhausted. I want each person to have a different partner each time he/she is selected for team A. For example, if Kay and Pat are selected in team A for week 4, Kay should have a different partner the next time Kay is selected in team A.
This is the code:
<code>import pandas as pd
def generate_roster(list1, list2=None):
# Ensure there are at least 4 people to form two pairs for Team A and Team B
raise ValueError("There should be at least four people to form two pairs for Team A and Team B.")
# Initialize dictionaries to keep track of when each person was last selected for Team A and Team B
last_selected_a = {person: -2 for person in people} # Start with -2 to allow immediate selection
last_selected_b = {person: -2 for person in people}
# Initialize dictionaries to count appearances in Team A and Team B
appearances_a = {person: 0 for person in people}
appearances_b = {person: 0 for person in people}
for week in range(1, 53): # 52 weeks in a year
while not valid_selection:
# Sort people by their appearances in Team A and Team B to prioritize those with fewer appearances
sorted_people_a = sorted(people, key=lambda p: (appearances_a[p], last_selected_a[p]))
sorted_people_b = sorted(people, key=lambda p: (appearances_b[p], last_selected_b[p]))
# Select two people for Team A ensuring no pair is formed exclusively from list2
for person in sorted_people_a:
if person not in selected_people and (person in list1 or any(p in list1 for p in selected_people)):
selected_people.append(person)
# Select two people for Team B ensuring no pair is formed exclusively from list2
for person in sorted_people_b:
if person not in selected_people and (person in list1 or any(p in list1 for p in selected_people[2:])):
selected_people.append(person)
team_a = selected_people[:2]
team_b = selected_people[2:]
# Check if this is the first week or if the same person is selected for the same team in successive weeks
if week == 1 or (not (set(team_a) & set(roster[-1]['Team A'].split(', ')) or set(team_b) & set(roster[-1]['Team B'].split(', ')))):
# Update the last selected week for each person
last_selected_a[person] = week
appearances_a[person] += 1
last_selected_b[person] = week
appearances_b[person] += 1
'Team A': ', '.join(team_a),
'Team B': ', '.join(team_b)
df_roster = pd.DataFrame(roster)
<code>import pandas as pd
import random
def generate_roster(list1, list2=None):
if list2:
people = list1 + list2
else:
people = list1
# Ensure there are at least 4 people to form two pairs for Team A and Team B
if len(people) < 4:
raise ValueError("There should be at least four people to form two pairs for Team A and Team B.")
# Initialize dictionaries to keep track of when each person was last selected for Team A and Team B
last_selected_a = {person: -2 for person in people} # Start with -2 to allow immediate selection
last_selected_b = {person: -2 for person in people}
# Initialize dictionaries to count appearances in Team A and Team B
appearances_a = {person: 0 for person in people}
appearances_b = {person: 0 for person in people}
roster = []
for week in range(1, 53): # 52 weeks in a year
valid_selection = False
while not valid_selection:
# Sort people by their appearances in Team A and Team B to prioritize those with fewer appearances
sorted_people_a = sorted(people, key=lambda p: (appearances_a[p], last_selected_a[p]))
sorted_people_b = sorted(people, key=lambda p: (appearances_b[p], last_selected_b[p]))
selected_people = []
# Select two people for Team A ensuring no pair is formed exclusively from list2
for _ in range(2):
for person in sorted_people_a:
if person not in selected_people and (person in list1 or any(p in list1 for p in selected_people)):
selected_people.append(person)
break
# Select two people for Team B ensuring no pair is formed exclusively from list2
for _ in range(2):
for person in sorted_people_b:
if person not in selected_people and (person in list1 or any(p in list1 for p in selected_people[2:])):
selected_people.append(person)
break
team_a = selected_people[:2]
team_b = selected_people[2:]
# Check if this is the first week or if the same person is selected for the same team in successive weeks
if week == 1 or (not (set(team_a) & set(roster[-1]['Team A'].split(', ')) or set(team_b) & set(roster[-1]['Team B'].split(', ')))):
valid_selection = True
# Update the last selected week for each person
for person in team_a:
last_selected_a[person] = week
appearances_a[person] += 1
for person in team_b:
last_selected_b[person] = week
appearances_b[person] += 1
roster.append({
'Week Number': week,
'Team A': ', '.join(team_a),
'Team B': ', '.join(team_b)
})
df_roster = pd.DataFrame(roster)
return df_roster
</code>
import pandas as pd
import random
def generate_roster(list1, list2=None):
if list2:
people = list1 + list2
else:
people = list1
# Ensure there are at least 4 people to form two pairs for Team A and Team B
if len(people) < 4:
raise ValueError("There should be at least four people to form two pairs for Team A and Team B.")
# Initialize dictionaries to keep track of when each person was last selected for Team A and Team B
last_selected_a = {person: -2 for person in people} # Start with -2 to allow immediate selection
last_selected_b = {person: -2 for person in people}
# Initialize dictionaries to count appearances in Team A and Team B
appearances_a = {person: 0 for person in people}
appearances_b = {person: 0 for person in people}
roster = []
for week in range(1, 53): # 52 weeks in a year
valid_selection = False
while not valid_selection:
# Sort people by their appearances in Team A and Team B to prioritize those with fewer appearances
sorted_people_a = sorted(people, key=lambda p: (appearances_a[p], last_selected_a[p]))
sorted_people_b = sorted(people, key=lambda p: (appearances_b[p], last_selected_b[p]))
selected_people = []
# Select two people for Team A ensuring no pair is formed exclusively from list2
for _ in range(2):
for person in sorted_people_a:
if person not in selected_people and (person in list1 or any(p in list1 for p in selected_people)):
selected_people.append(person)
break
# Select two people for Team B ensuring no pair is formed exclusively from list2
for _ in range(2):
for person in sorted_people_b:
if person not in selected_people and (person in list1 or any(p in list1 for p in selected_people[2:])):
selected_people.append(person)
break
team_a = selected_people[:2]
team_b = selected_people[2:]
# Check if this is the first week or if the same person is selected for the same team in successive weeks
if week == 1 or (not (set(team_a) & set(roster[-1]['Team A'].split(', ')) or set(team_b) & set(roster[-1]['Team B'].split(', ')))):
valid_selection = True
# Update the last selected week for each person
for person in team_a:
last_selected_a[person] = week
appearances_a[person] += 1
for person in team_b:
last_selected_b[person] = week
appearances_b[person] += 1
roster.append({
'Week Number': week,
'Team A': ', '.join(team_a),
'Team B': ', '.join(team_b)
})
df_roster = pd.DataFrame(roster)
return df_roster