Providing 'default' value with raw_input()?

Bengt Richter bokr at oz.net
Thu Dec 22 14:30:39 EST 2005


On 22 Dec 2005 08:55:17 -0800, "planetthoughtful" <planetthoughtful at gmail.com> wrote:

>Hi All,
>
>As always, my posts come with a 'Warning: Newbie lies ahead!'
>disclaimer...
>
>I'm wondering if it's possible, using raw_input(), to provide a
>'default' value with the prompt?
Sure, depending on what you mean ;-)
You can only get a prompt string printed to the screen with raw_input,
but you can build that string any way you want, so it can show e.g.,
User-friendly prose and the current value and a default value and anything else.

Then the user has to enter zero or more characters and press Enter.
Whether something changes value or not, and what value is used, depends on
what the program does with the string (possibly empty) that the user typed.

So you have to decide what user response should mean "change old value to default as shown"
and what should mean "make no change" and what should mean "convert the typed string to a value
and change the old value to that.

To have a user-friendly program, you won't want to make user errors too easy, and you
will probably want to have the program re-prompt if there is an input typo (or maybe
an input that converts ok but has bad business consequences (e.g., like that recent
Japanese stock sale switcheroo of price and number of shares that cost many megabucks).

>
>I would like to include the ability to edit an existing value (drawn
>from an SQLite table) using a DOS console Python app, but my gut
>feeling from reading what I can find about raw_input() is that it only
>allows you to provide a prompt, not a default value as well.
>
What's wrong with showing the default in the prompt itself? The thing is
what user input in response should signify the default? E.g., maybe a single
period by itself could mean "use the default" and nothing could mean "no change"
and other input would be a new value.

>If anyone can give me any advice on how I might achieve this, I would
>be immensely appreciative!

suppose you had some named values in one dict, e.g.,

 >>> for name, price in values.items():
 ...     while True: # retry until satisfied
 ...         uresp = raw_input(
 ...             '\n'
 ...             'Current price of %s is $%.2f %s\n'
 ...             'Press Enter to leave as is, or\n'
 ...             'type "D" (without quotes) followed by Enter to change price to %.2f,\n'
 ...             'or enter a new value: ' % (name, price, info[name][0], info[name][1]))
 ...         if not uresp: break
 ...         if uresp=='D': values[name] = info[name][1]; break
 ...         else:
 ...             try: values[name] = type(values[name])(uresp); break
 ...             except Exception, e:
 ...                 print '%s: %s'%(e.__class__.__name__, e)
 ...                 print 'Try again'
 ...
 
 Current price of yoghurt is $0.90 each
 Press Enter to leave as is, or
 type "D" (without quotes) followed by Enter to change price to 1.19,
 or enter a new value: D
 
 Current price of banana is $0.79 per pound
 Press Enter to leave as is, or
 type "D" (without quotes) followed by Enter to change price to 0.99,
 or enter a new value:
 
 Current price of apple is $1.29 per pound
 Press Enter to leave as is, or
 type "D" (without quotes) followed by Enter to change price to 1.49,
 or enter a new value: 1..23
 ValueError: invalid literal for float(): 1..23
 Try again
 
 Current price of apple is $1.29 per pound
 Press Enter to leave as is, or
 type "D" (without quotes) followed by Enter to change price to 1.49,
 or enter a new value: 1.23
 >>>

Ok, now we can see what happened:

 >>> for name, price in values.items(): print '%10s: %.2f'%(name,price)
 ...
    yoghurt: 1.19
     banana: 0.79
      apple: 1.23
 
I'm not suggesting this as a pattern to follow, just to illustrate what you can do
with raw_input. IOW, it's about how you build the prompt string, and what you do
with the user response input string that solves your problem.

Voluminous prompts get old fast, so you might e.g. want to accept a '?' to get extra
context-sensitive info instead, followed by retry.

Regards,
Bengt Richter



More information about the Python-list mailing list