def setUp(self): self.client = Redis() self.client.flushdb() self.ac = AutoComplete(self.client) self.timeout = 3
class TestAutoComplete(unittest.TestCase): def setUp(self): self.client = Redis() self.client.flushdb() self.ac = AutoComplete(self.client) self.timeout = 3 def test_feed_and_hint(self): self.ac.feed("黄晓明", 100) self.ac.feed("黄健翔", 70) self.ac.feed("黄健宏", 50) self.assertEqual(self.ac.hint("黄", 5), ["黄晓明", "黄健翔", "黄健宏"]) self.assertEqual(self.ac.hint("黄健", 5), ["黄健翔", "黄健宏"]) self.assertEqual(self.ac.hint("黄健", 1), ["黄健翔"]) def test_expire_feature_works(self): print("创建一个只存在 {0} 秒钟的自动补全结果。".format(self.timeout)) self.ac.feed("Redis", timeout=self.timeout) i = self.timeout while i != 0: print("倒数 {0} 秒钟……".format(i)) sleep(1) i -= 1 self.assertEqual(self.ac.hint("Re", 10), []) print("时间到,自动补全结果已自动被移除!")
def setUp(self): self.client = Redis(decode_responses=True) self.client.flushdb() self.ac = AutoComplete(self.client) self.timeout = 3
def test_auto_complete(self): auto_complete = AutoComplete(self.client) auto_complete.feed("黄晓明", 3) auto_complete.feed("黄建宏", 2) auto_complete.feed("黄晓军", 1) assert auto_complete.hint("黄") == ["黄晓明", "黄建宏", "黄晓军"] assert auto_complete.hint("黄晓") == ["黄晓明", "黄晓军"]
class TestAutoComplete(unittest.TestCase): def setUp(self): self.client = Redis(decode_responses=True) self.client.flushdb() self.ac = AutoComplete(self.client) def test_feed_and_hint(self): self.ac.feed("黄晓明", 100) self.ac.feed("黄健翔", 70) self.ac.feed("黄健宏", 50) self.assertEqual(self.ac.hint("黄", 5), ["黄晓明", "黄健翔", "黄健宏"]) self.assertEqual(self.ac.hint("黄健", 5), ["黄健翔", "黄健宏"]) self.assertEqual(self.ac.hint("黄健", 1), ["黄健翔"])
class DemoApp(MDApp): user = None id = None identifier = None kind = None dialog = None Enter = False # Indicate whether Pressing Enter will save the added RFID roster, names = find_roster() # Look for Students Roster auto_complete = AutoComplete( names) # Object which generates name suggestions suggestions = [] # Suggested names in case of roster current_count = 0 # Number of characters currently in the text field input_mode = False index = 0 menu_items = [] original_input = "" received = False def build(self): self.theme_cls.primary_palette = "Gray" self.title = "Smart Cabinet Admin Application" Window.bind(on_key_down=self._on_keyboard_down) screen = Builder.load_string(KV) return screen def _on_keyboard_down(self, *args): if self.root.current != "admin_routine" or not self.received: # Ignore keys unless in admin_routine and there is no dialog and return if args[2] == 41: # Escape button if self.dialog: self.dismiss() self.shrink_suggestions() return elif args[3] and args[3] in ALLOWED_CHARS: # an allowed character self.root.ids.identifier.text += args[3] self.original_input += args[3] if self.root.ids.identifier.text[:-1] in self.suggestions: # If a name is highlighted and user inputs letter, add letter to the suggested name self.original_input = self.root.ids.identifier.text[:-1] + args[ 3] self.root.ids.identifier.text = self.original_input self.index = 0 elif args[2] == 42 and self.root.ids.identifier.text: # backspace and there is a letter to delete self.original_input = self.root.ids.identifier.text self.root.ids.identifier.text = self.root.ids.identifier.text[:-1] self.original_input = self.original_input[:-1] self.index = 0 if not self.root.ids.identifier.text: self.shrink_suggestions() return elif args[2] == 40: # If Enter key is pressed if self.dialog: # If dialog is open self.send_identifier() self.original_input = "" elif self.root.ids.identifier.text and self.received: # If dialog is closed, and Enter key is pressed: # If suggestions are shown, copy highlighted text and shrink suggestions # self.index = 0 self.validate_identifier() self.shrink_suggestions() return # elif not self.roster or self.kind != "student": # return elif args[ 2] == 81 and self.root.ids.identifier.text and not self.dialog: # down arrow self.index += 1 self.index = min(self.index, len(self.suggestions) - 1) elif args[ 2] == 82 and self.root.ids.identifier.text and not self.dialog: # up arrow self.index -= 1 self.index = max(self.index, 0) else: return # menu_items: [input text, 5 suggestions] if not self.roster or self.kind != "student": return if not self.menu_items: self.menu_items = [ self.root.ids.identifier, self.root.ids.name0, self.root.ids.name1, self.root.ids.name2, self.root.ids.name3, self.root.ids.name4 ] self.suggestions = [self.original_input] + self.auto_complete.auto( self.original_input, max_sugg=5) if len(self.suggestions) == 1: self.shrink_suggestions() return self.show_suggestions() self.highlight_suggestions() if self.index == 0: self.root.ids.identifier.text = self.original_input for idx in range(1, 6): # Populate the name suggestions as needed try: self.menu_items[idx].text = self.suggestions[idx] except IndexError: self.menu_items[idx].text = "" pass def show_suggestions(self): self.input_mode = True # Show suggestions self.root.ids.name_list.size_hint_y = (len(self.suggestions) - 1) * 0.06 self.root.ids.name_list.pos_hint = { "center_y": 0.47 - (len(self.suggestions) - 1) / 2 * .06, "center_x": .5 } def shrink_suggestions(self): self.input_mode = False self.root.ids.name_list.size_hint_y = 0 self.root.ids.name_list.pos_hint = {"center_y": .47, "center_x": .5} def highlight_suggestions(self): for idx in range(1, 6): if idx == self.index: if not self.menu_items[self.index].text: continue self.menu_items[self.index].bg_color = SUGG_COLOR else: self.menu_items[idx].bg_color = SUGG_MENU_COLOR self.root.ids.identifier.text = self.menu_items[self.index].text def on_start(self): return def on_stop(self): try: self.user.close() except AttributeError: pass def connect2(self): self.user = Admin(gui=True) self.root.transition = SlideTransition(direction='left') self.root.current = "access_screen" self.root.ids.spinner2.active = False def connect(self): self.root.ids.spinner2.active = True executor = concurrent.futures.ThreadPoolExecutor() f = executor.submit(self.connect2) def admin_routine(self, kind): # Go to admin_routine screen and save the kind of RFID to be added self.root.transition = SlideTransition(direction='left') self.root.current = "admin_routine" self.kind = kind def get_id(self): # Get the Scanned ID, and allow user to input name (identifier) self.root.ids.id_label.text = "" self.root.ids.spinner.active = True executor = concurrent.futures.ThreadPoolExecutor() f = executor.submit(self.receive) def receive(self): self.user.send_msg(self.kind.encode()) self.id = self.user.get_msg().decode() self.root.ids.id_label.text = self.id self.root.ids.identifier.hint_text = "Enter Name" self.received = True self.root.ids.spinner.active = False def back_btn(self): if self.received: return self.root.transition = SlideTransition(direction='right') self.root.current = "access_screen" self.root.ids.identifier.text = "" self.root.ids.id_label.text = "" def validate_identifier(self): self.identifier = self.root.ids.identifier if not self.identifier.text: return self.dialog = MDDialog( title='Name Check', text=f"Are you sure you want to save {self.identifier.text}?", size_hint=(0.8, 1), buttons=[ConfirmBtn(on_release=self.send_identifier)], ) self.dialog.open() def dismiss(self): if self.dialog: self.dialog.dismiss() self.dialog = None def send_identifier(self, *args): print(self.identifier.text, "Sent!") self.dismiss() name = self.identifier.text.strip() self.user.send_msg(name.encode()) self.root.ids.id_label.text = "SAVED" self.identifier.hint_text = "" self.identifier.disabled = True self.root.ids.get_id.disabled = False self.original_input = "" self.index = 0 self.suggestions = [] self.menu_items = [] self.received = False