Skip to content

Instantly share code, notes, and snippets.

@qxf2
Last active May 4, 2020 10:57
Show Gist options
  • Save qxf2/7cd17fa5c28a1650d45c7ad2d69c2282 to your computer and use it in GitHub Desktop.
Save qxf2/7cd17fa5c28a1650d45c7ad2d69c2282 to your computer and use it in GitHub Desktop.
This script is an example of how to pick groups of 'r' people randomly from within a larger sample of N people such that no single person appears in two groups.
"""
This script is an example of how to pick groups of 'r' people randomly from within a larger sample of N people such that no single person appears in two groups.
I find this script useful when I have to divide my employees into groups randomly
"""
import argparse
import itertools
import random
#Note: Listing employees just to keep the example short
#You would (ideally) get a list of employees from some central datastore
#UPDATE EMPLOYEES TO SUIT YOUR CONTEXT
EMPLOYEES = ['Wilhelm', 'Emmanuel', 'Jose', 'Alexander', 'Max', 'Mikhail', 'Vassily', 'Tal', 'Tigran', 'Boris', 'Bobby', 'Anatoly', 'Gary', 'Vladimir', 'Anand', 'Magnus']
def check_no_overlap(my_tuple, reference_list):
"""
Verify if at least one member of a tuple overlpas with the members in a list of tuples
:return result_flag: boolean
"""
result_flag = True
for reference_tuple in reference_list:
result_flag &= set(my_tuple).isdisjoint(set(reference_tuple))
if result_flag is False:
break
return result_flag
def get_groups(group_size):
"""
Return groups of size group_size
:return groups: list of tuples
"""
unique_groups = []
expected_num_groups = int(len(EMPLOYEES)/group_size)
#We shuffle the combinations to keep the order fresh everytime
random.shuffle(EMPLOYEES)
if group_size >= len(EMPLOYEES):
unique_groups.append(tuple(EMPLOYEES))
else:
#all_combos is a list of all group_size combinations
all_combos = list(itertools.combinations(EMPLOYEES, group_size))
#Our next step is to make the groups disjoint
#'disjoint' = One employee cannot appear in two groups
for combo in all_combos:
if check_no_overlap(combo, unique_groups):
unique_groups.append(combo)
#A small optimization is to stop checking combos once we reach the expected number of groups
if len(unique_groups) == expected_num_groups:
break
return unique_groups
#----START OF SCRIPT
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--size', dest = 'size', type = int, default = 2, help = 'Size of the group you want')
args = parser.parse_args()
if args.size < 1:
parser.error(f'Invalid argument --size {args.size}. Group size should be an positive integer.')
groups = get_groups(args.size)
if len(groups):
print('Groups chosen are:')
for i, group in enumerate(groups):
print(f'{i}. {group}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment