Python – Iteration-time repeating elements appended in Python 3.6

Iteration-time repeating elements appended in Python 3.6… here is a solution to the problem.

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.

Related Problems and Solutions