tkinter and scrabble solver problems
Question: I have had to learn python 3.3.3 for a logic and design class. I am extremely
new at programming and the code below is the culmination of what ive learned
on my own in 10 weeks. I had my program working fine at a procedural level
with out a GUI. my program was a typical scrabble solver. I just am having a
horrible time with tkinter. I need to take my input from the entry to the main
module run through and input the results to a listbox. i even gave up on
passing parameters from the class tot he main so i set the rack and results to
a global var. I understand that this might be too much of hassle for someone
to help but any help i get to get this done before finals would be greatly
appreciated. thank you in advance.

    
    
    #only reason these are global is because im having trouble with tkinter and
    #passing the proper parameters to the main module
    
    global results
    global rack
    
    import tkinter as tk
    
    #class for GUI
    class application:
        def __init__(self):
    
    
           self.main=tk.Tk()
    
    
             #top fram includes rack label, rack entry, rack enter button and quit button
           self.top_frame = tk.Frame(self.main)
    
           self.main.title('Scrabble Solver')
           self.main.geometry('300x300')
           self.main.wm_iconbitmap('favicon.ico')
    
           self.racklbl = tk.Label(self.top_frame, text="Enter your rack")
           self.racklbl.pack()
    
           self.rackent=tk.Entry(self.top_frame)
           self.rackent.pack(side="left")
    
           self.rackbtn = tk.Button(self.top_frame, text = "Enter",
    command=self.getRackData)
           self.rackbtn.pack(side="left")
    
           self.top_frame.pack()
    
    
    
           #bottom frame includes listbox for results display and scrollbar
    
           self.bot_frame = tk.Frame(self.main)
    
           self.validlist = tk.Listbox(self.bot_frame, width=30)
           self.validlist.pack(side="left")
    
           self.scrollbar = tk.Scrollbar(self.bot_frame)
           self.scrollbar.pack(side="right", fill="y")
    
           self.QUIT = tk.Button(self.top_frame, text="QUIT",                       fg="red", command=self.main.destroy)
           self.QUIT.pack(side='left')
    
           self.bot_frame.pack()
    
           tk.mainloop()
    
    
        def showError(self):
            tk.messagebox.showinfo('You have entered too many letters')
        def getRackData(self):
            rack = input(self.rackent.get())
    
    
    
    def main():
        rack=""
        gui = application() 
    
    
        #dictionary for the scores
        scores = {"A": 1, "C": 3, "B": 3, "E": 1, "D": 2, "G": 2,
                 "F": 4, "I": 1, "H": 4, "K": 5, "J": 8, "M": 3,
                 "L": 1, "O": 1, "N": 1, "Q": 10, "P": 3, "S": 1,
                 "R": 1, "U": 1, "T": 1, "W": 4, "V": 4, "Y": 4,
                 "X": 8, "Z": 10}
    
    
        #get the rack letters
        #rack = getRackLetters(gui)
        #call module to put file into an array
        rack = getRackLetters(rack,gui)
        putFileIntoArray(rack, scores)
    
    
    # function to get rack letters 
    def getRackLetters(rack,gui):
        rack = rack.upper()
        #call function to verify number of letters entered
        verify= verifyRackLetters(rack)
        if verify == True:
            return rack
        else:
            gui.showError()
            main()
    #function to verify number of letters entered    
    def verifyRackLetters(rack):
        if len(rack) <= 8:
            verify = True
        else:
            verify = False
        return verify
    
    #module to put file into an array    
    def putFileIntoArray(rack, scores):
        words = []
        file = open("dict.dat", "r")   
    
        for line in file:
            line = line.strip()
            words.append(line)
    
        file.close()
        #call module to find and create an array of valid words then score them
        findValidWords(words, scores)
    
    
    
    # module to find and create an array of valid words then score them
    def findValidWords(words, rack, scores):
    
        valid = []
        for word in words:
    
            candidate = True
            rack_letters = list(rack)
    
            for letter in word:
                if letter not in rack_letters:
                    candidate = False
                else:
                    rack_letters.remove(letter)
            #score the valid words and append to list
            if candidate == True:
                total = 0
                for letter in word:
                    total = total + scores[letter]
                valid.append([total, word])
    
        #call module to sort and print the valid words list with scores
        scoreValidWords(valid)
    
        #module to sort and print the list
    def scoreValidWords(valid):
    valid.sort()
    
        for entry in valid:
            score = entry[0]
            word = entry[1]
            results.append(str(score) + " " + word)
    
    
        print(results)
    main()
    


