Advertisement
Guest User

Untitled

a guest
Feb 19th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.37 KB | None | 0 0
  1. # Problem Set 4C
  2. # Name: Yume Murakami
  3. # Collaborators:
  4. # Time Spent: x:xx
  5.  
  6. import string
  7. from ps4a import get_permutations
  8.  
  9. ### HELPER CODE ###
  10. def load_words(file_name):
  11. '''
  12. file_name (string): the name of the file containing
  13. the list of words to load
  14.  
  15. Returns: a list of valid words. Words are strings of lowercase letters.
  16.  
  17. Depending on the size of the word list, this function may
  18. take a while to finish.
  19. '''
  20.  
  21. print("Loading word list from file...")
  22. # inFile: file
  23. inFile = open(file_name, 'r')
  24. # wordlist: list of strings
  25. wordlist = []
  26. for line in inFile:
  27. wordlist.extend([word.lower() for word in line.split(' ')])
  28. print(" ", len(wordlist), "words loaded.")
  29. return wordlist
  30.  
  31. def is_word(word_list, word):
  32. '''
  33. Determines if word is a valid word, ignoring
  34. capitalization and punctuation
  35.  
  36. word_list (list): list of words in the dictionary.
  37. word (string): a possible word.
  38.  
  39. Returns: True if word is in word_list, False otherwise
  40.  
  41. Example:
  42. >>> is_word(word_list, 'bat') returns
  43. True
  44. >>> is_word(word_list, 'asdf') returns
  45. False
  46. '''
  47. word = word.lower()
  48. word = word.strip(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
  49. return word in word_list
  50.  
  51.  
  52. ### END HELPER CODE ###
  53.  
  54. WORDLIST_FILENAME = 'words.txt'
  55.  
  56. # you may find these constants helpful
  57. VOWELS_LOWER = 'aeiou'
  58. VOWELS_UPPER = 'AEIOU'
  59. CONSONANTS_LOWER = 'bcdfghjklmnpqrstvwxyz'
  60. CONSONANTS_UPPER = 'BCDFGHJKLMNPQRSTVWXYZ'
  61.  
  62. class SubMessage(object):
  63. def __init__(self, text):
  64. '''
  65. Initializes a SubMessage object
  66.  
  67. text (string): the message's text
  68.  
  69. A SubMessage object has two attributes:
  70. self.message_text (string, determined by input text)
  71. self.valid_words (list, determined using helper function load_words)
  72. '''
  73. self.message_text = text
  74. self.valid_words = load_words(WORDLIST_FILENAME)
  75.  
  76. def get_message_text(self):
  77. '''
  78. Used to safely access self.message_text outside of the class
  79.  
  80. Returns: self.message_text
  81. '''
  82. return self.message_text
  83.  
  84. def get_valid_words(self):
  85. '''
  86. Used to safely access a copy of self.valid_words outside of the class.
  87. This helps you avoid accidentally mutating class attributes.
  88.  
  89. Returns: a COPY of self.valid_words
  90. '''
  91. return self.valid_words
  92.  
  93. def build_transpose_dict(self, vowels_permutation):
  94. '''
  95. vowels_permutation (string): a string containing a permutation of vowels (a, e, i, o, u)
  96.  
  97. Creates a dictionary that can be used to apply a cipher to a letter.
  98. The dictionary maps every uppercase and lowercase letter to an
  99. uppercase and lowercase letter, respectively. Vowels are shuffled
  100. according to vowels_permutation. The first letter in vowels_permutation
  101. corresponds to a, the second to e, and so on in the order a, e, i, o, u.
  102. The consonants remain the same. The dictionary should have 52
  103. keys of all the uppercase letters and all the lowercase letters.
  104.  
  105. Example: When input "eaiuo":
  106. Mapping is a->e, e->a, i->i, o->u, u->o
  107. and "Hello World!" maps to "Hallu Wurld!"
  108.  
  109. Returns: a dictionary mapping a letter (string) to
  110. another letter (string).
  111. '''
  112.  
  113. punc = list(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
  114. dict = {}
  115. for i, let in enumerate(vowels_permutation.lower()):
  116. dict[VOWELS_LOWER[i]] = let
  117. for i, let in enumerate(vowels_permutation.upper()):
  118. dict[VOWELS_UPPER[i]] = let
  119. for let in CONSONANTS_LOWER:
  120. dict[let] = let
  121. for let in CONSONANTS_UPPER:
  122. dict[let] = let
  123. for pun in punc:
  124. dict[pun] = pun
  125. return dict
  126.  
  127. def apply_transpose(self, transpose_dict):
  128. '''
  129. transpose_dict (dict): a transpose dictionary
  130.  
  131. Returns: an encrypted version of the message text, based
  132. on the dictionary
  133. '''
  134.  
  135. enc_message = []
  136. for let in self.message_text:
  137. enc_message.append(transpose_dict[let])
  138. return ''.join(enc_message)
  139.  
  140. class EncryptedSubMessage(SubMessage):
  141. def __init__(self, text):
  142. '''
  143. Initializes an EncryptedSubMessage object
  144.  
  145. text (string): the encrypted message text
  146.  
  147. An EncryptedSubMessage object inherits from SubMessage and has two attributes:
  148. self.message_text (string, determined by input text)
  149. self.valid_words (list, determined using helper function load_words)
  150. '''
  151. SubMessage.__init__(self, text)
  152.  
  153. def decrypt_message(self):
  154. '''
  155. Attempt to decrypt the encrypted message
  156.  
  157. Idea is to go through each permutation of the vowels and test it
  158. on the encrypted message. For each permutation, check how many
  159. words in the decrypted text are valid English words, and return
  160. the decrypted message with the most English words.
  161.  
  162. If no good permutations are found (i.e. no permutations result in
  163. at least 1 valid word), return the original string. If there are
  164. multiple permutations that yield the maximum number of words, return any
  165. one of them.
  166.  
  167. Returns: the best decrypted message
  168.  
  169. Hint: use your function from Part 4A
  170. '''
  171. tranpose_dict_list = []
  172. de_message_list = []
  173. perm_list = get_permutations('aeiou')
  174. for perm in perm_list:
  175. tranpose_dict_list.append(self.build_transpose_dict(perm))
  176. for dic in tranpose_dict_list:
  177. de_message = self.apply_transpose(dic)
  178. de_message_list.append(de_message)
  179. test = []
  180. big_test = []
  181. word_list = self.get_valid_words()
  182. for mes in de_message_list:
  183. de_words = mes.split()
  184. for word in de_words:
  185. if is_word(word_list, word):
  186. test.append(1)
  187. else:
  188. test.append(0)
  189. big_test.append((sum(test), mes))
  190. del test[0:len(test)]
  191. best_choice = max(big_test)
  192. possible_de_message = []
  193. for tup in big_test:
  194. if tup[0] == best_choice[0] and tup[1] not in possible_de_message:
  195. possible_de_message.append(tup[1])
  196. de_string = ''
  197. for mes in possible_de_message:
  198. de_string = de_string + ', ' + mes
  199. return de_string[1:]
  200.  
  201.  
  202. if __name__ == '__main__':
  203.  
  204. # Example test case
  205. message = SubMessage("Hello World!")
  206. permutation = "eaiuo"
  207. enc_dict = message.build_transpose_dict(permutation)
  208. print("Original message:", message.get_message_text(), "Permutation:", permutation)
  209. print("Expected encryption:", "Hallu Wurld!")
  210. print("Actual encryption:", message.apply_transpose(enc_dict))
  211. enc_message = EncryptedSubMessage(message.apply_transpose(enc_dict))
  212. print("Decrypted message:", enc_message.decrypt_message())
  213.  
  214. #TODO: WRITE YOUR TEST CASES HERE
  215. message = SubMessage('Hairy Chest')
  216. permutation = 'iauoe'
  217. enc_dict = message.build_transpose_dict(permutation)
  218. print("Original message:", message.get_message_text(), "Permutation:", permutation)
  219. print("Expected encryption:", "Hiury Chast!")
  220. print("Actual encryption:", message.apply_transpose(enc_dict))
  221. enc_message = EncryptedSubMessage(message.apply_transpose((enc_dict)))
  222. print('Decrypted message:', enc_message.decrypt_message())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement