Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.20 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import bst
  4. import avl
  5. import logging
  6.  
  7. log = logging.getLogger(__name__)
  8.  
  9. class TerminalUI:
  10. def __init__(self, mode):
  11. '''
  12. Select BST mode by passing "bst" as argument; otherwise select AVL mode.
  13. '''
  14. if mode == "bst":
  15. logging.info("running in BST mode")
  16. self._tree = bst.BST()
  17. else:
  18. logging.info("running in AVL mode")
  19. self._tree = avl.AVL()
  20.  
  21. def run(self):
  22. '''
  23. Provides a terminal-based UI to perform tree operations.
  24. '''
  25. flag = 0
  26. self.display_menu()
  27. while True:
  28. opt, err = self.get_choice()
  29. if err is not None:
  30. self.display_error(err)
  31. continue
  32.  
  33. if opt == "m":
  34. self.display_menu()
  35. elif opt == "t":
  36. self.display_tree()
  37. elif opt == "a":
  38. self.add_value()
  39. flag = 1
  40. elif opt == "d":
  41. if flag == 1:
  42. self.delete_value()
  43. else:
  44. print("Add value(s) first.")
  45. elif opt == "f":
  46. self.is_member()
  47. elif opt == "q":
  48. break
  49. else:
  50. log.error("menu case '{}' is missing, aborting".format(opt))
  51. return 1
  52.  
  53. def display_menu(self):
  54. '''
  55. Shows a menu which is encapsulated between a top rule and a bottom rule.
  56. '''
  57. print(self.menu_rule("top", self.menu_width()))
  58. for opt in self.menu_options():
  59. print("\t{}".format(opt))
  60. print(self.menu_rule("bot", self.menu_width()))
  61.  
  62. def display_error(self, err):
  63. '''
  64. Shows an error message.
  65. '''
  66. print("error> {}".format(err))
  67.  
  68. def display_tree(self):
  69. '''
  70. Shows the tree's structure and content.
  71. '''
  72. if self._tree.is_empty():
  73. print("\n Tree is empty\n")
  74. return
  75.  
  76. self.show_2d()
  77. print("")
  78. print("Size: {}".format(self._tree.size()))
  79. print("Height: {}".format(self._tree.height()))
  80. print("Inorder: {}".format(self._tree.inorder()))
  81. print("Preorder: {}".format(self._tree.preorder()))
  82. print("Postorder: {}".format(self._tree.postorder()))
  83. print("BFS star: {}".format([
  84. v if v is not None else "*" for v in self._tree.bfs_order_star()
  85. ]))
  86. print("")
  87.  
  88. def add_value(self):
  89. '''add_value:
  90. Prompts the user for an integer which is added to the tree.
  91. '''
  92. value, err = self.get_int("Enter value to be added")
  93. if err is not None:
  94. self.display_error(err)
  95. return
  96. self._tree = self._tree.add(value)
  97.  
  98. def delete_value(self):
  99. '''delete_value:
  100. Prompts the user for an integer which is removed from the tree.
  101. '''
  102. value, err = self.get_int("Enter value to be deleted")
  103. if err is not None:
  104. self.display_error(err)
  105. return
  106. self._tree = self._tree.delete(value)
  107.  
  108. def is_member(self):
  109. '''is_member:
  110. Prompts the user for a value that is checked for membership in the tree.
  111. '''
  112. value, err = self.get_int("Enter search value")
  113. if err is not None:
  114. self.display_error(err)
  115. return
  116.  
  117. print("\n {} is a {}member\n".format(
  118. value,
  119. "" if self._tree.is_member(value) is True else "non-"),
  120. )
  121.  
  122. def menu_rule(self, pos, width):
  123. '''
  124. Returns a horizontal line using stars or tildes.
  125. '''
  126. return ("*" if pos == "top" else "~") * width
  127.  
  128. def menu_width(self):
  129. '''
  130. Returns the menu width.
  131. '''
  132. return 32
  133.  
  134. def menu_options(self):
  135. '''
  136. Returns a list of printable menu options. Blank entries will be interpreted
  137. as new lines, and single characters before the colon as hotkeys.
  138. '''
  139. return [
  140. "m: menu",
  141. "t: display tree",
  142. "",
  143. "a: add value",
  144. "d: delete value",
  145. "f: test membership",
  146. "",
  147. "q: quit",
  148. ]
  149.  
  150. def menu_hotkeys(self):
  151. '''
  152. Returns a list of symbols that the menu defined as valid hotkeys.
  153. '''
  154. opts = self.menu_options()
  155. return [ o.split(":")[0] for o in opts if len(o.split(":")[0]) == 1 ]
  156.  
  157. def get_choice(self):
  158. '''
  159. Attempts to read a valid menu option from the user. Caller should look
  160. for errors by comparing the second return value against ``not None''.
  161. '''
  162. buf = input("menu> ")
  163. if len(buf) != 1:
  164. return None, "input must be a a single character"
  165. if buf[0] not in self.menu_hotkeys():
  166. return None, "invalid choice"
  167. return buf[0], None
  168.  
  169. def get_int(self, message):
  170. '''
  171. Writes a message to stdout and waits for an integer from stdin.
  172. '''
  173. buf = input("{}> ".format(message))
  174. try:
  175. return int(buf), None
  176. except ValueError:
  177. return None, "invalid input (not an integer)"
  178.  
  179. def show_2d(self):
  180.  
  181. a = self._tree.bfs_order_star()
  182. i = 1
  183. hojd_pa_trad = self._tree.height()
  184. just_nu_hojd = 0
  185.  
  186. for p in range(len(a)):
  187. antal = 2**(hojd_pa_trad - just_nu_hojd)
  188.  
  189. for x in range(antal):
  190.  
  191. print("\t", end='')
  192.  
  193. print("{}".format(a[p] if a[p] is not None else "*" ), end = '')
  194.  
  195. for x in range(antal):
  196.  
  197. print("\t", end='')
  198.  
  199. if p + 1 == i:
  200.  
  201. print("\n")
  202. i = i * 2 + 1
  203. just_nu_hojd = just_nu_hojd + 1
  204.  
  205. '''
  206. Shows a pretty 2D tree based on the output of bfs_order_star(). None
  207. values are are replaced by stars ("*").
  208. '''
  209.  
  210.  
  211. if __name__ == "__main__":
  212. logging.critical("ui contains no main module")
  213. sys.exit(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement