Getting an input without hitting enter

AutoPython 0 Tallied Votes 7K Views Share

!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]))
lllllIllIlllI 178 Veteran Poster

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

commented: True +3
AutoPython 5 Junior Poster

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

pythopian 10 Junior Poster in Training

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.

AutoPython 5 Junior Poster

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.

pythopian 10 Junior Poster in Training

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. :-/

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

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.

pythopian 10 Junior Poster in Training

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?

AutoPython 5 Junior Poster

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.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

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") )
e-papa commented: straight to the point. +3
e-papa 13 Posting Pro in Training

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

TrustyTony 888 ex-Moderator Team Colleague Featured Poster

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

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.