-3

I'm currently making a stopwatch function, where the user has to input 1 to start and 2 to stop the stopwatch. I'm wondering how to implement the stop function when the while loop is going on as whatever I tried didn't work.

This is the stopwatch code I'm working on:

second = 0
minute = 0
hour = 0
millisecond = 0

start = input("Press 1 to start and 2 to stop: ")

while True:
if start == "2":
  break
else:
  print("%02d : %02d : %02d "%(hour, minute, second,))
  time.sleep(1)
  second += 1
  if second == 60:
   minute += 1
   second -= 60
   if minute == 60:
      hour += 1
      minute -= 60
Frightera
  • 4,773
  • 2
  • 13
  • 28
yes
  • 1
  • 1
  • 1
    try `ctrl+c` to stop it – leaf_yakitori Jun 18 '21 at 06:43
  • Because `input` blocks until the user types something, the only way to do this is to use threading. You could create a thread to print your countdown, have the main thread block on an `input` call , and signal the thread to stop. – Tim Roberts Jun 18 '21 at 06:53
  • @TimRoberts how will I make this threading work? – yes Jun 18 '21 at 12:48
  • Does this answer your question? [How to kill a while loop with a keystroke?](https://stackoverflow.com/questions/13180941/how-to-kill-a-while-loop-with-a-keystroke) – Lenormju Jun 18 '21 at 13:32
  • You should Google `python threading`. It's not really very hard. The only trick is you can't force the thread to exit; you need to set a global flag that the thread checks on its own. – Tim Roberts Jun 18 '21 at 20:50

2 Answers2

1

input is blocking until the user types something (and hit enters).
So if you put it in your while loop, the user will get asked repeatedly if he wants to stop, each time pausing the clock, it is not what is expected.
But if you put the input outside the loop (it is strange that you do that), then the user is never asked to type something until the loop ends (which is never).
It means that in your case, input is not a solution.

There is a very similar question which has an accepted answer (slightly adapted to your case) :

try:
    while True:
        print("%02d : %02d : %02d "%(hour, minute, second,))
        ...
except KeyboardInterrupt:
    # here the loop has definitely stopped
    ...

which works with Ctrl+C, being a standard way to signal the program to stop something.

If you want to use something other than Ctrl+C, there are other questions here on StackOverflow that could fit your needs :

Your question is thus a duplicate of one of these.

Lenormju
  • 4,078
  • 2
  • 8
  • 22
0

Here's a threading example that does what you describe.

import time
import threading

thread_live = False

def countdown():
    seconds = 0;
    while thread_live:
        hour = seconds // 3600
        minute = (seconds // 60) % 60
        second = seconds % 60
        print("%02d:%02d:%02d "%(hour, minute, second))
        seconds += 1
        time.sleep(1)
    print("exiting")


while True:
    start = input("Press 1 to start and 2 to stop, 3 to exit: ")
    if start == "1" and not thread_live:
        cd = threading.Thread(target=countdown)
        thread_live = True
        cd.start()
    elif start == "2" and thread_live:
        thread_live = False
        cd.join()
    elif start == "3":
        break

Here's a version that uses a timedelta to store and format the time:

import time
import datetime
import threading

thread_live = False

def countdown():
    t = datetime.timedelta(0)
    one = datetime.timedelta(seconds=1)

    while thread_live:
        print(str(t))
        t += one
        time.sleep(1)
    print("exiting")


while True:
    start = input("Press 1 to start and 2 to stop, 3 to exit: ")
    if start == "1" and not thread_live:
        cd = threading.Thread(target=countdown)
        thread_live = True
        cd.start()
    elif start == "2" and thread_live:
        thread_live = False
        cd.join()
    elif start == "3":
        break
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30