Code Cohesion
Several of your functions are doing too much work. For example dict_maker
gets input from the user (not specified in docstring). It would be much better to pass that user input as a parameter.
Another function that does too much is list_print
. Since it kind of acts like a main function, this is somewhat excusable; however, it's doing its own job (printing the tuples) while also having to call dict_maker
.
You could break out some of the code in rack_check
into a seperate function perhaps called can_be_spelled
. I'd argue this helps with code readability since the function name documents what the inner for
loop is doing while also allowing for code reuse.
def rack_check(rack, words):
return [word for word in words if can_be_spelled(word, rack)]
def can_be_spelled(word, rack):
letters = list(rack)
for letter in word:
if not letter in letters:
return False
letters.remove(letter)
return True
Note how this also simplifies the logic too since a function return
acts more naturally than a break
.
Use a main function so you can import the code in this file:
if __name__ == "__main__":
scores = get_scrabble_letter_scores()
word_master = look_up("sowpods.txt")
rack = raw_input("Letters: ")).lower()
dict = dict_maker(scores, word_master, rack)
list_print(dict)
Some quick things to consider:
- You're using a fair amount of hard coded constants and globals. If you refactor these to function parameters, you can programatically change and reuse them (i.e. the score each letter gets, which file the words are stored in, whether you get the rack from a user or an AI). These changes come at little to no cost while also vastly improving the code's cohesion, so why not?
if valid
reads better thanif valid == True
look_up
,dict_maker
, andlist_print
are pretty vauge function names- Getting user input in a function restricts it to a user context
- Printing output restricts a function to a printing context