Exception has occurred: AttributeError 'str' object has no attribute 'variables'

49 Views Asked by At

I'm currently trying to program a backtrack resolver for an university project. It should resolve the job scheduling problem. I created 2 classes to do this: JobSchedulingProblem and Constraint.

class JobSchedulingProblem:
    def __init__(self):
        self.constraints = constrs.constraint()
        self.variables={}
        
    def checkAllconstraints(self,assignment) ->bool:
        for var1,var2 in self.constraints.constraints:
            result=self.check_constraint(var1,var2, assignment)
            if not result:
                return False
        return True
    
    def check_constraint(arg1,arg2,self,assignment) ->bool:
        if (self.variables[arg1]  not in assignment) or (self.variables[arg2] not in assignment):
            return True
        if self.constraints.constraints[arg1][arg2][1]==0:
            return assignment[arg2]>=assignment[arg1]+self.constraints.constraints[arg1][arg2][0]
        if self.constraints.constraints[arg1][arg2][1]==1:
            return assignment[arg1]+self.constraints.constraints[arg1][arg2][0]<=assignment[arg2]
        if self.constraints.constraints[arg1][arg2][1]==2:
            return (assignment[arg1]+self.constraints.constraints[arg1][arg2][0]<=assignment[arg2])or(assignment[arg2]+self.constraints.constraints[arg1][arg2][0]<=assignment[arg1])

    def add_variable(self, var, domain):
        self.variables[var] = domain
        print (self.variables.keys())

    def add_constraint(self, arg1,arg2, value, type, assignment):
        self.constraints.constraints[arg1][arg2]=(value,type)
        if type==1:
            self.constraints.constraints[arg2][arg1]=(value,0)
        if type==0:
            self.constraints.constraints[arg2][arg1]=(value,1)
        else:
            self.constraints.constraints[arg2][arg1]=(value,2)

            
    def removeDomains(new_assignment, var,self):
        removeddomains={}
        for var1 in self.constraints.constraints[var]:
            if self.constraints.constraints[var][var1][1]==0:
                intervallo_da_rimuovere = range(1, new_assignment+1-self.constraints.constraints[var][var1][0])
                # crea un nuovo range escludendo l'intervallo specificato
                nuovo_dominio = list(self.variables[var1])
                nuovo_dominio = list(filter(lambda x: x not in intervallo_da_rimuovere, nuovo_dominio))
                self.variables[var1] = range(nuovo_dominio[0], nuovo_dominio[-1] + 1)
                removeddomains[var1]=intervallo_da_rimuovere
            if (self.constraints.constraints[var][var1][1]==1) or (self.constraints.constraints[var][var1][1]==2):
                intervallo_da_rimuovere = range(1, new_assignment+1+self.constraints.constraints[var][var1][0])
                # crea un nuovo range escludendo l'intervallo specificato
                nuovo_dominio = list(self.variables[var1])
                nuovo_dominio = list(filter(lambda x: x not in intervallo_da_rimuovere, nuovo_dominio))
                self.variables[var1] = range(nuovo_dominio[0], nuovo_dominio[-1] + 1)
                removeddomains[var1]=intervallo_da_rimuovere
        return removeddomains
    
    def putRemovedDomains(tmp, var,self):
        for var1 in self.constraints.constraints[var]:
            lista1 = list(tmp[var1])
            lista2 = list(self.variables[var1])
            lista_unione = lista1 + lista2
            # Crea un nuovo range basato sulla lista unione
            self.variables[var1] = range(lista_unione[0], lista_unione[-1] + 1)




    def backtracking_search(self, assignment={}):
        if len(assignment) == len(self.variables):
            return assignment

        var_not_assigned = [var for var in self.variables if var not in assignment]
        var = var_not_assigned[0]

        for value in self.variables[var]:
            new_assignment = assignment.copy()
            new_assignment[var] = value

            if self.checkAllconstraints( new_assignment):
                tmp = self.removeDomains(new_assignment, var, self)
                result = self.backtracking_search(self, new_assignment)
                if result is None:
                    self.putRemovedDomains(tmp,var,self)
                if result is not None:
                    return result
        return None
