On Thu, 13 Sep 2012 10:23:22 +0200, Peter Otten wrote: > MRAB wrote: > >> On 12/09/2012 19:04, Alister wrote: >>> On Wed, 12 Sep 2012 18:56:46 +0200, Jabba Laci wrote: >>> >>>>> For example: >>>>> >>>>> def install_java(): >>>>> pass >>>>> >>>>> def install_tomcat(): >>>>> pass >>>> >>>> Thanks for the answers. I decided to use numbers in the name of the >>>> functions to facilitate function calls. Now if you have this menu >>>> option for instance: >>>> >>>> (5) install mc >>>> >>>> You can type just "5" as user input and step_5() is called >>>> automatically. If I use descriptive names like install_java() then >>>> selecting a menu point would be more difficult. And I don't want >>>> users to type "java", I want to stick to simple numbers. >>>> >>>> Laszlo >>> >>> No No NO! >>> you cant just pass user input to system calls without validating it >>> first (google sql injection for examples of the damage unsanitised >>> input can cause, it is not just as SQL problem) >>> >>> it is just as easy so select a reasonably named function as a bad one >>> >>> option=raw_input('select your option :') >>> >>> if option =="1": install_java() >>> if option =="2": install_other() >>> >>> alternatively you cold add your functions into a dictionary an call >>> them from that >>> >>> opts={'1':install java,'2':install_other} >>> >>> option=raw_input('select your option :') >>> opts[option] >>> >>> Poorly named functions are a major example of poor programming style. >>> >>> one of the fundamental pillars for python is readability! >>> >> Or you could do this: >> >> >> def install_java(): >> "Install Java" >> print "Installing Java" >> >> def install_tomcat(): >> "Install Tomcat" >> print "Installing Tomcat" >> >> menu = [install_java, install_tomcat] >> >> for index, func in enumerate(menu, start=1): >> print "{0}) {1}".format(index, func.__doc__) >> >> option = raw_input("Select your option : ") >> >> try: >> opt = int(option) >> except ValueError: >> print "Not a valid option" >> else: >> if 1 <= opt < len(menu): >> menu[opt - 1]() >> else: >> print "Not a valid option" > > I'd still argue that a function index is the wrong approach. You can use > tab completion to make entering descriptive names more convenient: > > import cmd > > class Cmd(cmd.Cmd): > prompt = "Enter a command (? for help): " > > def do_EOF(self, args): > return True > def do_quit(self, args): > return True > > @classmethod def install_command(class_, f): > def wrapped(self, arg): > if arg: > print "Discarding argument {!r}".format(arg) > return f() > > wrapped.__doc__ = f.__doc__ > wrapped.__name__ = f.__name__ class_._add_method("do_" + > f.__name__, wrapped) > return f > > @classmethod def _add_method(class_, methodname, method): > if hasattr(class_, methodname): > raise ValueError("Duplicate command > {!r}".format(methodname)) > setattr(class_, methodname, method) > > command = Cmd.install_command > > @command def install_java(): > "Install Java" > print "Installing Java" > > @command def install_tomcat(): > "Install Tomcat" > print "Installing Tomcat" > > if __name__ == "__main__": > Cmd().cmdloop()
To be honest I prefer the "if X do Y" approach for readability but a dictionary can be undated dynamically & used to automatically create the menu so it can have its place -- I'll see you... on the dark side of the moon... -- Pink Floyd -- http://mail.python.org/mailman/listinfo/python-list