1

I am working on an Autocomplete text editor. It take an input from the user when space is pressed and prints the list of words with prefix mentioned by the user.

Here is the code:

#!/usr/bin/env python

from tkinter import *
import tkinter.font as tkFont


class Node:
    def __init__(self):
        self.word = None
        self.nodes = {}  # dict of nodes

    def __get_all__(self):
        x = []

        for key, node in self.nodes.items():
            if (node.word is not None):
                x.append(node.word)

            x = x + node.__get_all__

        return x

    def __str__(self):
        return self.word

    def __insert__(self, word, string_pos=0):
        current_letter = word[string_pos]

        if current_letter not in self.nodes:
            self.nodes[current_letter] = Node();
        if (string_pos + 1 == len(word)):
            self.nodes[current_letter].word = word
        else:
            self.nodes[current_letter].__insert__(word, string_pos + 1)

            return True

    def __get_all_with_prefix__(self, prefix, string_pos):
        x = []
        #print("We are in the get prefix func", prefix)

        for key, node in self.nodes.items():
            if (string_pos >= len(prefix) or key == prefix[string_pos]):
                if (node.word is not None):
                    x.append(node.word)

                if (node.nodes != {}):
                    if (string_pos + 1 <= len(prefix)):
                        x = x + node.__get_all_with_prefix__(prefix, string_pos + 1)
                    else:
                        x = x + node.__get_all_with_prefix__(prefix, string_pos)

        return x


class Trie:
    def __init__(self):
        self.root = Node()

    def insert(self, word):
        self.root.__insert__(word)

    def get_all(self):
        return self.root.__get_all__

    def get_all_with_prefix(self, prefix, string_pos=0):
        return self.root.__get_all_with_prefix__(prefix, string_pos)


root = Tk()
trie = Trie()
customFont = tkFont.Font(family="arial", size=17)

with open('words_file_for_testing.txt', mode='r') as f:
    for line in f:
        for word in line.split():
            trie.insert(word)


def retrieve_input(self):
    inputValue = content_text.get("1.0", "end-1c")
    print(trie.get_all_with_prefix(inputValue))
    printing_the_list(inputValue)

def printing_the_list(getinputvalue):
    print(getinputvalue)
    print(type(getinputvalue))
    print(trie.get_all_with_prefix("A"))
    print(trie.get_all_with_prefix(getinputvalue))
    #print(type(words))
    #print(words)
    #print(trie.get_all_with_prefix("A"))
    #master = Tk()
    #listbox = Listbox(master)
    #listbox.pack()
    #for item in words:
    # listbox.insert(END, item)

root.title("Autocomplete Word")
root.geometry('800x400+150+200')
content_text = Text(root, wrap='word', font=customFont)
content_text.focus_set()
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')
root.bind("<space>", retrieve_input)
root.mainloop()

Now, I am having problem with its printing_the_list(getinputvalue) function. In this function, getinputvalue is the variable in which user input value is stored. When I manually entered the string to print(trie.get_all_with_prefix("A")) funtion it print the words list as desired but, when I tried to print the prefix list of words with user input value using the getinputvalue variable, got an empty list as [].

The above python code prints:

[]
A 
<class 'str'>
['AAE', 'AAEE', 'AAG', 'AAF', 'AAP', 'AAPSS', 'AAM', 'AAMSI', 'AARC', 'AAII', 'AAO', 'Aar', 'Aaron', 'Aarika', 'Aargau', 'Aaren', 'Aarhus', 'Aara', 'Aarau', 'Aandahl', 'Aani', 'Aaqbiye', 'Aalesund', 'Aalto', 'Aalborg', 'Aalst', 'Aachen', 'A-and-R']
[]

What am I doing wrong.

4
  • 5
    I'm not helping here, but just know __insert__ and __get_all__ are really bad named methods. __<name>__ methods are reserved for python built-in, you should never name a method or attribute like this. You can name it like _<name> if you want to make it "private" (technically not, but it's a convention) Commented Jul 31, 2017 at 16:09
  • agreed, except one minor point, it's more like: _protected and __private (by convention) Commented Jul 31, 2017 at 16:27
  • 1
    Is the output for your test desirable? When you get all words with prefix 'A', you only get back words that begin with two As like Aaron and Aalto. Is this what you want? Commented Jul 31, 2017 at 18:13
  • The problem is in print(trie.get_all_with_prefix(inputValue)) function, it not taking inputValue and returning empty list []. but when I pass string like print(trie.get_all_with_prefix("A")) it works perfect. i dont know what is wrong in this line: print(trie.get_all_with_prefix(inputValue)) Commented Aug 1, 2017 at 4:43

1 Answer 1

1

Your problem is that when you type A and then press space

inputValue = content_text.get("1.0", "end-1c")

returns 'A ' instead of 'A'.

This is because content_text.get() adds a new line character at the end of the string. To ignore both the newline character and the space, use:

inputValue = content_text.get("1.0", "end-2c")
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot @Josselin, you are a Saviour
You're welcome, I found the issue out using pdb, the Python debugger. It's a very useful tool! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.