def openFiles(self): '''Prompts the user for the location of the dictionary and document to be checked, via a the system's file explorer dialog.''' self.fileOptions = {'parent': self.root, 'initialdir': self.directory} try: with askopenfile(message="Location of dictionary file:", **self.fileOptions) as dictionaryFile: self.dictionary = LanguageHelper(dictionaryFile) with askopenfile(message="Location of document file:", **self.fileOptions) as documentFile: self.document = map(str.strip, documentFile.read().split(' ')) except AttributeError: sys.exit()
class SpellChecker: '''A spell-checking and editing toolkit with a GUI interface.''' def __init__(self): '''Constructs the Tkinter window and configures all the necessary options and bindings. Declares all necessary class-level attributes, constructs the widgets to be bound to the Tkinter window, and starts the spell checking process automatically after creation.''' self.directory = os.path.dirname(os.path.realpath(__file__)) self.root = Tk() self.root.geometry("1000x600+%d+%d" % (self.root.winfo_screenwidth()/2 - 500, self.root.winfo_screenheight()/2 - 300)) self.root.protocol('WM_DELETE_WINDOW', sys.exit) self.openFiles() self.documentIndex = int() self.documentIndexHistory = list() self.ignoreList = list() self.punctuation = ['.', '?', '!', ',', ';', ':'] self.createButtons() self.createDocumentBox() self.createSuggestionBox() self.startSpellChecker() mainloop() def openFiles(self): '''Prompts the user for the location of the dictionary and document to be checked, via a the system's file explorer dialog.''' self.fileOptions = {'parent': self.root, 'initialdir': self.directory} try: with askopenfile(message="Location of dictionary file:", **self.fileOptions) as dictionaryFile: self.dictionary = LanguageHelper(dictionaryFile) with askopenfile(message="Location of document file:", **self.fileOptions) as documentFile: self.document = map(str.strip, documentFile.read().split(' ')) except AttributeError: sys.exit() def createButtons(self): '''Creates all necessary buttons and binds them to the relevant methods. Places them in the main window via the grid geometry manager.''' labels = [["New", {0: self.newFile }], ["Exit", {0: self.exitProgram }], ["Save", {0: self.saveToFile }], ["Clear", {0: self.clearText }], ["Add", {0: self.addToDictionary }], ["Edit", {0: self.editSuggestion }], ["Ignore", {0: self.ignoreWord }], ["Previous", {0: self.previousWord }]] buttonList = dict() for each in range(len(labels)): buttonList[labels[each][0]] = Button(self.root, height=2, width=9, text=labels[each][0], command=labels[each][1][0]) buttonList[labels[each][0]].grid(row=0, column=each, padx = 8, pady=2) def createDocumentBox(self): '''Creates the Text widget that will be used to display the document and all edits to the user. Placed in the main window via the place geometry manager. Uses relative, scalable coordinates.''' self.documentBox = Text(self.root, yscrollcommand=Scrollbar(Frame(self.root), orient=VERTICAL).set) self.documentBox.insert(INSERT, ' '.join(self.document)) self.documentBox.place(relx=0.02, y=50, relwidth=0.46, relheight=0.88) def createSuggestionBox(self): '''Creates the Listbox widget that will be used to display the edit suggestions as choices to the user. Placed in the main window via the place geometry manager. Uses relative, scalable coordinates.''' self.suggestionBox = Listbox(self.root, yscrollcommand=Scrollbar(Frame(self.root), orient=VERTICAL).set) self.suggestionBox.bind("<<ListboxSelect>>", lambda x: self.updateSuggestionBox(True)) self.suggestionBox.place(relx=0.52, y=50, relwidth=0.46, relheight=0.88) def updateDocumentBox(self, wordFix): '''Updates the Text widget with the edit selected by the user. Takes a string as an argument and clears the widget when the program runs out of words to edit.''' try: if self.document[self.documentIndex][-1] in self.punctuation: self.document[self.documentIndex] = wordFix + self.document[self.documentIndex][-1] else: self.document[self.documentIndex] = wordFix self.documentBox.delete('1.0', END) self.documentBox.insert(INSERT, ' '.join(self.document)) except IndexError: self.documentBox.delete('1.0', END) def updateSuggestionBox(self, trigger=False): '''Checks if the function was triggered by the user's Listbox selection. If so, it updates the document box with the desired edit. If not, cycles forward until it finds an incorrectly spelled word and it updates the document index and displays the new edit suggestions to the user accordingly. Records every misspelled word found in a list, storing the original word and the index where it was found. Takes a boolean as an argument, whose default value is False.''' try: if trigger: self.updateDocumentBox(self.suggestionBox.get(self.suggestionBox.curselection())) cycleForward = True while cycleForward: if self.document[self.documentIndex] in self.ignoreList: choiceList = [None] elif self.document[self.documentIndex][-1] in self.punctuation: choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex][:-1]) else: choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex]) if choiceList not in [[None], []]: self.documentIndexHistory.append([self.documentIndex, self.document[self.documentIndex]]) self.suggestionBox.delete(0, END) for choice in choiceList: self.suggestionBox.insert(END, choice) cycleForward = False else: self.documentIndex += 1 except (IndexError, TclError): self.suggestionBox.delete(0, END) def startSpellChecker(self): '''Starts the program by cycling through the words in the document until it finds an incorrectly spelled word. Displays edit suggestions to the user accordingly.''' if self.document[self.documentIndex][-1] in self.punctuation: choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex][:-1]) else: choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex]) if choiceList not in [[None], []]: self.documentIndexHistory.append([self.documentIndex, self.document[self.documentIndex]]) for choice in choiceList: self.suggestionBox.insert(END, choice) else: self.documentIndex += 1 self.startSpellChecker() def newFile(self): '''Destroys the Tk object, prompting the outside loop to construct a new SpellChecker instance.''' self.root.destroy() def exitProgram(self): '''Prompts the user to choose a filename and location to save the document progress, and then hard-exits the program.''' self.saveToFile() sys.exit() def saveToFile(self): '''Prompts the user to choose a filename and location to save the document progress.''' try: with asksaveasfile(message="Location to save file:", **self.fileOptions) as output: output.write(' '.join(self.document)) except AttributeError: pass def clearText(self): '''Clears the document and document box widget.''' self.document = list() self.documentBox.delete('1.0', END) def addToDictionary(self): '''Adds the mispelled word to a list of acceptable words and calls previousWord(), which cycles the document index forward and moves onto the next mispelled word.''' self.ignoreList.append(self.document[self.documentIndex]) self.ignoreWord() def editSuggestion(self): '''Promps the user for a custom edit to the mispelled word, via a system dialog. Applies the edit to the document and updates the document box accordingly. Calls updateSuggestionBox at the end to cycle the program forward to the next mispelled word.''' try: editedWord = askstring("Edit Word", "Enter word to use:") self.updateDocumentBox(editedWord) self.documentIndex += 1 self.updateSuggestionBox() except TypeError: pass def ignoreWord(self): '''Increments the document index by one and calls updateSuggestionBox() to cycle forward to the next misspelled word.''' self.documentIndex += 1 self.updateSuggestionBox() def previousWord(self): '''Sets the currect document index to the index of the previous mispelled word and pops the two most recent edits off the edit history. Updates the document with the original misspelled word and calls updateSuggestionBox() to cycle the program forward.''' try: self.documentIndex = self.documentIndexHistory[-2][0] self.updateDocumentBox(self.documentIndexHistory[-2][1]) self.documentIndexHistory = self.documentIndexHistory[:-2] self.updateSuggestionBox() except IndexError: pass