Iteration-time repeating elements appended in Python 3.6
I’m trying to write part of the code that gets elements from two different lists and matches them as shown below, but for some reason I keep getting duplicate elements in the output list.
def assign_tasks(operators, requests, current_time):
"""Assign operators to pending requests.
Requires:
- operators, a collection of operators, structured as the output of
filesReading.read_operators_file;
- requests, a list of requests, structured as the output of filesReading.read_requests_file;
- current_time, str with the HH:MM representation of the time for this update step.
Ensures: a list of assignments of operators to requests, according to the conditions indicated
in the general specification (omitted here for the sake of readability).
"""
operators = sorted(operators, key=itemgetter(3, 4, 0), reverse=False)
requests = sorted(requests, key=itemgetter(3), reverse=True)
isAssigned = 0
tasks = []
langr = 0 #Variable that gets the language of the request's file (customer's language)
lango = 0 #Variable that gets the language of the operator's file (operator's language)
for i in range(len(requests)-1):
langr = requests[i][1] #What language does the customer speaks?
for k in range(len(operators)-1):
lango = operators[k][1] #What language does the operator speaks?
if langr == lango: #Do they speak the same language?
for j in range(len(operators[k][2])-1):
if (operators[k][2][j] == requests[i][2]) and (operators[k][4] <= 240): # The operator knows how to solve the client's problem? If yes, then group them together.
a = operators[k][2][j]
b = requests[i][2]
tasks.append([current_time, requests[i][0], operators[k][0]])
operator_time = operators[k][4]
request_time = requests[i][4]
new_operator_time = operator_time + request_time
operators[k][4] = new_operator_time
isAssigned == True
#operators.remove(operators[k])
requests.remove(requests[i])
else:
isAssigned = False
if isAssigned == False:
tasks.append([current_time, requests[i][0], "not-assigned"])
operators = sorted(operators, key=itemgetter(3, 4, 0), reverse=False)
return tasks, operators, requests
My current input is this:
operators = [['Atilio Moreno', 'portuguese', ('laptops',), '10:58', 104], ['Leticia Ferreira', 'portuguese', ('laptops',), '11:03', 15], ['Ruth Falk', 'german', ('phones', ' hifi'), '11:06', 150], ['Marianne Thibault', 'french', ('phones',), '11:09', 230], ['Mariana Santana', 'portuguese', ('phones',), '11:11', 230], ['Beate Adenauer', 'german', ('hifi', ' phones'), '11:12', 140], ['Zdenka Sedlak', 'czech', ('phones',), '11:13', 56], ['Romana Cerveny', 'czech', ('phones',), '11:13', 213]]
requests = [['Christina Holtzer', 'german', 'hifi', 'fremium', 7], ['Andrej Hlavac', 'czech', 'phones', 'fremium', 9], ['Dulce Chaves', 'portuguese', 'laptops', 'fremium', 15], ['Otavio Santiago', 'portuguese', 'laptops', 'fremium', 15], ['Dina Silveira', 'portuguese', 'phones', 'fremium', 9], ['Rafael Kaluza', 'slovenian', 'laptops', 'fremium', 13], ['Sabina Rosario' , 'portuguese', 'laptops', 'fremium', 10], ['Nuno Rodrigues', 'portuguese', 'laptops', 'fremium', 12], ['Feliciano Santos', 'portuguese', 'phones', 'fremium', 12]]
current_time = "14:55 06:11:2017"
print(assign_tasks(operators, requests, current_time))
My current output is three lists, for example, the first one is something like this:
[[11:05, Christina Holtzer, not-assigned],[11:05, Christina Holtzer, Beate Adenauer],[11:05, Andrej Hlavac, not-assigned]]
Solution
I don’t really know the logic you’re after, it’s not even my point of view, my point is that you may not be able to focus on logic because you’re too busy with those indexed things. So I took the liberty of modifying your code slightly to show what’s important, and if you’re using Python, you should take advantage of this feature because readability is important.
from operator import attrgetter
class Person:
def __init__(self, name, lan):
self.name = name
self.lan = lan
def is_compatible(self, other):
if other.lan == self.lan:
return True
return False
class Requester(Person):
def __init__(self, *args, problem, mode, time, **kwargs):
super().__init__(*args, **kwargs)
self.problem = problem
self.mode = mode
self.time = time
class Operator(Person):
def __init__(self, *args, expertise, hour, time, **kwargs):
super().__init__(*args, **kwargs)
self.expertise = expertise
self.hour = hour
self.time = time
self.assigned = False
operators = [
Operator(name='Atilio Moreno', lan='portuguese', expertise=('laptops',), hour='10:58', time=104),
.
.
.
Operator(name='Romana Cerveny', lan='czech', expertise=('phones',), hour='11:13', time=213),
]
requests = [
Requester(name='Christina Holtzer', lan='german', problem='hifi', mode='fremium', time=7),
.
.
.
Requester(name='Feliciano Santos', lan='portuguese', problem='phones', mode='fremium', time=12),
]
Once this is done, the task of thinking about logic becomes much simpler, just enter your thoughts:
def assign_tasks(operators, requests, current_time):
operators.sort(key=attrgetter('hour', 'time', 'name'))
requests.sort(key=attrgetter('mode'))
tasks = []
for requester in requests:
for operator in operators:
if requester.is_compatible(operator) and requester.problem in operator.expertise and operator.time < 240:
if not operator.assigned:
tasks.append([current_time, requester.name, operator.name])
operator.assigned = True
operator.time += requester.time
break # Breaks out of second for-loop so we go to the next requester
else: #In case no operator is available
tasks.append([current_time, requester.name, 'not-assigned'])
return tasks, operators, requests
tasks, operators, requests = assign_tasks(operators=operators, requests=requests, current_time=0)
print(tasks)
The output of this is:
[[0, 'Christina Holtzer', 'Ruth Falk'], [0, 'Andrej Hlavac', 'Zdenka Sedlak'], [0, 'Dulce Chaves', 'Atilio Moreno'], [0, 'Otavio Santiago', 'not-assigned'], [0, 'Dina Silveira' , 'not-assigned'], [0, 'Rafael Kaluza', 'not-assigned'], [0, 'Sabina Rosario', 'not-assigned'], [0, 'Nuno Rodrigues', 'not-assigned'], [0, 'Feliciano Santos', 'not-assigned']]
It’s a bit long, but all requestors either have operators or not.
Again, I
don’t know if this logic is the logic you’re after, but I hope you’ll see that using this approach makes it easier to think about the problem (what really matters), and it’s also easier for others to read.