Providing 'default' value with raw_input()?

P

planetthoughtful

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?

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.

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

Many thanks and much warmth,

planetthoughtful
 
K

keirr

planetthoughtful said:
I'm wondering if it's possible, using raw_input(), to provide a
'default' value with the prompt?
def get_input_with_default(default, prompt=">>> "):
result = raw_input('['+str(default)+'] '+str(prompt))
if result == "": result = default
return default
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.
I think it is the editing part that is going to give you a hard time.
curses and readline might be some help if you were on a Unix platform.
I can't think of any way to provided a editable value at the dos
prompt.

All the best,
Keir.
 
S

Steve Holden

planetthoughtful said:
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?

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.

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

Many thanks and much warmth,

planetthoughtful
You need to define your own function, with a default argument that gives
the value. You can make it work just like raw_input if no default value
is provided. Something like:
... if dflt:
... prompt = "%s [%s]: " % (prompt, dflt)
... res = raw_input(prompt)
... if not res and dflt:
... return dflt
... return res
...How many beans make five [5]: six
'six'How many beans make fiveten
'ten'How many beans make five [5]:
'5'

regards
Steve
 
P

planetthoughtful

Hi Steve,

As keir mentioned, my goal is to be able to edit the value returned
from a record stored in SQLite, so that it can be updated with the new
value.

To give a little background: as a learning exercise I'm writing a
command line app that will allow me to quickly capture todo items
(based on a similar concept used by an app for the Mac described on
43folders.com). I have the functionality working for adding todo items,
and listing items by various criteria, and updating the status of
items, but haven't included any functionality for being able to edit
items.

It seems, according to kier, that this simply can't be done via the
command line in DOS, which is a shame.

Sorry I didn't explain myself very well in my original post.

Much warmth,

planetthoughtful
 
N

Noah

So you are saying that something like this would not work for you?

current_record_value = get_value_in_database ('record_key')
new_record_value = raw_default ("Enter new record value",
current_record_value)
set_value_in_database ('record_key', new_record_value)

Maybe you are confusing this with TAB completion at the shell command
line.

I often use my own default_input function. I also add the ability to
HELP text
to the prompt, so if the user enters '?' then extra information is
printed.
Of course, that means

Yours,
Noah
 
K

keirr

planetthoughtful said:
It seems, according to keir, that this simply can't be done via the
command line in DOS, which is a shame.

Now, I said I couldn't think of a way to do it - not that it wasn't
possible :)
If you don't need you program to be portable you can use extensions -
in this case
I would expect you need readline for windows, and ctypes (because
readline for windows needs ctypes).

You can fetch readline from
http://sourceforge.net/project/showfiles.php?group_id=82407
and ctypes from
http://sourceforge.net/project/showfiles.php?group_id=71702

I can't promise these will work (all my python has to be 'pure' and
cross platform so I've never used readline or rlcompleter) but
functions like insert_text look to be in the right area for what (I
think) you want.
Good luck!

Keir.
 
P

planetthoughtful

Hi Noah,

I can't find any mention of a 'raw_default' function. So, lol, yes I'm
kind of saying that it would not work for me (well, it won't unless I
can find where / how you sources and implemented that function, bearing
in mind this will be running on Windows).

Many thanks and much warmth,

planetthoughtful
 
B

Bengt Richter

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.,
... 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:
...
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
 
P

planetthoughtful

Bengt said:
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.

Hi Bengt,

I think that would be a great solution if the value being 'edited' was
relatively short, or numeric, etc. But the values I want to 'edit' can
be several hundred characters long (ie they're text fields containing
todo notes), and using your method, I'd either accept the existing
value, or have to retype the text for that record. I think I mislead
people when I used the word 'default' -- I meant in the sense of being
able to edit the existing value, so that value, out of each record,
would be presented as the 'default', available for editing.

Sorry for the confusion.

Much warmth,

planetthoughtful
 
P

planetthoughtful

Hi Kier,

Any idea where I'd find documentation on using this extension? I've
downloaded and installed, but haven't had any luck finding docs for it.

Much warmth,

planetthoughtful
 
K

keirr

planetthoughtful said:
Hi Kier,

Any idea where I'd find documentation on using this extension? I've
downloaded and installed, but haven't had any luck finding docs for it.
As it's a windows version of the standard readline module (usually
available on Unix only)
I'd _guess_ that you could use the standard library readline
documenation, i.e. go to python.org and look up the readline module in
the library docs.

Cheers,

Keir.
 
K

Kent Johnson

planetthoughtful said:
I think that would be a great solution if the value being 'edited' was
relatively short, or numeric, etc. But the values I want to 'edit' can
be several hundred characters long (ie they're text fields containing
todo notes), and using your method, I'd either accept the existing
value, or have to retype the text for that record. I think I mislead
people when I used the word 'default' -- I meant in the sense of being
able to edit the existing value, so that value, out of each record,
would be presented as the 'default', available for editing.

For fields that long I think a GUI is more appropriate than trying to use command-line
editing. You might take a look at easygui - it's textbox is readonly but it looks like it
wouldn't be hard to make it editable - or learn enough Tkinter to do it yourself.
http://www.ferg.org/easygui/

Kent
 
R

Roger Upole

If you have Pywin32 build 205 installed, you can use the
win32console module to add the data to the typeahead
buffer before you call raw_input.

import win32console
stdin=win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)

def raw_input_with_default(prompt, default_val):
keypresses=[]
for c in default_val:
evt=win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
evt.Char=unicode(c)
evt.RepeatCount=1
evt.KeyDown=True
keypresses.append(evt)
stdin.WriteConsoleInput(keypresses)
return raw_input(prompt)

data=raw_input_with_default('modify this: ','some data')
print data

hth
Roger
 
B

Bengt Richter

Hi Bengt,

I think that would be a great solution if the value being 'edited' was
relatively short, or numeric, etc. But the values I want to 'edit' can
be several hundred characters long (ie they're text fields containing
todo notes), and using your method, I'd either accept the existing
value, or have to retype the text for that record. I think I mislead
people when I used the word 'default' -- I meant in the sense of being
able to edit the existing value, so that value, out of each record,
would be presented as the 'default', available for editing.

Sorry for the confusion.
If you want to edit text, maybe the best thing is a text editor?
Why not write it into a temp file and start the user's favorite editor
on it, and when done, read the file back into python and delete the temp.
Maybe check whether any changes actually happened before updating the DB.

os.popen{2,3,4} and tempfile module might help.

Regards,
Bengt Richter
 
A

Alex Martelli

Bengt Richter said:
If you want to edit text, maybe the best thing is a text editor?
Why not write it into a temp file and start the user's favorite editor

Agreed. There's a recipe for that in the online Python Cookbook, and we
edited and enhanced that into the 2nd edition of the printed (O'Reilly)
Python Cookbook, too.


Alex
 
P

planetthoughtful

My intention is to build a GUI for this app, yes, but given that I'm
about a week old in my learning of Python, I thought a command-line app
was a better place to start. I'm actually quite surprised at how
featured I've managed to make this app all things considered, and now
I'm running into things that aren't easy to do in Python (and probably
also not easy to do in any scripting language on a Win machine), as
opposed to not easy for me to work out.

I had thought to build GUIs in wxPython - is Tkinter any easier to
learn?

Much warmth,

planetthoughtful
 
P

planetthoughtful

Thank you for the suggestion, I'll have a look at this as an
alternative.

I must admit, it seems a little like a 'kludge', though -- but probably
a necessary one, given the limitations of the OS.

I'm assuming os.popen() keeps track of when the editor closes? Or would
I have to manually fire an 'ok, now update the record in the db' event
after editing the value?

Much warmth,

planetthoughtful
 
A

Alex Martelli

planetthoughtful said:
Thank you for the suggestion, I'll have a look at this as an
alternative.

I must admit, it seems a little like a 'kludge', though -- but probably
a necessary one, given the limitations of the OS.

Hmmm, what OS? The recipe I mentioned is probably the best approach on
Windows, MacOS, Linux, and other Unix variants -- what other OS do you
have in mind, that would let you submit to the user hundreds of
characters for editing without in fact using an editor?
I'm assuming os.popen() keeps track of when the editor closes? Or would

It has to, because it needs to supply all the subprocess's output as the
contents of the file object it returns, and it couldn't be sure it has
all of the output until the subprocess has finished. There are, of
course, other ways to control sub-processes (Python 2.4's subprocess
module, in particular).
I have to manually fire an 'ok, now update the record in the db' event
after editing the value?

In some situations it may be impractical to rely on the editor closing;
for example, the user's favorite editor might be a multitab one that's
big, heavy, and slow to start, so that the user doesn't close the whole
process but rather just a specific tab. In such cases, unless you can
build in some hook specific to the user's favorite editor (so you can
know when a specific tab/file is done getting edited), you may end up
requiring the user to press enter at your prompt to indicate he or she's
done editing, or some such semi-kludge. I cannot think of a
sufficiently general solution, given the variety of editors around, to
just magically divine the crucial "done with editing" condition...


Alex
 
S

Scott David Daniels

planetthoughtful said:
...
I had thought to build GUIs in wxPython - is Tkinter any easier to
learn?

I certainly found Tkinter easier. There are a couple of good tutorials
(and there is always the Grayson book) on the web to get started. What
is easiest to learn is (in many cases) a property of the student,
however. Were I a Linux-only GPL kind of a guy, I think Qt might be
an interesting way to go. One thing that helps tremendously in learning
Tkinter: using Idle in single-process mode:

C:\Python24\Python C:\Python24\Lib\idlelib\idle.pyw -n

This is obviously a WinXX example, but the "-n" parameter to idle is
the important part. Since a single-process Idle is running the Tkinter
GUI loop, you can try operations a step at a time (letting you see what
happens).

--Scott David Daniels
(e-mail address removed)
 
P

planetthoughtful

Hi Roger,

This is exactly what I was looking for!

Thank you so much!

I now have a fully functioning command-line todo app.

Anyone interested in why I picked that as my 2nd-ever-Python-app might
like to read the post over at 43folders.com about suggested uses for
Quicksilver on the Mac (http://www.43folders.com/2005/11/21/qs-redux/).
I wasn't aware of anything similar on Windows, so it seemed like a good
opportunity to build something with similar (and, in fact, better)
functionality (at least in terms of the 43folders.com use for
Quicksilver) using Python.

Anyway, thanks again -- very much appreciate everyone's input!

Much warmth,

planetthoughtful
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top