1

I am trying to make a timer (Python 3.6.0). I know there are other posts with simpler timers but I want to make a more complex timer. Here is my code:

import time

x = 0

run = input("Start timer? [Y]/[N]")
while run == 'Y':
    time.sleep(1)
    x += 1
    print(x)
else:
    print("end of code")

Is there a way to break the while loop (so that the timer can stop) while the program runs? If I put "in = input()" under the "x += 1" line so that the user can stop the loop, the timer stops counting because the user must provide input every second. If I run the above code without any kind of input I cannot type anything in the Python Shell because the loop keeps going. Is there any way to solve this problem?

Bram Fran
  • 113
  • 5
  • 11
  • You will need to use threading if you want code to execute while doing an input(). This can get quite complicated quite quickly. Are you sure this is what you need to do? – Stephen Rauch Jan 16 '17 at 17:37
  • http://stackoverflow.com/questions/3295938/else-clause-on-python-while-statement – Ostap Khl Jan 16 '17 at 17:38
  • See [here](http://stackoverflow.com/questions/40949738/implementing-a-timercountdown-that-runs-pararell-with-the-game-logic) which in itself is a duplicate, to help get you started. Note: the base duplicate by Alex Martelli seems to be in flux about working across different OS. – roganjosh Jan 16 '17 at 17:39
  • Another option which is overkill is to use something like pygame, so it'll record your key strokes and just check that during the loop – Peter Jan 16 '17 at 17:40
  • Or you can use `select` to wait for user input instead of sleeping like in this answer [here](http://stackoverflow.com/a/2904057/5992438) – bunji Jan 16 '17 at 17:43
  • Is there a way to check the input of the user without caring about how much the timer has counted? – Bram Fran Jan 16 '17 at 17:48
  • Yeah, it's the same principle, one thread is blocked waiting for `input`, the other keeps the timer going. But as @StephenRauch mentioned in the first comment, you might want to think about whether running threads is what you need here. For example, why can't you just use something like `start = datetime.datetime.now()` before the loop, and then check how much time elapsed once the loop is broken by taking the end time and subtracting `start`? – roganjosh Jan 16 '17 at 17:51
  • Thats an interesting idea. Can you post an answer on how the code should look like after this additon? – Bram Fran Jan 16 '17 at 17:56
  • I have added an answer I put together quickly but I have to go out right now. If you need some changes, I'll try respond when I'm back – roganjosh Jan 16 '17 at 18:05

1 Answers1

0

As discussed in comments, something like this might be suitable for you. I'm not quite sure what the timer is supposed to do whilst waiting for input but perhaps something like this helps.

import time

start_timer = input('Do you want to start the timer? Y / N: ')

if start_timer.lower() == 'y':
    print('Type N or n to break the loop')
    start = time.time()
    while start_timer.lower() != 'n':
        start_timer = input()

    end = time.time()
    print('Total loop time: {}'.format(end - start))
else:
    print('Ok, ending')

Edit: The only way to break out of the while loop is to type N or n (the use of .lower() will convert the input to n if it is N). The system time is recorded before entering the loop. The user can then type anything they want for as long as they want, except n. Typing n will then break the loop, the system time is taken again, and the difference between the start and end time is displayed. There is no need for a running timer, just the "before and after" times.

roganjosh
  • 12,594
  • 4
  • 29
  • 46
  • @BramFran I have changed the code slightly. Now there is only one way to break the loop, allowing the user to continue entering inputs provided that they don't match the input that is set to break the loop (`n` in this case). I also added an explanation. – roganjosh Jan 17 '17 at 12:50
  • This is exactly what I needed! Very clever soloution. – Bram Fran Jan 17 '17 at 12:55