Computer Science glossary made with Tkinter This is a Computer science glossary that I made with Tkinter. The user inputs the word that they want and then the code searches the text file for it and then ouputs it to the user.

#My Computer Scienece Glossary project

from tkinter import *

#key down function
def click():
    global definition
    entered_text=textentry.get() #this will collect the text from the text entry box
    output.delete(0.0, END)
    try:
        definition = my_compdictonary[entered_text]
    except:
        definition = "Sorry defintion not found"
    output.insert(END, definition)

### main:
window = Tk()
window.title("Computer Science Glossary")
window.configure(background="black")

### My Photo
photo1 = PhotoImage(file="me.gif")
Label(window,image=photo1, bg="black") .grid(row=0, column=0, sticky=W)

#create label
Label(window, text="Enter the word you want the definition for:",bg="black", fg="white", font="none 12 bold").grid(row=1, column=0, sticky=N)

#create a text entry box
textentry = Entry(window, width=20, bg="white")
textentry.grid(row=2, column=0, sticky=N)


#add a submit button
Button(window, text="SUBMIT", width=6, command=click).grid(row=3, column=0, sticky=N)

#create another label
Label(window, text="\nDefinition:", bg="black", fg="white", font="none 12 bold").grid(row=4, column=0, sticky=N)

#create a textbox
output = Text(window, width=60, height=4, wrap=WORD, background="white")
output.grid(row=5, column=0, columnspan=1, sticky=N)

#the dictionary
my_compdictonary = {}
with open("glossary.txt", "r+") as file:
    for line in file:
        word, defintions = line.strip().split(" : ")
        my_compdictonary[word] = defintions



window.mainloop()


I want suggestions on how I can make this computer science glossary better.

All suggestions will be greatly appreciated.
PEP-8

As always, follow the PEP-8 coding standards.


Don't exceed 79 characters per line
You a space around the = assignment operator (you mostly do this, but violate it in entered_text=textentry.get()


Use a main function

Avoid writing code in the main scope.  Move the code into a main function, and call it ... but only if the script is not imported into another file:

def main():
    window = Tk()
    # ...
    window.mainloop()

if __name__ == '__main__':
    main()


Catch only the exceptions you expect

The following code:

try:
    definition = my_compdictonary[entered_text]
except:
    definition = "Sorry definition not found"


will catch any and every exception, and ignore them all, regardless of the correct type.  Why is it bad?  Imagine you correct the spelling error in your main program, and change my_compdictonary to my_compdictionary, but you don't correct it in this section of code.  You test the program, and it doesn't crash, but every definition you look up returns "Sorry definition not found".  Where is the bug?  How hard is it to debug?

If instead the code was written as:

try:
    definition = my_compdictonary[entered_text]
except KeyError:
    definition = "Sorry definition not found"


the program would crash with a NameError, with the traceback showing you the exact line in question.  Now how hard is it to debug?

In this particular case, the try...except structure is really overkill.  You can provide a default argument when getting a key from the dictionary to handle the key not found case.  That reduces the above four lines to only one:

definition = my_compdictonary.get(entered_text, "Sorry definition not found")


Keep related code together

You have:

output.delete(0.0, END)
# Four
# unrelated
# lines of
# code
output.insert(END, definition)


It would be clearer to keep output.delete() and output.insert() as back to back lines.  Eg)

definition = my_compdictonary.get(entered_text, "Sorry definition not found")
output.delete(0.0, END)
output.insert(END, definition)


Avoid global

Avoid using global as much as possible.  It is a sign of poorly organized code, and makes it harder to reason about the correctness of the code, and harder to test the code because side-effects increase in scope.

In this case, it is simple to avoid the global definition because definition is never used anywhere except in the click() function.  It should not be a global variable; it is local!

Never ask for more than you need

with open("glossary.txt", "r+") as file:


Why are you opening the file for reading plus?  Will you ever be writing to it?  Can the program now accidentally write to the file because it has write privileges, corrupting the file?  You are only reading the file; just open it for reading.

with open("glossary.txt") as file:


Be liberal in what you accept

The Robustness Principle warns us about the input we get from the outside.  Be fault tolerant.  Or perhaps better, make it so faults can't happen.

    word, defintions = line.strip().split(" : ")


What happens when a definition contains a colon?

noun : A person, place, or thing.  Can be classified into two groups : common or proper. 


split(" : ") now returns 3 items, and you've only got variables for two.  So you'll get ValueError: too many values to unpack (expected 2).  How can you avoid this?  How about telling split() that you only expect to find one delimiter:

    word, defintions = line.strip().split(" : ", 1)


Now, word is "noun" and defintions is "A person, place, or thing.  Can be classified into two groups : common or proper."

What about blank lines?  They will still crash the program.  You might want to test for those as well.  What about non-blank lines that don't have a definition?  Those, well maybe it would be ok if those result in an exception; that would be really bad input in the "glossary.txt".



Make it easier for reviewers to run your code.  You have an image 'me.gif' in your code that we don't have.  Running without it crashes the program due to file not found.  How big was that image?  32x32?  300x300?  It would affect the size of the resulting window.  Do we just delete the lines of code so we can test the program?

How about 'glossary.txt'?  Do we have to guess what the file format is?  Perhaps you could have given a sample file with 3 or 4 entries.



Future Improvements

You might want to allow the user to look up a definition by just pressing "Enter" after typing in the word.  The way it works right now, the user has to move their hands from the keyboard to the mouse.

What if the user enters with CAPS LOCK on?  What if the definition is provided with a capital letter?  Is the definition really not found?  Could you be a little more liberal in what you accept?



Here is a simple refactoring of your original code with some of the suggestions from comments above.  No global variables.  The click() function is moved into main(), so it has access to the local variables textentry, my_compdictonary and output.  The image was deleted, so I could quickly run the program.  The dictionary is generated using list comprehension, and will ignore blank lines.

This is by no means the "best" code.  Many improvements can still be made in naming (can we have something better than click?), spelling of variables, and so on.  Perhaps a class may be in order.  

from tkinter import *

"""
A Computer science glossary made with Tkinter

Requires a "glossary.txt" file with definitions, one per line, with a
space-colon-space separating the term from the definition.  Eg)

    word : a fragment of language
    term : a word or phrase used to describe a thing or to express a concept 

Also should require a "me.gif" image of approximately 64 x 64 pixels, but
that was removed temporarily.
"""

def main():
    """Main function.

       This function creates the UI, and enters the tkinter mainloop.
       It does not return until the user closes the UI."""

    def click():
        entered_text = textentry.get()
        definition = my_compdictonary.get(entered_text,
                                          "Sorry defintion not found")
        output.delete(0.0, END)
        output.insert(END, definition)

    window = Tk()
    window.title("Computer Science Glossary")
    window.configure(background="black")

    Label(window, text="Enter the word you want the definition for:",
          bg="black", fg="white", font="none 12 bold"
         ).grid(row=1, column=0, sticky=N)

    textentry = Entry(window, width=20, bg="white")
    textentry.grid(row=2, column=0, sticky=N)

    Button(window, text="SUBMIT", width=6, command=click).grid(row=3, column=0, sticky=N)

    Label(window, text="\nDefinition:", bg="black", fg="white",
          font="none 12 bold"
         ).grid(row=4, column=0, sticky=N)

    output = Text(window, width=60, height=4, wrap=WORD, background="white")
    output.grid(row=5, column=0, columnspan=1, sticky=N)

    with open("glossary.txt", "r") as file:
        my_compdictonary = dict( (line.split(" : ", 1)) for line in file if line )

    window.mainloop()

if __name__ == '__main__':
    main()