Stopwatch in python? Count up until
I want to make a stopwatch in python 3.3 that keeps counting down until you click a button or something, it should stop counting. This is my code:
seconds = 0
minutes = 0
continued = 0
while continued != 1:
print(minutes, ":", seconds)
time.sleep(1)
if seconds == 59:
seconds = 0
minutes = minutes + 1
else:
seconds = seconds + 1
without using CTRL + C
I'm not using a GUI or anything like that, just pure python code running on the command line using IDLE.
source to share
Trying to wait for a key press in a loop, without threads or timers / signals, will block the loop.
One way to continue processing the main loop (stopwatch) while waiting for a key press is through threads. A preliminary search led me to the ActiveState recipe , although I found a solution from this thread .
import threading, os, time, itertools, queue
try : # on windows
from msvcrt import getch
except ImportError : # on unix like systems
import sys, tty, termios
def getch() :
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try :
tty.setraw(fd)
ch = sys.stdin.read(1)
finally :
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
commands = queue.Queue(0)
def control(commands) :
while 1 :
command = getch()
commands.put(command) # put the command in the queue so the other thread can read it
# don't forget to quit here as well, or you will have memory leaks
if command == " " :
print "Stop watch stopped!"
break
def display(commands):
seconds = 0
minutes = 0
command = ""
while 1 :
# parsing the command queue
try:
# false means "do not block the thread if the queue is empty"
# a second parameter can set a millisecond time out
command = commands.get(False)
except queue.Empty, e:
command = ""
# behave according to the command
if command == " " :
break
print(minutes, ":", seconds, end="")
if seconds == 59:
seconds = 0
minutes = minutes + 1
else:
seconds = seconds + 1
time.sleep(1)
# start the two threads
displayer = threading.Thread(None,display,None, (commands,),{})
controler = threading.Thread(None, control, None, (commands,), {})
if __name__ == "__main__" :
displayer.start()
controler.start()
source to share
If you need a graphical interface for your stopwatch, you might be interested in the following code for Python 3.x.
#! /usr/bin/env python3
import tkinter
import time
class StopWatch(tkinter.Frame):
@classmethod
def main(cls):
tkinter.NoDefaultRoot()
root = tkinter.Tk()
root.title('Stop Watch')
root.resizable(True, False)
root.grid_columnconfigure(0, weight=1)
padding = dict(padx=5, pady=5)
widget = StopWatch(root, **padding)
widget.grid(sticky=tkinter.NSEW, **padding)
root.mainloop()
def __init__(self, master=None, cnf={}, **kw):
padding = dict(padx=kw.pop('padx', 5), pady=kw.pop('pady', 5))
super().__init__(master, cnf, **kw)
self.grid_columnconfigure(1, weight=1)
self.grid_rowconfigure(1, weight=1)
self.__total = 0
self.__label = tkinter.Label(self, text='Total Time:')
self.__time = tkinter.StringVar(self, '0.000000')
self.__display = tkinter.Label(self, textvariable=self.__time)
self.__button = tkinter.Button(self, text='Start', command=self.__click)
self.__label.grid(row=0, column=0, sticky=tkinter.E, **padding)
self.__display.grid(row=0, column=1, sticky=tkinter.EW, **padding)
self.__button.grid(row=1, column=0, columnspan=2,
sticky=tkinter.NSEW, **padding)
def __click(self):
if self.__button['text'] == 'Start':
self.__button['text'] = 'Stop'
self.__start = time.clock()
self.__counter = self.after_idle(self.__update)
else:
self.__button['text'] = 'Start'
self.after_cancel(self.__counter)
def __update(self):
now = time.clock()
diff = now - self.__start
self.__start = now
self.__total += diff
self.__time.set('{:.6f}'.format(self.__total))
self.__counter = self.after_idle(self.__update)
if __name__ == '__main__':
StopWatch.main()
source to share
Use curses:
import curses
from datetime import datetime
SPACE_KEY = ord(' ')
def run(win):
curses.echo()
win.timeout(1000) # Wait at most one second for a key.
start = datetime.now()
while True:
now = datetime.now()
minutes, seconds = divmod((now - start).total_seconds(), 60)
win.addstr(0, 0, "%02d:%02d" % (minutes, round(seconds)))
c = win.getch()
if c == SPACE_KEY:
break
curses.wrapper(run)
On Windows this is not a problem as you have kbhit
and getch
available in the module msvcrt
.
source to share