class constraint:
    constraints={}
    def __init__(self):
        self.constraints = {
            'Aa': {},
            'Ap': {},
            'Rda': {},
            'Rsa': {},
            'Rdp': {},
            'Rsp': {},
            'Dda': {},
            'Dsa': {},
            'Ddp': {},
            'Dsp': {},
            'Cda': {},
            'Csa': {},
            'Cdp': {},
            'Csp': {},
            'I': {},
        }
        self.constraints['Aa']['Rda']=(10,1) 
        self.constraints['Aa']['Rsa']=(10,1) 
        self.constraints['Ap']['Rdp']=(10,1) 
        self.constraints['Ap']['Rdp']=(10,1)
        self.constraints['Rda']['Dda']=(1,1)   
        self.constraints['Dda']['Cda']=(2,1) 
        self.constraints['Rsa']['Dsa']=(1,1) 
        self.constraints['Ddp']['Cdp']=(2,1)  
        self.constraints['Rsp']['Dsp']=(1,1) 
        self.constraints['Dsp']['Csp']=(2,1) 
        self.constraints['Aa']['Ap']=(10,2) 
        self.constraints['Ap']['Aa']=(10,2)
        self.constraints['Aa']['I']=(3,1)
        self.constraints['Ap']['I']=(3,1)
        self.constraints['Rda']['I']=(3,1)
        self.constraints['Dda']['I']=(3,1)
        self.constraints['Cda']['I']=(3,1)
        self.constraints['Rsa']['I']=(3,1)
        self.constraints['Dsa']['I']=(3,1)
        self.constraints['Csa']['I']=(3,1)
        self.constraints['Rdp']['I']=(3,1)
        self.constraints['Ddp']['I']=(3,1)
        self.constraints['Cdp']['I']=(3,1)
        self.constraints['Rsp']['I']=(3,1)
        self.constraints['Dsp']['I']=(3,1)
        self.constraints['Csp']['I']=(3,1)
        self.constraints['I']['Aa']=(3,0)
        self.constraints['I']['Ap']=(3,0)
        self.constraints['I']['Rda']=(3,0)
        self.constraints['I']['Dda']=(3,0)
        self.constraints['I']['Cda']=(3,0)
        self.constraints['I']['Rsa']=(3,0)
        self.constraints['I']['Dsa']=(3,0)
        self.constraints['I']['Csa']=(3,0)
        self.constraints['I']['Rdp']=(3,0)
        self.constraints['I']['Ddp']=(3,0)
        self.constraints['I']['Cdp']=(3,0)
        self.constraints['I']['Rsp']=(3,0)
        self.constraints['I']['Dsp']=(3,0)
        self.constraints['I']['Csp']=(3,0)
        self.constraints['Rda']['Aa']=(10,0) 
        self.constraints['Rsa']['Aa']=(10,0) 
        self.constraints['Rdp']['Ap']=(10,0) 
        self.constraints['Rsp']['Ap']=(10,0)
        self.constraints['Dda']['Rda']=(1,0)   
        self.constraints['Cda']['Dda']=(2,0) 
        self.constraints['Dsa']['Rsa']=(1,0) 
        self.constraints['Csa']['Dsa']=(2,0) 
        self.constraints['Ddp']['Rdp']=(1,0) 
        self.constraints['Cdp']['Ddp']=(2,0)  
        self.constraints['Dsp']['Rsp']=(1,0) 
        self.constraints['Csp']['Dsp']=(2,0) 

While trying to run it, I got 2 errors:

Exception has occurred: AttributeError 'str' object has no attribute 'variables' File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 15, in check_constraint if (self.variables[arg1] not in assignment) or (self.variables[arg2] not in assignment): File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 9, in checkAllconstraints result=self.check_constraint(var1,var2, assignment) File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 79, in backtracking_search if self.checkAllconstraints( new_assignment): File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 114, in main soluzione = csp.backtracking_search() File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 149, in main() AttributeError: 'str' object has no attribute 'variables'

or

Exception has occurred: TypeError JobSchedulingProblem.check_constraint() takes 4 positional arguments but 5 were given File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 9, in checkAllconstraints result=self.check_constraint(var1,var2, self, assignment) File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 79, in backtracking_search if self.checkAllconstraints( new_assignment): File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 114, in main soluzione = csp.backtracking_search() File "/home/alebonch/Python/Progetto IA/Backtrackjobscheduling.py", line 149, in main() TypeError: JobSchedulingProblem.check_constraint() takes 4 positional arguments but 5 were given

When I tried to change: result=self.check_constraint(var1,var2, assignment)

into: result=self.check_constraint(var1,var2, self, assignment)

I tried asking chatGPT for help, but Im really confused by how the variables become strings and by the fact that the editor thinks Im passing more arguments than Im supposed to do. Its my first time programming in python and I probably made lots of mistakes, any help would be really appreciated.

1

There are 1 best solutions below

0
AlexM On

Class functions in Python have an automatic first argument of self, which is the instance of the class that you called the function. All of your class functions (e.g. check_constraint()) should have self as the first argument then so there's no confusion, but when you call that function on an instance of the class (e.g. my_instance_of_JobSchedulingProblem.check_constraint()) you skip the self argument. I think both of your errors will be resolved by making self the first argument of all of your functions.