How to timeout when waiting for raw_input from user ?

Discussion in 'Python' started by northof40, Dec 4, 2009.

  1. northof40

    northof40 Guest

    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.
    northof40, Dec 4, 2009
    #1
    1. Advertising

  2. northof40

    northof40 Guest

    On Dec 5, 12:52 pm, northof40 <> wrote:
    > 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)
    northof40, Dec 4, 2009
    #2
    1. Advertising

  3. On Fri, Dec 4, 2009 at 6:55 PM, northof40 <> wrote:
    > On Dec 5, 12:52 pm, northof40 <> wrote:
    >> 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)
    >


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

    - Max
    Maxim Khitrov, Dec 5, 2009
    #3
  4. northof40

    Paul Rubin Guest

    northof40 <> writes:
    > 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.
    Paul Rubin, Dec 5, 2009
    #4
  5. northof40

    northof40 Guest

    On Dec 5, 2:44 pm, Maxim Khitrov <> wrote:
    > On Fri, Dec 4, 2009 at 6:55 PM, northof40 <> wrote:
    > > On Dec 5, 12:52 pm, northof40 <> wrote:
    > >> 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)

    >
    > 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')
    > ---
    >
    > - Max


    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.
    northof40, Dec 5, 2009
    #5
  6. northof40

    northof40 Guest

    On Dec 5, 6:23 pm, Paul Rubin <> wrote:
    > northof40 <> writes:
    > > 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.


    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.
    northof40, Dec 5, 2009
    #6
  7. northof40

    Rune Strand Guest

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


    from threading import Timer
    Rune Strand, Dec 5, 2009
    #7
  8. On Sat, Dec 5, 2009 at 9:01 AM, Rune Strand <> wrote:
    > The easiest wasy is to use the Timer object in the threading module.
    >
    >
    > from threading import Timer


    Doesn't work on Windows.

    - Max
    Maxim Khitrov, Dec 5, 2009
    #8
  9. northof40

    Rune Strand Guest

    On Dec 5, 3:07 pm, Maxim Khitrov <> wrote:
    >
    > 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
    Rune Strand, Dec 5, 2009
    #9
  10. On Sat, Dec 5, 2009 at 9:11 AM, Rune Strand <> wrote:
    > On Dec 5, 3:07 pm, Maxim Khitrov <> wrote:
    >>
    >> 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


    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
    Maxim Khitrov, Dec 5, 2009
    #10
  11. northof40

    MrJean1 Guest

    Try using the function timelimited from this recipe

    <http://code.activestate.com/recipes/576780/>

    An (untested) example with a 60 second timeout would be:

    try:
    r = timelimited(60, raw_input, 'enter right or wrong: ')
    except TimeLimitExpired:
    ....
    except KeyboardInterrupt:
    ....

    /Jean


    On Dec 4, 3:52 pm, northof40 <> wrote:
    > 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.
    MrJean1, Dec 5, 2009
    #11
  12. northof40

    zeph Guest

    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()
    zeph, Dec 5, 2009
    #12
  13. northof40

    Rune Strand Guest

    On Dec 5, 3:42 pm, Maxim Khitrov <> wrote:

    > 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
    Rune Strand, Dec 6, 2009
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. QDL
    Replies:
    0
    Views:
    311
  2. caocheng
    Replies:
    0
    Views:
    325
    caocheng
    Apr 9, 2006
  3. Replies:
    3
    Views:
    447
  4. Mark Probert

    Timeout::timeout and Socket timeout

    Mark Probert, Oct 6, 2004, in forum: Ruby
    Replies:
    1
    Views:
    1,271
    Brian Candler
    Oct 6, 2004
  5. Simon_21

    Client side waiting & timeout

    Simon_21, May 2, 2008, in forum: Javascript
    Replies:
    1
    Views:
    105
    Thomas 'PointedEars' Lahn
    May 2, 2008
Loading...

Share This Page