How to timeout when waiting for raw_input from user ?

N

northof40

Hi - I'm writing a *very* simple program for my kids. It asks the user
to give it the answer to a maths question and says "right" or "wrong"

They now want a timed version where they would only get so long to
respond to the question.

I'm thinking of some logic where a raw_input call is executed and then
if more than X seconds elapses before the prompt is replied to the
process writes a message "Sorry too slow" (or similar).

I can't see the wood for the trees here - what's the best way to do
this given the rather simple environment it's needed within.

Regards

richard.
 
N

northof40

Hi - I'm writing a *very* simple program for my kids. It asks the user
to give it the answer to a maths question and says "right" or "wrong"

They now want a timed version where they would only get so long to
respond to the question.

I'm thinking of some logic where a raw_input call is executed and then
if more than X seconds elapses before the prompt is replied to the
process writes a message "Sorry too slow" (or similar).

I can't see the wood for the trees here - what's the best way to do
this given the rather simple environment it's needed within.

Regards

richard.

Sorry I should said that based upon other answers I've seen to similar
questions this needs to run on a windows machine (other answers
suggest this is more difficult than running on *nix)
 
M

Maxim Khitrov

Sorry I should said that based upon other answers I've seen to similar
questions this needs to run on a windows machine (other answers
suggest this is more difficult than running on *nix)

Simplest solution I could come up with. This is indeed much easier on
*nix (just use select.select on sys.stdin with a timeout).

---
from msvcrt import getch, kbhit, putch
from time import sleep, time

ans = ''
end = time() + 5

print('2 + 2 = ?')

while True:
while time() < end:
if kbhit():
break
else:
sleep(0.001)
else:
ans = None
break

char = getch()
if char == '\r':
print('')
break
ans += char
putch(char)

if ans is None:
print('\nSorry too slow')
else:
try:
print('right' if int(ans) == 4 else 'wrong')
except:
print('not a number')
 
P

Paul Rubin

northof40 said:
I'm thinking of some logic where a raw_input call is executed and then
if more than X seconds elapses before the prompt is replied to the
process writes a message "Sorry too slow" (or similar).

The simplest way to do this is with the alarm function and a signal
handler. See the docs for the signal module.
 
N

northof40

Simplest solution I could come up with. This is indeed much easier on
*nix (just use select.select on sys.stdin with a timeout).

---
from msvcrt import getch, kbhit, putch
from time import sleep, time

ans = ''
end = time() + 5

print('2 + 2 = ?')

while True:
        while time() < end:
                if kbhit():
                        break
                else:
                        sleep(0.001)
        else:
                ans = None
                break

        char = getch()
        if char == '\r':
                print('')
                break
        ans += char
        putch(char)

if ans is None:
        print('\nSorry too slow')
else:
        try:
                print('right' if int(ans) == 4 else 'wrong')
        except:
                print('not a number')

That's really great - thanks. I've never looked at the whole msvcrt
module before - it looks like it could be useful ... at least for
windows programmes.

Thanks again.

R.
 
N

northof40

The simplest way to do this is with the alarm function and a signal
handler.  See the docs for the signal module.

Hi Paul - Thanks for your reply. Unfortunately it seems like the bit
of the signal module I would need for this is not implemented for
windows (AttributeError: 'module' object has no attribute 'SIGALRM').
Still no matter when I asked the question I couldn't even figure out
what module might provide this functionality for any platform so it
was useful knowledge for the future. Thanks again.

regards

Richard.
 
R

Rune Strand

The easiest wasy is to use the Timer object in the threading module.


from threading import Timer
 
R

Rune Strand

Doesn't work on Windows.

- Max

Yes, it does. I've used it a lot, also in Py2Exe apps. Try the
documentation example yourself

def hello():
print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
 
M

Maxim Khitrov

Yes, it does. I've used it a lot, also in Py2Exe apps.  Try the
documentation example yourself

def hello():
   print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed

I'm not talking about the Timer, I'm talking about the original
question. There's nothing (that I know of) you can do with a Timer on
Windows to interrupt a raw_input call.

- Max
 
Z

zeph

Here's what I came up with, though it only asks once question then
quits depending on the answer or lack thereof. And while, yes, you
can't interrupt a raw_input call from a timer, providing for a blank
line (user hitting enter) is a way around it:

import threading import Timer
from random import randrange
import sys

def multiply_game():
a = randrange(1,10)
b = randrange(1,10)
answer = raw_input('what is %s * %s?: ' % (a,b))
if not answer:
return
timer.cancel()
if str(answer) == str(a * b):
print 'right! :D'
else:
print 'wrong :('

def tooslow():
print "\ntoo slow :(\nHit ENTER to quit"

timer = Timer(30, tooslow) # 30 seconds
timer.start()
multiply_game()
 
R

Rune Strand

I'm not talking about the Timer, I'm talking about the original
question. There's nothing (that I know of) you can do with a Timer on
Windows to interrupt a raw_input call.

That is true. But if the issue here is to present a question, and
await answer for N seconds, before pusing next question, Timer() can
be used to call SendKeys() and have it send "{ENTER}" to raw_input.

http://www.rutherfurd.net/python/sendkeys/index.html

SendKeys is Win-only
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top