Best method for a menu in a command line program?
Ben Finney
ben+python at benfinney.id.au
Wed Nov 3 22:03:47 EDT 2010
braden faulkner <brf256 at gmail.com> writes:
> I'm using a menu for my command line app using this method.
>
> choice = "foobar"
The default choice for a “nothing here yet” value is the built-in
‘None’.
Sometimes that's not the right choice; but if you have no particular
reaason in a specific program to avoid ‘None’ for that purpose, use it.
> while choice != "q":
> if choice == "c":
> temp = input("Celsius temperature:")
> print "Fahrenheit:",celsius_to_fahrenheit(temp)
> elif choice == "f":
> temp = input("Fahrenheit temperature:")
> print "Celsius:",fahrenheit_to_celsius(temp)
> elif choice != "q":
> print_options()
> choice = raw_input("option:")
Python lacks a ‘case’ statement. But it does have functions as
first-class objects; you can treat functions as data.
So your approach above, with a chain of if-elif-elif clauses, is best
replaced by a dispatch dictionary into functions specific to each
command.
Here's my attempt at making it more Pythonic and maintainable::
#! /usr/bin/python
# -*- coding: utf-8 -*-
import sys
import textwrap
def print_commands():
commands_display = ", ".join(commands.keys())
sys.stdout.write(textwrap.dedent("""\
Valid commands are: %(commands_display)s.
""") % vars())
def quit():
raise SystemExit()
def celsius_to_fahrenheit(in_value):
return ((in_value * (9.0/5) + 32.0))
def fahrenheit_to_celsius(in_value):
return ((in_value - 32.0) * (5.0/9))
def prompt_and_convert_temperature(labels, conversion_func):
(from_label, to_label) = labels
input = float(raw_input("%(from_label)s: " % vars()))
result = conversion_func(input)
sys.stdout.write("%(to_label)s temperature: %(result)0.2f\n" % vars())
commands = {
'q': (lambda: quit()),
'c': (lambda: prompt_and_convert_temperature(
["Celsius", "Fahrenheit"], celsius_to_fahrenheit)),
'f': (lambda: prompt_and_convert_temperature(
["Fahrenheit", "Celsius"], fahrenheit_to_celsius)),
}
if __name__ == '__main__':
choice = None
while choice is None:
choice = raw_input("Command: ")
if choice in commands:
commands[choice]()
else:
choice = None
print_commands()
--
\ “I am as agnostic about God as I am about fairies and the |
`\ Flying Spaghetti Monster.” —Richard Dawkins, 2006-10-13 |
_o__) |
Ben Finney
More information about the Python-list
mailing list