Present blank screen, wait for key press -- how? - python

'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.

Related

Python command to jump into interactive mode from a script

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.

Why msvcrt.getch() is getting always same input without pressing any key on Windows

I am using Windows. I want take user input without pressing enter key and I found many examples, but somehow they are not working on me. I do not press any key and still msvcrt.getch() function is getting input(or atleast it is printing something) all the time. My code below:
import msvcrt
from time import sleep
while True:
print(msvcrt.getch())
sleep(1)
This is printing b'\xff' all the time. And if I press something, it does not care, it still print same string. I am using python 3.6
Problem solved. If using msvcrt: Code has to run in console. I was running that with IDLE.
https://www.reddit.com/r/learnpython/comments/3ji6ew/ordgetch_returns_255_constantly/
Thanks to ingolemo.

Obtaining a user input value with pygame_textinput module?

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())

Can I change where the raw_input cursor is when the program is running? - python

Can I change where the raw_input cursor is when the program is running?
For example, my code is:
print raw_input ("Please enter your last name..")
print (" Type now ..")
print raw_input ("please enter your first name..")
I want the "Type now" part to be in the lower part of the screen somewhere but the flashing | to remain after the "please enter your last name" part.
Oooo, while I am here, can someone paste me out the code that makes my | spin around? :D or impress me with something even more fancy?
There is no cross-platorm way to do this kind of "console GUI" functionality.
If you don't care about Windows, most other platforms have the curses module. It's a bit heavy-weight for what you want, but it can do everything you want and more.
Alternatively, if you only care about common terminals (ANSI control sequences, 80-character width, etc.), you can do it by sending explicit control sequences, or using wrapper libraries that do so on your behalf.
Or, if you only care about Windows, there are various different wrappers around conio on PyPI.
And as you may have guessed, the code to spin the cursor around depends on which library you used. Although you don't actually need full cursor movement functionality for that; you just need some way to read from the keyboard in raw mode. (You can do this on Windows with the msvcrt library, on Unix with the tty library and/or just using select on stdin.) Then, you just loop, waiting for a key with a timeout of, say, 0.1 seconds, and update the cursor if it times out.
Something like this:
cursor = itertools.repeat(r'|/-\')
while True:
if msvcrt.khbit():
return msvcrt.getwch()
msvcrt.putwch('\008')
msvcrt.putwch(next(cursor))
time.sleep(0.1)
while True:
for i in ["/","-","|","\","|"]:
print "%s\r" % i,

Avoiding raw_input to take keys pressed while in a loop for windows

I am trying to make a program which has a raw_input in a loop, if anyone presses a key while the long loop is running the next raw_input takes that as input, how do I avoid that?
I don't know what else to add to this simple question. Do let me know if more is required.
EDIT
Some code
for i in range(1000):
var = raw_input("Enter the number")
#.... do some long magic and stuff here which takes afew seconds
print 'Output is'+str(output)
So if someone presses something inside the magic phase, that is take as the input for the next loop. That is where the problem begins. (And yes the loop has to run for 1000 times).
This works for me with Windows 7 64bit, python 2.7.
import msvcrt
def flush_input():
while msvcrt.kbhit():
msvcrt.getch()
I put the OS in the title, window 7 64 bit to be specific. I saw the
answers there. They do apply but by god they are so big. Aren't there
other n00b friendly and safer ways to take inputs?
Let me try to explain why you need to do such an elaborate process. When you press a key it is stored in a section of computer memory called keyboard buffer (not to be confused with stdin buffer). This buffer stores the key's pressed until it is processed by your program. Python doesn't provide any platform independent wrapper to do this task. You have to rely on OS specific system calls to access this buffer, and flush it, read it or query it. msvcrt is a MS VC++ Runtime Library and python msvcrt provides a wrapper over it. Unless you wan't a platform independent solution, it is quite straight forward.
Use msvcrt getch to read a character from console. msvcrt.kbhit() to test if a key press is present in the keyboard buffer and so on. So as MattH has shown, it just a couple of lines code. And if you think you are a noob take this opportunity to learn something new.
Just collect your input outside of the loop (before you enter the loop). Do you really want the user to enter 1000 numbers? well maybe you do. but just include a loop at the top and collect the 1000 numbers at the start, and store them in an array.
then on the bottom half change your loop so it just does all the work. then if someone enters something no the keyboard, it doesn't really matter anymore.
something like this:
def getvars(top=1000):
vars = []
for i in range(0,top):
anum = int(raw_input('%d) Please enter another number: ' % i))
vars.append(anum)
return vars
def doMagic(numbers):
top = len(numbers)
for number in numbers:
# do magic number stuff
print 'this was my raw number %s' % number
if __name__ == "__main__":
numbers = getvars(top=10)
doMagic(numbers)
presented in a different sort of way and less os dependent
There is another way to do it that should work. I don't have a windows box handy to test it out on but its a trick i used to use and its rather undocumented. Perhaps I'm giving away secrets... but its basically like this: trick the os into thinking your app is a screensaver by calling the api that turns on the screensaver function at the start of your magic calculations. at the end of your magic calculations or when you are ready to accept input again, call the api again and turn off the screensaver functionality.
That would work.
There is another way to do it as well. Since you are in windows this will work too. but its a fair amount of work but not really too much. In windows, the window that is foreground (at the top of the Z order) that window gets the 'raw input thread'. The raw input thread receives the mouse and keyboard input. So to capture all input all you need to do is create a function that stands up a transparent or (non transparent) window that sits at the top of the Z order setWindowPos would do the trick , have it cover the entire screen and perhaps display a message such as Even Geduld or Please wait
when you are ready to prompt the user for more input, you use showwindow() to hide the window, show the previous results, get the input and then reshow the window and capture the keys/mouse all over again.
Of course all these solutions tie you to a particular OS unless you implement some sort of try/except handling and/or wrapping of the low level windows SDK calls.

Categories