From a88192a1f9f642681afc99db0a5d743932bdc04e Mon Sep 17 00:00:00 2001 From: DavidVFitzGerald <72464297+DavidVFitzGerald@users.noreply.github.com> Date: Tue, 6 Oct 2020 20:32:23 +0200 Subject: [PATCH] Update rotate_pairs.py The current solution does not check for all rotated words, due to the stop argument of the range being 14 instead of 26 in the rotate_pairs function. For example, the word "act" should print out "act 24 yar", but currently does not print out anything. As the current solution uses a somewhat brute force approach, my suggested solution uses a different approach, where each word is rotated only once. It also makes use of a dictionary to store the rotate pairs, by using the setdefault method covered in Exercise 11.2. This suggested solution also directly addresses the specification of the exercise description ("Write a program that reads a wordlist and finds all the rotate pairs."). Only the word_list needs to be provided as argument, and a list containing lists with all rotate pairs is returned. Each word is thus contained only once in the returned list of lists. Since the suggested approach does not need to check for the presence of a word in the list of words, the words can be provided simply as a list instead of a dict. --- code/rotate_pairs.py | 58 ++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/code/rotate_pairs.py b/code/rotate_pairs.py index 850512a..f5b8852 100644 --- a/code/rotate_pairs.py +++ b/code/rotate_pairs.py @@ -1,11 +1,8 @@ """This module contains a code example related to - Think Python, 2nd Edition by Allen Downey http://thinkpython2.com - Copyright 2015 Allen Downey - License: http://creativecommons.org/licenses/by/4.0/ """ @@ -14,32 +11,41 @@ from rotate import rotate_word -def make_word_dict(): - """Read the words in words.txt and return a dictionary - that contains the words as keys""" - d = dict() - fin = open('words.txt') - for line in fin: - word = line.strip().lower() - d[word] = None +def make_word_list(): + """Read the words in words.txt and return a list + that contains the words.""" + with open('words.txt') as fin: + word_list = [] + for line in fin: + word = line.strip().lower() + word_list.append(word) + + return word_list - return d - -def rotate_pairs(word, word_dict): - """Prints all words that can be generated by rotating word. - - word: string - word_dict: dictionary with words as keys +def rotate_pairs(word_list): + """Return list of all rotate pairs found in word_list. + word_list: list of words """ - for i in range(1, 14): - rotated = rotate_word(word, i) - if rotated in word_dict: - print(word, i, rotated) + rotate_pairs = {} + + for word in word_list: + first_letter = word[0] + if first_letter.isupper(): + ref_letter = ord('A') + elif first_letter.islower(): + ref_letter = ord('a') + + # Create a rotated word which always starts with "A" or "a" + # and use it as a key to store the word in the rotate_pairs dict. + rotated_word = rotate_word(word, ref_letter - ord(first_letter)) + rotate_pairs.setdefault(rotated_word, []).append(word) + + # Rotate pairs are contained in the lists that have more than one word. + rotate_pairs = [item for item in rotate_pairs.values() if len(item) > 1] + return rotate_pairs if __name__ == '__main__': - word_dict = make_word_dict() - - for word in word_dict: - rotate_pairs(word, word_dict) + word_list = make_word_list() + all_rotate_pairs = rotate_pairs(word_list)