I have a project that involves asking for (for now, command-line) feedback from the user every so often while its main method runs.
So far I have been using input('{my_prompt}') to obtain this input from my user, but I have to quite annoyingly handle user input every time I invoke input(). This makes my code balloon to > 5 lines of code per user input line, which feels quite excessive. Some of my user input handling includes the below.
if input.lower() not in ['y', 'n']:
raise ValueError('Not valid input! Please enter either "y" or "n"')
if input.lower() == 'y':
input = True
else:
input = False
The above could be handled in 1 line of code if the user were passing command line arguments in and I could use argparse, but unfortunately the sheer volume of prompts prevents command line arguments from being a viable option.
I am familiar with the libraries cmd and click, but as far as I can tell, they both lack the functionality that I would like from argparse, which is namely to validate the user input.
In summary, I'm looking for a user input library that validates input and can return bool values without me having to implement the conversion every time.
If all you need is to check "yes/no" prompts, click supports it natively with click.confirm:
if click.confirm("Do you want to do this thing?"):
# ... do something here ....
There are a variety of other input-handling functions part of click, which are documented in the User Input Prompts section of the documentation.
Related
I have a python script that runs and accepts user input to make decisions. Based on the input I would like to give the user control of the python repl. Here is an example:
def func():
# hand over control to the user
breakpoint()
while True:
print('What would you like to do?\nq: quit\ni: interact')
i = input()
if i=='q':
break
elif i=='i':
func()
else:
print(f'invalid command: {i}')
Calling this code snippet with for example ipython3, the user is prompted for input. When the user presses i, func() is called, at which point I would like the user to be able to type python commands such as print(i).
My current best solution is to then set a breakpoint, the user may then need to type r to get to the right frame and then must then type interact. This is nearly acceptable, but I would like my user to not need to know that I'm using a debugger to give them interactive control, rather I would like them to be given an ipython prompt directly.
I looked at this post from 10 years ago: Jump into a Python Interactive Session mid-program? rz.'s comment looks interesting, but it looks like too much has changed for me to use his answer as is, plus there may be newer ways of doing things.
Python3: I'm trying to allow a user a given amount of time to enter a response into an input, but after a given amount of time if they haven't entered anything, I want to abort the input and assign a default value to the variable that is storing the input, or otherwise feed default values into the input statement after the given time period.
I've tried this:
from threading import Timer
timeout = 2
t = Timer(timeout, print, ["\nSorry, time is up"])
t.start()
answer = input("You have 2 seconds to answer:")
t.cancel()
print(answer)
from a different stack overflow post, but the problem is that the interpreter still prompts the user for input even after the final line is executed and answer is printed, and this won't work for what I'm trying to do (essentially, a command line game that needs to keep going when the player isn't giving it input but update when it does receive input).
What is the best way to do this? I know python doesn't really have a timeout function or something like that, but is there any way to achieve this via system commands or a module?
There are several plausible approaches (some of which are probably Unix-specific):
Read the input in a subprocess that can be killed after the timeout. (Many functions, including subprocess.run, accept a timeout parameter to automate this.)
Use alarm or similar to send your own process a signal (and install a signal handler that throws an exception).
Have another thread close the descriptor being read after the timeout; this sounds drastic but is generally said to work, so long as you don’t accidentally open a file on the closed descriptor before restoring it with dup2.
Read the input with lower-level facilities like non-blocking read and select—which will unfortunately disable nice things like readline.
In any case, you have to decide what to do with incomplete but non-empty input entered before the timeout. The terminal driver will likely transfer it invisibly to the next input prompt by default.
Using a select call may be a easier way.
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], [], [], 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
Refer to Keyboard input with timeout?
I've been working in my spare time on a simple game using pygame to allow me to get familiar with its code. The game I am making is a abstraction of a Four in a Row game which implements maths questions. To get the user's answer I am using a module called pygame_textinput. However, I am struggling to extract the user's answer which I want to then be able to compare to the correct answer, which will allow the user to place their disk in the grid.
The code for this I have is:
mathsanswer = pygame_textinput.TextInput()
This is outside of the main loop which I then call upon in the code below.
mathsanswer.update(events) #Check if user has inputted text
display.blit(mathsanswer.get_surface(), (600,725))
This part of the code works perfectly as the text the user types is displayed on screen.
However when I try to extract what the user has typed I get:
<pygame_textinput.TextInput object at 0x00000219C1F101D0>
Is there a way to get what the user has typed as the variable.
Thanks for any help.
Try this.. you need to use get_text() to get the input.
To catch the user input after the user hits Return, simply evaluate the return value of the update()-method - it is always False except for when the user hits Return, then it's True. To get the inputted text, use get_text(). Example:
if mathsanswer.update(events):
print(mathsanswer.get_text())
I do not know how to ask a user for input giving him a hint at the same time.
When I use raw_input("some description") a small window pops up and the user must enter something, as the input is completely empty. How to achieve the same, but with something already written to the input box (a hint for the user, which he/she could accept or simply change it)?
This has been answered before:
https://stackoverflow.com/a/2533142/1217949
The standard library functions input() and raw_input() don't have this functionality. If you're using Linux you can use the readline module to define an input function that uses a prefill value and advanced line editing:
def rlinput(prompt, prefill=''):
readline.set_startup_hook(lambda: readline.insert_text(prefill))
try:
return raw_input(prompt)
finally:
readline.set_startup_hook()
'lo,
I am currently trying to code a simple routine for an experiment we are planning to run. The experiment starts by entering a subject number and creating a bunch of files. I got that part working. Next, we want the screen to go blank and display a message. Something like 'Please fill in questionnaire 1 and press [ENTER] when you are done.'
My question is, how do you recommend I present a blank screen with a message like that that waits for a certain key to be pressed?
I have quite some programming experience but haven't worked with Python before so any hints are greatly appreciated. Thanks a lot in advance for your time!
~~~~~~~~~~~~~~~~~~
Some extra info that might be relevant: We are running this on Windows XP (Service Pack 2) computers. The whole point of this is that the participant does not have access to the desktop or anything on the computer basically. We want the experiment to start and display a bunch of instructions on the screen that the subject has to follow without them being able to abort etc. Hope this makes sense.
If you're in python 2, use raw_input().
If you're using python 3, use input().
You can prompt the user for information and store the result as a string.
in python 2.x
response = raw_input("What would you like to do next?")
in python 3.x
response = input("What would you like to do next?")
On windows, you can use functions in the msvcrt module. For example, kbhit() waits until the user presses a key.
To print the blank screen before putting the prompt, I used the following
import os
import sys
VALIDINPUT = '0'
while VALIDINPUT == '0':
p = os.popen('clear')
for line1 in p.readlines():
print line1
<put the logic for reading user input here>
<put the logic to check for valid user input here and if the user input is valid, then
assign 1 to VALIDINPUT>
This will show a blank screen and the prompt until the user provides a valid input.
Hope this helps. I used this on Linux.
raw_input('Please fill in questionnaire 1 and press [ENTER] when you are done.') will wait for someone to hit [enter].
Clearing the screen may be OS/environment dependent, I am not sure.