class Interact: def __init__(self): self.prompt = '?' def run(self): while 1: command = self.readCommand() if not command: break result = self.evalCommand(command) if result: break def readCommand(self): try: return raw_input(self.prompt) except: return None # break loop on ctrl-d class Menu(Interact): def readCommand(self): # extend superclass read print '\n\tMENU...' # print menu items first self.showOptions() return Interact.readCommand(self) def evalCommand(self, cmd): try: return self.runCommand(cmd) # catch bad key/index, etc. except (EOFError, SystemExit): # let sys.exit, ctrl-d pass return 1 # but break main loop except: print "what: '%s'?" % cmd # return None implicitly # the rest is exactly the same as menu1.py # subclasses repeated here for convenience class DictMenu(Menu): def showOptions(self): options = self.menu.keys() # menu = dictionary options.sort() for cmd in options: print '\t\t' + cmd def runCommand(self, cmd): return self.menu[cmd]() # call action by name class ListMenu(Menu): # menu = nested sequences def showOptions(self): for i in range(len(self.menu)): print '\t\t%d) %s' % (i, self.menu[i][0]) def runCommand(self, cmd): try: index = eval(cmd) # convert string to number except: raise IndexError return self.menu[index][1]() # selected by position