Why does my attribute seemingly not exist after I have defined it

Viewed 40

I am working on a project but I have an error coming up saying that an attribute of one of the objects does not exist despite me defining it. This is my first time encountering this error and I am not sure what is causing it. I would also love some tips on the program in general as I am still fairly new to OOP and inheritance using tkinter.

    import tkinter as tk
    import time as t
    from tkinter import messagebox as m
    from FiveLetterWords import fivewords as wordbank #This is Wordle's list of five letter words to us
    from PossibleFiveLetterWords import possfivewords as possiblewords #This is a list of all five letter words
    from random import choice

    #Define all colours to be used at some point
    GREEN="#50C878"
    YELLOW="#FFEA00"
    RED="#EE4B2B"
    GREY="#D3D3D3"
    BLACK="#000000"

    def wordle_check(word,answer):   #This is my algorithm for Wordle. There may be an easier way to do it but I know this one works
      colours = ["" for y in answer]
      greychecked = []
      checked = []
      answerlist = ["" for z in answer]
      for z in answer:
        answerlist[answer.index(z)] = z
      greenchecked = ["F" for y in range(len(answer))]
      for y in range(len(answer)):
        if greenchecked[y] != "T":
          if word[y] not in answer:
            colours[y] = GREY
            greychecked.append(word[y])
          elif word[y] in answer and answer.count(word[y]) == greenchecked.count("T") and greenchecked.index("T") == y:
            colours[y] = GREY
            greychecked.append(word[y])
      for y in range(len(answer)):
        if word[y] == answer[y]:
          colours[y] = GREEN
          greenchecked[y] = "T"
          checked.append(word[y])
      for y in range(len(answer)):
        if word[y] not in greychecked:
          if answer.count(word[y]) == 1 and word.count(word[y]) > 1:
            if greenchecked[y] != "T":
              if word[y] not in checked:
                checked.append(word[y])
                colours[y] = YELLOW
              else:
                colours[y] = GREY
          else:
            if greenchecked[y] != "T":
              if greenchecked[answerlist.index(word[y])] == "F":
                colours[y] = YELLOW
              else:
                colours[y] = GREY
      return colours

    class App(tk.Tk): #Create App class inheriting from tkinter Tk window to group together the tiles, graphics and functionality in the game
      def __init__(self):
        global answer
        global window
        super().__init__()
        self.geometry("410x540")
        self.configure(bg=GREY)
        self.answer=choice(wordbank)
        self.title=tk.Label(master=self,bg=GREY,relief=tk.GROOVE,font=("Arial",21,"bold"),text="~ ~ ~ ~ Wordle ~ ~ ~ ~")
        self.title.grid(row=0, column=0, columnspan=5,sticky="NESW",pady=5,padx=5,ipady=5,ipadx=5)
        self.blankspaceA=tk.Label(master=self,bg=GREY)
        self.blankspaceA.grid(row=1,column=0,columnspan=5,sticky="NESW")
        self.rows=[Set(self,i,bg=GREY) for i in range(2,8)]
        self.bind("<Key>",self.process_key)
        self.bind("<BackSpace>",self.process_back)
        self.bind("<Enter>",self.process_guess)
        self.mainloop()

      def end(self): #Ends the game and program
        self.destroy()
        quit()

      def process_key(self,event): #Processes a letter key press
        for item in self.winfo_children():
          if not item.completed:
            for tile in item.winfo_children():
              if not tile.entered and not tile.final:
                tile.entered=True
                tile.place_letter(event.char)
                if tile.grid_info["column"] == 4:
                  item.completed=True
                break
            break

      def process_back(self,event): #Processes a backspace key press
        for item in reversed(self.winfo_children()):
          for tile in reversed(item.winfo_children()):
            if tile.entered and not tile.final:
              tile.entered=False
              tile.place_letter("")

      def guess(self,event): #Processes an Return Key press and gives the result of a guess
        for item in self.winfo_children():
          if item.completed and not item.final:
            guess=""
            for tile in item.winfo_children():
              guess+=tile["text"]
            if guess not in possiblewords:
              for tile in item.winfo_children():
                tile.show_wrong()
            else:
              result=wordle_check(guess,self.answer)
              list=item.winfo_children()
              for x in range(5):
                list[x].configure(bg=result[x])
                list[x].final=True

    class Set(tk.Frame): #Create Set class inheriting from tkinter Frame to group a row of tiles together. Having experimented before, I think this doesn't affect the grid() layout
      def __init__(self,master,row,*args,**kwargs):
        super().__init__(master,*args,**kwargs)
        self.completed=False
        self.final=False
        self.grid(row=row,column=0,columnspan=5,sticky="NESW",padx=10,ipady=5,ipadx=5)
        self.tiles=[Tile(self,row,j) for j in range(5)]

    class Tile(tk.Label): #Create a Tile class inheriting from tk.Label to act as a tile in the game
      def __init__(self,master,r,c):
        super().__init__(master=master,bg=GREY,font=("Arial",12,"bold"),relief=tk.RAISED,width=3,height=2)
        self.colour=GREY
        self.entered=False
        self.final=False
        self.grid(row=r,column=c,sticky="NESW",pady=10,padx=10,ipadx=10,ipady=10)

      def show_wrong(self): #Highlights the label red for a sec to indicate the answer is wrong
        self.configure(bg=RED)
        t.sleep(0.75)
        self.configure(bg=self.colour)

      def place_letter(self,letter): #Adds text to the label
        if len(letter) <= 1:
          self.configure(text=letter)

    def win(): #Flashes message if you win
      pass

    def lose(): #Flashes message if you lose
      pass

    if __name__ == "__main__": #Start game
      window = App()

Other Info: As can be seen, it is not quite finished. I am using Replit online IDE. Thanks

The error message is:

    Exception in Tkinter callback
    Traceback (most recent call last):
      File "/nix/store/2vm88xw7513h9pyjyafw32cps51b0ia1-python3-3.8.12/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
        return self.func(*args)
      File "main.py", line 100, in process_guess
        if item.completed and not item.final:
    AttributeError: 'Label' object has no attribute 'completed'
0 Answers
Related