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())
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Apr 7, 2016 at 9:10
\$\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.

answered Apr 7, 2016 at 13:01
\$\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\$ Commented Apr 8, 2016 at 7:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.