I need some assistance in these functions. The function is that I have a list of employees and they are divided into 3 sections: manager, assist and emp.
Below is approach I created to randomly select n number of employees in list
list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
random.shuffle(list_sample)
total_num=4
temp_re_list=list_sample[:total_num]
The function I want is to randomly select employees from the list but have the ability to choose based on certain conditions if the list allows it. For example if I need 6 employees and from these 6 i need at least 2 managers along with 1 assist. If the list doesn't contain manager or assist then it will try to provide any emp as long as it gives me the same total emp. Just to be clear the list_sample will allows be greater or equal to total_num
list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
total_num=6
manager_num=1
assist_num=2
emp_num=3
# another example of the list
list_sample=["Assist 1","Assist 2","Assist 4","Emp 2","Emp 3","Emp 5","Emp 6"]
manager_num=1
assist_num=2
Currently, I'm think of dividing list_sample into multiple list but i don't think its an efficient way
import random
list_sample=["Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
total_num=6
manager_num=1
assist_num=2
emp_num=3
res = []
manager_list=[]
assist_list=[]
emp_lists=[]
random.shuffle(list_sample)
for x in list_sample:
if "Manager" in x:
manager_list.append(x)
elif "Assist" in x:
assist_list.append(x)
elif "Emp" in x:
emp_lists.append(x)
If anyone can guide me into how i can develop this function, it will be great
Thank you
CodePudding user response:
Simply use simple random and if conditions like so:
import random
list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
total_num=6
manager_num=1
assist_num=2
emp_num=3
res = []
while total_num > 0:
choice = random.choice(list_sample)
if "Manager" in choice and manager_num > 0:
res.append(choice)
manager_num -= 1
total_num -= 1
elif "Assist" in choice and assist_num > 0:
res.append(choice)
assist_num -= 1
total_num -= 1
elif "Emp" in choice and emp_num > 0:
res.append(choice)
emp_num -= 1
total_num -= 1
print(res)
Note: This is a straightforward approach and can be further simplified using Pythonic techniques such as eval()
CodePudding user response:
I think that split to separate lists isn't necessarily a bad idea. It will provide you with flexibility.
For example you can do something like this
list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
random.shuffle(list_sample)
managers = [li for li in list_sample if li.startswith("Manager")]
assists = [li for li in list_sample if li.startswith("Assist")]
emps = [li for li in list_sample if li.startswith("Emp")]
managers_num = 4
assists_num = 1
emps_num = 3
total = managers_num assists_num emps_num
result = []
# Choose Managers
result.append(managers[:managers_num])
result.append(assists[:assists_num])
left = managers_num assists_num - len(result)
result.append(emps[:emps_num left])
Anyway, I think that not dividing to groups or sorting the array will require more loop iterations on the whole list which is not efficient.
CodePudding user response:
This solution allows you to choose the type of employees for a role.
For instance, to select managers first by manager, then assistant, then Employee:
- specify manager_categories = ["Man", "Ass", "Emp"] (category by first 3 letters of employee)
Code
from random import shuffle
def select_emp(lst,
managers = 0,
manager_categories = ['Man', 'Ass', 'Emp'],
assistants = 0,
assistants_categories = ['Ass', 'Emp'],
employees = 0,
employee_categories = ['Emp']):
def selection(category, cnt, seen):
' Choose employees at random of a particular type (i.e. prefix) '
options = [emp for emp in lst if emp.startswith(category) and emp not in seen] # possible employees
shuffle(options) # random order
return sorted(options[:cnt], key = lambda x: int(x.split()[1])) # up to cnt of employees # select up to cnt
# sorted by index
def draw(categories, needed, seen):
''' Selects employees based on preferred order of categories
For instance, if we need a certain number of managers we loop over the employee
categories we allow until we satisfy the requriement
'''
allocated = []
if needed > 0:
for category in categories:
allocated = selection(category, needed - len(allocated), seen)
seen.update(allocated)
if len(allocated) == needed:
break
else:
raise Exception('Not enought employees to satisfy constraint')
return allocated
seen = set()
# Allocate managers, assistants, & employees
managers = draw(manager_categories, managers, seen)
assistants = draw(assistants_categories, assistants, seen)
employees = draw(employee_categories, employees, seen)
return managers, assistants, employees
Usage
from pprint import pprint as pp # pretty print
list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
Example 1
Using default manager, assistant, and employee categories
pp(select_emp(list_sample,
managers = 5,
assistants = 2,
employees = 3))
>>> (['Manager 1', 'Manager 2', 'Manager 3', 'Manager 4', 'Assist 2'],
['Assist 1', 'Assist 3'],
['Emp 2', 'Emp 3', 'Emp 6'])
Example 2
Allows selection of managers from Managers or Employees by changing default manager_categories
pp(select_emp(list_sample,
managers = 5,
manager_categories = ['Man', 'Emp'], # changed default
assistants = 2,
employees = 3))
>>> (['Manager 1', 'Manager 2', 'Manager 3', 'Manager 4', 'Emp 1'],
['Assist 2', 'Assist 3'],
['Emp 2', 'Emp 4', 'Emp 5'])
CodePudding user response:
Your code is efficient. Here is an another way of doing the same.
import random
list_sample=["Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
total_num=6
manager_num=1
assist_num=2
emp_num=3
res = []
manager_list=[]
assist_list=[]
emp_lists=[]
# Getting all the managers, assistants and employees
for x in list_sample:
if x.startswith("Assist"):
assist_list.append(x)
elif x.startswith("Emp"):
emp_lists.append(x)
else:
manager_list.append(x)
# Check if the number of managers, assistants and employees are correct
while len(manager_list) < manager_num:
# Get random emp from emp_lists
manager_list.append(emp_lists.pop(random.randint(0, len(emp_lists)-1)))
while len(assist_list) < assist_num:
# Get random emp from emp_lists
assist_list.append(emp_lists.pop(random.randint(0, len(emp_lists)-1)))
print("manager_list: ", manager_list)
print("assist_list: ", assist_list)
print("emp_lists: ", emp_lists)
Output :
manager_list: ['Emp 4']
assist_list: ['Assist 1', 'Assist 2', 'Assist 3', 'Assist 4']
emp_lists: ['Emp 1', 'Emp 2', 'Emp 3', 'Emp 5', 'Emp 6']