Answer: Although I removed the scrollbar ( I guess you will figure out how to add that
too) I completely rewrote your code, to be more pythonic, and easier to read
and write. However I tried to stick to your code as much as possible.

I guess it is working now:

![enter image description here](http://i.stack.imgur.com/nGeYW.png) ![enter
image description here](http://i.stack.imgur.com/syOh9.png)

Here is the `dictionary.dat` I used:

    
    
    beast
    lemon
    ape
    apple
    sea
    pea
    orange
    bat
    

And here is the code itself:

    
    
    # Import python modules
    import tkinter
    import tkinter.messagebox
    from collections import Counter
    
    # Module level constants
    SCORES = {'A': 1, 'C': 3, 'B': 3, 'E': 1, 'D': 2, 'G': 2, 'F': 4, 'I': 1,
              'H': 4, 'K': 5, 'J': 8, 'M': 3, 'L': 1, 'O': 1, 'N': 1, 'Q': 10,
              'P': 3, 'S': 1, 'R': 1, 'U': 1, 'T': 1, 'W': 4,  'V': 4, 'Y': 4,
              'X': 8, 'Z': 10}
    
    class App(tkinter.Tk):
    
        def __init__(self, word_list, *args, **kwargs):
            # Initialize parent class by passing instance as first argument
            tkinter.Tk.__init__(self, *args, **kwargs)
    
            # Store values
            self.word_list = word_list
    
            # Setup main window
            self.title('Scrabble Solver')
    
            # Create widgets
            rack_label = tkinter.Label(self, text='Enter your rack')
            self.rack_entry = tkinter.Entry(self)
            rack_button = tkinter.Button(self, text='Enter', command=self.search)
            quit_button = tkinter.Button(self, text='Quit', command=self.quit)
            self.valid_list = tkinter.Listbox(self, width=40, font='Courier')
    
            # Place widgets
            rack_label.grid(row=0, column=0, sticky=tkinter.W)
            self.rack_entry.grid(row=1, column=0, sticky=tkinter.W)
            rack_button.grid(row=1, column=1, sticky=tkinter.W)
            quit_button.grid(row=1, column=2, sticky=tkinter.W)
            self.valid_list.grid(row=2, columnspan=3, sticky=tkinter.W)
    
        def run(self):
            # Enter event loop
            self.mainloop()
    
        def error(self):
            # Throw and error message dialog
            tkinter.messagebox.showinfo('You have entered too many letters!')
    
        def search(self):
            # Cleanup up valid list
            self.valid_list.delete(0, tkinter.END)
            # Get data of entry, and make them lower case
            rack = self.rack_entry.get().lower()
            # Check length of data
            if len(rack) <= 8:
                return self.find_valid_words(rack)
            self.error()
    
        def find_valid_words(self, rack):
            # Create a dictionary for valid words and its values
            valid = {}
            rack_chars = Counter(rack)
            for word in self.word_list:
                word_chars = Counter(word)
                if word_chars == word_chars & rack_chars:
                    valid[word] = sum(SCORES[letter.upper()] for letter in word)
    
            # Sort the results and insert them into the list box
            if valid:
                for word, score in sorted(valid.items(), key=lambda v: v[1], reverse=True):
                    self.valid_list.insert(tkinter.END, '{:<10} {}'.format(word, score))
            else:
                self.valid_list.insert(tkinter.END, 'No results found.')
    
    if __name__ == '__main__':
        # Open dictionary file and scan for words
        with open('dictionary.dat', 'r') as f:
            all_words = [word for word in f.read().split()]
        # Create instance and call run method
        App(all_words).run()
    

