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())
Related
New here and very novice in Python. I have a question about Python.
At my workplace, I have some trainings with PL/SQL, where our first task was create RPN calculator. Because I'm not that good in PL/SQL and syntax of that language is strange in my opinion, I made it in Python.
Everything worked smoothly, until a time when I was asked to create function to check if string of values are RPN. Just before that, I made simple program to check if entered values match with those in dictionary, but I stopped to Run.
AcceptedChars = ["0","1","2","3","4","5","6","7","8","9","+","-","/","*"," "]
def checking_for_rpn():
checking = str(input("Enter values for check: "))
for AcceptedCharsCheck in checking:
if not(AcceptedCharsCheck in AcceptedChars):
print("False")
return False
print("Ok")
return True
Then, I added some crazy codes from web for checking RPN and that's fricked my code.
Now, I canot run it by Run Module. Shell displays standard view when it's ready.
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.
Please mind that I am completely green in Python and I do not know how callbacks work in this language.
I have been trying for some time to solve my problem, but I cannot figure out what to do.
I have the problem with using callbacks in Python. I use the Python keyboard module to listen to keys pressed on a machine.
When I try to use the keyboard.hook() method, it asks me for a callback. I know how callbacks work, but as long as Python is not my main language I can't really figure out what to do with it.
In JavaScript it's as easy as naming a parameter in a function then printing that parameter. Easy as that.
import keyboard
keyboard.hook()
## How to print keys?
In the official documentation, it is written that the hook() method invokes a callback. How do I access this callback and most importantly print keys which are recorded from it? I just need a simple example then I will be able to remember it forever.
Any help really appreciated.
You can pass a function just like you would a variable—by passing its name to the hook() method.
Then, per the docs on keyboard.hook(), it calls your callback with a keyboard.KeyboardEvent with three fields:
name: an Unicode representation of the character (e.g. "&") or description (e.g. "space"). The name is always lower-case.
scan_code: number representing the physical key, e.g. 55.
time: timestamp of the time the event occurred, with as much precision as given by the OS.
So, putting it together, you can use it like this:
import keyboard
def my_keyboard_hook(keyboard_event):
print("Name:", keyboard_event.name)
print("Scan code:", keyboard_event.scan_code)
print("Time:", keyboard_event.time)
keyboard.hook(my_keyboard_hook)
# Block forever, so that the program won't automatically finish,
# preventing you from typing and seeing the printed output
keyboard.wait()
And each time a key is pressed, you'll print the details of the keyboard event.
Note that the keyboard.wait() call is not necessary if your program would otherwise continue running—I just wanted to make sure that you didn't run the example code, see it terminate immediately, and then think something went wrong.
Something like this appears to be what you want from the documentation.
def keyHook(info):
print(info)
keyboard.hook(keyHook)
'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.
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.