3

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

Cédric Julien
  • 78,516
  • 15
  • 127
  • 132
Rick_2047
  • 302
  • 1
  • 4
  • 10
  • show us the code you're using, then it will be easier to help you – Cédric Julien Dec 21 '11 at 09:58
  • I can't exactly show the code, but let me show you something equivalent. – Rick_2047 Dec 21 '11 at 09:59
  • 1
    Possible Duplicate http://stackoverflow.com/questions/2520893/how-to-flush-the-input-stream-in-python. Please let us know your OS. Solution is very OS specific. – Abhijit Dec 21 '11 at 10:01
  • 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? – Rick_2047 Dec 21 '11 at 10:05

3 Answers3

3

This works for me with Windows 7 64bit, python 2.7.

import msvcrt

def flush_input():
  while msvcrt.kbhit():
    msvcrt.getch()
MattH
  • 37,273
  • 11
  • 82
  • 84
1

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.

Abhijit
  • 62,056
  • 18
  • 131
  • 204
1

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.

zel
  • 11
  • 2