4
\$\begingroup\$
##open file and create a dictionary of {"word":"sorted word"}

word_file = open("word_list(1).txt","r")
word_list = {}
for text in word_file:
    simple_text = ''.join(sorted(text.lower().strip()))
    word_list.update({text.lower().strip():simple_text})

##lowercase and sort the user input word
def simplify_entered_word():
    lower_word = ''.join(sorted(input_word.lower().strip())) #Creates a list with the lowercase, sorted letters.
    return lower_word

#Compare the sorted user input with the values of the dictionary to find the anagrams.
def find_in_dict(entered_word):
    for key,val in word_list.items():
        if val == entered_word:
            print(key,input_word)

##main loop

while True:
    input_word = input("Input the word for anagram checking: ")
    find_in_dict(simplify_entered_word())
\$\endgroup\$
0

1 Answer 1

5
\$\begingroup\$

Good that you tagged with Python 3, as it kinda works in Python 2.7 with a bit different behaviour.

All the time reminder to format according to PEP8; here I'd note that there should be spaces between names, i.e. key, val and print(key, input_word).

Firstly, it's good that there are functions to split the logic up. However part of that is negated by using globals. In general using globals is a bad pattern - here in particular it makes more sense to pass the word list through to the individual functions.

Edit: And I forgot to update it to not use globals, shame on me ...

Most of the comments can also be docstrings instead.


Now, for the globals. Just pass them through to the functions:

def simplify_entered_word(input_word):
    "Lowercase and sort the user input word."
    word = input_word.lower().strip()
    return word, "".join(sorted(word))

This function can now also be reused easily by returning two results, the lowercased word and the sorted result.

Next I'd move the word list reading its own function:

def read_word_list(filename):
    """Open file and create a dictionary of {"word":"sorted word"}."""
    with open(filename, "r") as word_file:
        word_list = {}
        for text in word_file:
            word = text.lower().strip()
            simple_text = "".join(sorted(word))
            word_list.update({word: simple_text})
        return word_list

However this can also be much easier in terms of simplify_entered_word:

def read_word_list(filename):
    """Open file and create a dictionary of {"word":"sorted word"}."""
    with open(filename, "r") as word_file:
        return {simple[0]: simple[1]
                for simple in map(simplify_entered_word, word_file)}

N.b. there might be a better way to write that dictionary comprehension. Note also that I used with as to not leak the file handle from open.

And then call that with the filename:

if __name__ == "__main__":
    word_list = read_word_list("word_list(1).txt")
    while True:
        input_word = input("Input the word for anagram checking: ")
        find_in_dict(word_list, simplify_entered_word(input_word)[1])

Just in case this will only run as a script and not if the file is imported somewhere else, which is good practice.

One problem that still remains is the iteration in find_in_dict. It'd be much simpler if the data structure is slightly changed by collecting all words for one anagram into a list:

from collections import defaultdict

def read_word_list(filename):
    """Open file and create a dictionary of {"word":"sorted word"}."""
    with open(filename, "r") as word_file:
        word_list = defaultdict(list)
        for word, simplified in map(simplify_entered_word, word_file):
            word_list[simplified].append(word)
        return word_list

def find_in_dict(word_list, entered_word):
    """Compare the sorted user input with the values of the dictionary to find
    the anagrams."""
    for name in word_list.get(entered_word, []):
        print(name, entered_word)

Note the use of defaultdict to simplify the automatic creation of the list.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ "N.b. there might be a better way to write that dictionary comprehension." It's not using a comprehension at all, ;P dict(map(simplify_entered_word, word_file)). You change how you use the dict with the defaultdict addition, if you didn't you could use defaultdict(int, map(lambda x: (x, x*2), range(10))). \$\endgroup\$
    – Peilonrayz
    Commented Apr 8, 2016 at 7:58

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.