From c2342397ebe0f715d7855b5d88f2f5fba078eddd Mon Sep 17 00:00:00 2001 From: oysteini Date: Tue, 11 May 2010 19:23:52 +0000 Subject: [PATCH] Reimplementert confirm som meny; mer tegnkodingshakking. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Har nå mulighet for default-valg i confirm (default-en vises med stor bokstav, som i '(Y/n)', og velges hvis man skriver en tom linje), og confirm leser input på samme måte som alt annet (via Menu.input_str). Har laget en funksjon safe_str som prøver å gjøre om et vilkårlig objekt til noe Python kan printe uten å bli sur. Tok i bruk denne i raw_input-kallet i Menu.input_str (det viser seg at raw_input blir muggen hvis den får et unicode-objekt som inneholder ikke-ASCII-tegn). --- helpers.py | 104 ++++++++++++++++++++++++++++---------------------- text_based.py | 39 +++++++++++++++---- 2 files changed, 91 insertions(+), 52 deletions(-) diff --git a/helpers.py b/helpers.py index 3ce1b25..2d7de06 100644 --- a/helpers.py +++ b/helpers.py @@ -20,56 +20,56 @@ def search_product(string, session): Product.name.ilike('%'+string+'%'))).all() return product_list -def guess_data_type(string): - if string.startswith('NTNU'): - return 'card' - if string.isdigit(): - return 'bar_code' - if string.isalpha() and string.islower(): - return 'username' - return 'product_name' +# def guess_data_type(string): +# if string.startswith('NTNU'): +# return 'card' +# if string.isdigit(): +# return 'bar_code' +# if string.isalpha() and string.islower(): +# return 'username' +# return 'product_name' -def retrieve_user(string, session): -# first = session.query(User).filter(or_(User.name==string, User.card==string)).first() - search = search_user(string,session) - if isinstance(search,User): - print "Found user "+search.name - return search - else: - if len(search) == 0: - print "No users found matching your search" - return None - if len(search) == 1: - print "Found one user: "+list[0].name - if confirm(): - return list[0] - else: - return None - else: - print "Found "+str(len(search))+" users:" - return select_from_list(search) +# def retrieve_user(string, session): +# # first = session.query(User).filter(or_(User.name==string, User.card==string)).first() +# search = search_user(string,session) +# if isinstance(search,User): +# print "Found user "+search.name +# return search +# else: +# if len(search) == 0: +# print "No users found matching your search" +# return None +# if len(search) == 1: +# print "Found one user: "+list[0].name +# if confirm(): +# return list[0] +# else: +# return None +# else: +# print "Found "+str(len(search))+" users:" +# return select_from_list(search) -def confirm(prompt='Confirm? (y/n) '): - while True: - input = raw_input(prompt) - if input in ["y","yes"]: - return True - elif input in ["n","no"]: - return False - else: - print "Nonsense!" +# def confirm(prompt='Confirm? (y/n) '): +# while True: +# input = raw_input(prompt) +# if input in ["y","yes"]: +# return True +# elif input in ["n","no"]: +# return False +# else: +# print "Nonsense!" -def select_from_list(list): - while True: - for i in range(len(list)): - print i+1, " ) ", list[i].name - choice = raw_input("Select user :\n") - if choice in [str(x+1) for x in range(len(list))]: - return list[int(choice)-1] - else: - return None +# def select_from_list(list): +# while True: +# for i in range(len(list)): +# print i+1, " ) ", list[i].name +# choice = raw_input("Select user :\n") +# if choice in [str(x+1) for x in range(len(list))]: +# return list[int(choice)-1] +# else: +# return None def argmax(d, all=False, value=None): maxarg = None @@ -85,3 +85,17 @@ def argmax(d, all=False, value=None): if all: return filter(lambda k: d[k] == d[maxarg], d.keys()) return maxarg + +def safe_str(obj): + ''' + Ugly hack to avoid Python complaining about encodings. + + Call this on any object to turn it into a string which is + (hopefully) safe for printing. + ''' + if isinstance(obj, str): + return obj + if isinstance(obj, unicode): + return obj.encode('utf8') + else: + return safe_str(unicode(obj)) diff --git a/text_based.py b/text_based.py index 10fef9b..78ae35d 100644 --- a/text_based.py +++ b/text_based.py @@ -35,7 +35,7 @@ class Menu(): print self.exit_disallowed_msg return if self.exit_confirm_msg != None: - if not confirm(self.exit_confirm_msg): + if not self.confirm(self.exit_confirm_msg): return raise ExitMenu() @@ -105,7 +105,7 @@ class Menu(): prompt = self.prompt while True: try: - result = raw_input(prompt) + result = raw_input(safe_str(prompt)) except EOFError: print 'quit' self.exit_menu() @@ -193,6 +193,9 @@ class Menu(): return 2 return 1 + def confirm(self, prompt, default=None): + return ConfirmMenu(prompt, default).execute() + def print_header(self): print print self.header_format % self.name @@ -248,6 +251,7 @@ product name or barcode. else: return self.item_value(item_i) + class Selector(Menu): def __init__(self, name, items=[], prompt='select> ', return_index=True, @@ -269,6 +273,26 @@ class Selector(Menu): print self.help_text +class ConfirmMenu(Menu): + def __init__(self, prompt='confirm?', default=None): + Menu.__init__(self, 'question', prompt=prompt, + exit_disallowed_msg='Please answer yes or no') + self.default=default + + def _execute(self): + options = {True: 'Y/n', False: 'y/N', None: 'y/n'}[self.default] + while True: + result = self.input_str('%s (%s) ' % (self.prompt, options)) + if result in ['y','yes']: + return True + if result in ['n','no']: + return False + if self.default != None and result == '': + return self.default + print 'Please answer yes or no' + + + # class ChargeMenu(Menu): # def __init__(self): # self.name = "Add credits to a user account" @@ -479,7 +503,8 @@ When finished, write an empty line to confirm the purchase. thing = self.input_thing(empty_input_permitted=True) if thing == None: if not self.complete_input(): - if confirm('Not enough information entered. Abort purchase? (y/n) '): + if self.confirm('Not enough information entered. Abort purchase?', + default=True): return False continue break @@ -607,9 +632,9 @@ def search_ui2(search_str, result, thing, session): print 'No %ss matching "%s"' % (thing, search_str) return None if len(result) == 1: - msg = 'One %s matching "%s": %s. Use this? (y/n) ' %\ - (thing, search_str, result[0]) - if confirm(msg): + msg = 'One %s matching "%s": %s. Use this?' %\ + (thing, search_str, unicode(result[0])) + if ConfirmMenu(msg, default=True).execute(): return result[0] return None limit = 9 @@ -640,7 +665,7 @@ main = Menu('Dibbler main menu', AddProductMenu(), EditProductMenu()]) ], exit_msg='happy happy joy joy', - exit_confirm_msg='Really quit Dibbler? (y/n) ') + exit_confirm_msg='Really quit Dibbler?') if not conf.quit_allowed: main.exit_disallowed_msg = 'You can check out any time you like, but you can never leave.' while True: