How to set a default editable string for raw_input?

PythonInputRaw Input

Python Problem Overview


I'm using Python 2.7's raw_input to read from stdin.

I want to let the user change a given default string.

Code:

i = raw_input("Please enter name:")

Console:

Please enter name: Jack

The user should be presented with Jack but can change (backspace) it to something else.

The Please enter name: argument would be the prompt for raw_input and that part shouldn't be changeable by the user.

Python Solutions


Solution 1 - Python

You could do:

i = raw_input("Please enter name[Jack]:") or "Jack"

This way, if user just presses return without entering anything, "i" will be assigned "Jack".

Solution 2 - Python

Python2.7 get raw_input and set a default value:

Put this in a file called a.py:

import readline
def rlinput(prompt, prefill=''):
   readline.set_startup_hook(lambda: readline.insert_text(prefill))
   try:
      return raw_input(prompt)
   finally:
      readline.set_startup_hook()

default_value = "an insecticide"
stuff = rlinput("Caffeine is: ", default_value)
print("final answer: " + stuff)

Run the program, it stops and presents the user with this:

el@defiant ~ $ python2.7 a.py
Caffeine is: an insecticide

The cursor is at the end, user presses backspace until 'an insecticide' is gone, types something else, then presses enter:

el@defiant ~ $ python2.7 a.py
Caffeine is: water soluable

Program finishes like this, final answer gets what the user typed:

el@defiant ~ $ python2.7 a.py 
Caffeine is: water soluable
final answer: water soluable

Equivalent to above, but works in Python3:

import readline    
def rlinput(prompt, prefill=''):
   readline.set_startup_hook(lambda: readline.insert_text(prefill))
   try:
      return input(prompt)
   finally:
      readline.set_startup_hook()

default_value = "an insecticide"
stuff = rlinput("Caffeine is: ", default_value)
print("final answer: " + stuff)

More info on what's going on here:

https://stackoverflow.com/a/2533142/445131

Solution 3 - Python

In dheerosaur's answer If user press Enter to select default value in reality it wont be saved as python considers it as '' string so Extending a bit on what dheerosaur.

default = "Jack"
user_input = raw_input("Please enter name: %s"%default + chr(8)*4)
if not user_input:
	user_input = default

Fyi .. The ASCII value of backspace is 08

Solution 4 - Python

I only add this because you should write a simple function for reuse. Here is the one I wrote:

def default_input( message, defaultVal ):
    if defaultVal:
        return raw_input( "%s [%s]:" % (message,defaultVal) ) or defaultVal
    else:
        return raw_input( "%s " % (message) )

Solution 5 - Python

On platforms with readline, you can use the method described here: https://stackoverflow.com/a/2533142/1090657

On Windows, you can use the msvcrt module:

from msvcrt import getch, putch

def putstr(str):
    for c in str:
        putch(c)

def input(prompt, default=None):
    putstr(prompt)
    if default is None:
        data = []
    else:
        data = list(default)
        putstr(data)
    while True:
        c = getch()
        if c in '\r\n':
            break
        elif c == '\003': # Ctrl-C
            putstr('\r\n')
            raise KeyboardInterrupt
        elif c == '\b': # Backspace
            if data:
                putstr('\b \b') # Backspace and wipe the character cell
                data.pop()
        elif c in '\0\xe0': # Special keys
            getch()
        else:
            putch(c)
            data.append(c)
    putstr('\r\n')
    return ''.join(data)

Note that arrows keys don't work for the windows version, when it's used, nothing will happen.

Solution 6 - Python

For windows users with gitbash/msys2 or cygwin you can use it's built in readline through python subprocess. It is a sort of hack but works quite well and doesn't require any third party code. For personal tools this works really well.

Msys2 specific: If you want ctrl+c to immediately exit, you will need to run your program with
winpty python program.py

import subprocess
import shlex

def inputMsysOrCygwin(prompt = "", prefilled = ""):
    """Run your program with winpty python program.py if you want ctrl+c to behave properly while in subprocess"""
    try:
        bashCmd = "read -e -p {} -i {} bash_input; printf '%s' \"$bash_input\"".format(shlex.quote(prompt), shlex.quote(prefilled))
        userInput = subprocess.check_output(["sh", "-c", bashCmd], encoding='utf-8')
        return userInput
    except FileNotFoundError:
        raise FileNotFoundError("Invalid environment: inputMsysOrCygwin can only be run from bash where 'read' is available.")

userInput = ""
try:
    #cygwin or msys2 shell
    userInput = inputMsysOrCygwin("Prompt: ", "This is default text")
except FileNotFoundError:
    #cmd or powershell context where bash and read are not available 
    userInput = input("Prompt [This is default text]: ") or "This is default text"

print("userInput={}".format(userInput))

Solution 7 - Python

Try this: raw_input("Please enter name: Jack" + chr(8)*4)

The ASCII value of backspace is 08.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionifschleifeView Question on Stackoverflow
Solution 1 - PythoncodefreakView Answer on Stackoverflow
Solution 2 - PythonEric LeschinskiView Answer on Stackoverflow
Solution 3 - PythonAnujView Answer on Stackoverflow
Solution 4 - PythonchubbsondubsView Answer on Stackoverflow
Solution 5 - PythonquantumView Answer on Stackoverflow
Solution 6 - PythonWill BenderView Answer on Stackoverflow
Solution 7 - PythondheerosaurView Answer on Stackoverflow