954,525 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?

Getting an input without hitting enter

0
By AutoPython on Nov 16th, 2009 1:59 am

!USING PYTHON 3.1!
USING WINDOWS

I never thought it could be so simple.
However I should have clarified that it's a 1 character input. But the general idea is the same. Someone suggested that I explain what is going on better, so I'm going to do that. The function 'getch()' waits for a keyboard hit. But the reason that it has to be converted so many times in the line '(str(list(str(getch()))[2]))' is because getch() has to be annoying and add a b(It's a nonetype) before everything, and to be even more annoying, it's not a string (grrr)... So we have to first convert the whole thing to a string, put it in a list, take the 3rd item from the list, which would be the character you pressed. Convert it back to a string, then print it.

from msvcrt import getch

while True:
    print (str(list(str(getch()))[2]))

You should probably document your code to explain what each bit is doing, like why you need the third item in the list, why it need to be converted so many times, and what getch() and msvrt are.

But other then that, good snippet

Paul Thompson
Veteran Poster
1,119 posts since May 2008
Reputation Points: 264
Solved Threads: 183
 

Thanks for the feed back! I never thought about documenting it that much, but why not. It's a small snippet.

AutoPython
Junior Poster
138 posts since Sep 2009
Reputation Points: 14
Solved Threads: 18
 

This is not that new. msvcrt.getch() was available on Windows with Python 2.5 already. Well, at least it was in the ActivePython distro. (Meaning: It's good news for pythoneers locked into older versions of Python.)

That said, a good example of a finer grained keyboard/console control compared to the more "traditional", "terminal"-oriented methods.

pythopian
Junior Poster in Training
81 posts since Nov 2009
Reputation Points: 20
Solved Threads: 25
 

I realized that it wasn't that new, but I just wanted to show everybody a simpler way of dong it, many versions of these are really long and clunky, and those aren't the ones I suggest you use. Especially the Tkinter ones. Blah, they stop working after you click the screen or anything else.

AutoPython
Junior Poster
138 posts since Sep 2009
Reputation Points: 14
Solved Threads: 18
 

Interestingly though, I just checked how it works with Py 2.5 on my Windows box, and the snippet crashed. It is because, in my context, getch() always returns a 1-char string.

It might be that the getch() behaviour has changed between msvcrt versions - either that of the python module, or that of the underlying MS C++ library on the system. That's irritating though, because AFAICT the Python folks are damn careful about braking interfaces. :-/

pythopian
Junior Poster in Training
81 posts since Nov 2009
Reputation Points: 20
Solved Threads: 25
 

In general, one ought to avoid platform specific code with a cross platform language like Python.

This code works only on Windows, the Tkinter approach may look mildly more complex, but it is cross platform.

vegaseat
DaniWeb's Hypocrite
Moderator
5,989 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 
In general, one ought to avoid platform specific code with a cross platform language like Python.

While I personally do favor platform-independent code, I wouldn't agree with that statement on absolute terms. There is at least one situation when it's perfectly OK to have platform specific code: In platform-specific implementations of a generic interface. Example: Python's getpass() function uses msvcrt in its implementation on Windows.

I'd extend the principle to"Don't use platform specific code if there is a platform independent alternative. If there is none, encapsulate the platform-specific code behind a designated module interface."

Back to the topic at hand: Any clue why the snippet fails in one context, while it is (obviously) working in AutoPython's case? Anybody?

pythopian
Junior Poster in Training
81 posts since Nov 2009
Reputation Points: 20
Solved Threads: 25
 

The reason Pythopian, is because in Python 2.5(and 2.6), getch() returns characters like 'a', 'e', '2', '(' etc. But in Python 3.1 it does b'a', b'3', b'5'. I was wondering if it was almost a bug.

AutoPython
Junior Poster
138 posts since Sep 2009
Reputation Points: 14
Solved Threads: 18
 

The C function getch() will return a byte string in Python3, so you have to decode it.

Something like that ...

# windows console only
# C:\Windows\System32\msvcrt.dll contains C functions

from msvcrt import getch

while True:
    # Python3 byte string to string
    print( getch().decode("utf8") )
vegaseat
DaniWeb's Hypocrite
Moderator
5,989 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

Wow, just saw this now really good of you. Thanks.

e-papa
Posting Pro in Training
465 posts since Mar 2011
Reputation Points: 23
Solved Threads: 4
 

Fro me the vegaseat's code does not function well, this version works from command line (not IDLE):

# windows console only
# C:\Windows\System32\msvcrt.dll contains C functions

from msvcrt import getch
mystring = c = ''
while c.lower() != 'q':
    c = getch().decode("cp437")
    print(c)
    mystring += c

print('Inputed string:', mystring)


This newer snippet of mine shows cross platform way with Tkinter: Tkinter for console getkey, Pause/Restart/Quit

pyTony
pyMod
Moderator
5,359 posts since Apr 2010
Reputation Points: 782
Solved Threads: 852
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: