I started using a Python script for a stopwatch today and noticed a significant slow down in all the other things I have opened (Firefox, Sublime Text, Terminal). System Monitor is telling me my stopwatch script is using about 24% of my CPU. Seems odd that something so trivial uses that much resource.
Can I please get some pointers on how to improve this? I'd really like to run it in the background and keep track of my time spent on various things.
Here is the scripts:
#! /usr/bin/env python3
import tkinter
import time
import datetime
import numpy as np
import subprocess
class StopWatch(tkinter.Frame):
@classmethod
def main(cls):
tkinter.NoDefaultRoot()
root = tkinter.Tk()
root.title('Stop Watch')
root.resizable(False, False)
root.grid_columnconfigure(0, weight=1)
root.geometry("200x235")
padding = dict(padx=5, pady=5)
widget = StopWatch(root, **padding)
widget.grid(sticky=tkinter.NSEW, **padding)
icon = tkinter.PhotoImage(file='stopwatch.ico')
root.tk.call('wm', 'iconphoto', root._w, icon)
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(0,weight=1)
self.__total = 0
self.start_time=datetime.datetime.now().strftime("%H:%M")
self.start_date=datetime.datetime.now().strftime("%m/%d/%Y")
self.start_dt=tkinter.StringVar(self, self.start_time+" "+self.start_date)
self.__label = tkinter.Label(self, text='Session Time:')
self.__time = tkinter.StringVar(self, '00:00')
self.__display = tkinter.Label(self, textvariable=self.__time,font=(None, 26),height=2)
self.__button = tkinter.Button(self, text='Start', relief=tkinter.RAISED, bg='#008000', activebackground="#329932", command=self.__click)
self.__record = tkinter.Button(self, text='Record', relief=tkinter.RAISED, command=self.__save)
self.__startdt = tkinter.Label(self, textvariable=self.start_dt)
self.__label.grid (row=0, column=0, sticky=tkinter.NSEW, **padding)
self.__display.grid (row=1, column=0, sticky=tkinter.NSEW, **padding)
self.__button.grid (row=2, column=0, sticky=tkinter.NSEW, **padding)
self.__record.grid (row=3, column=0, sticky=tkinter.NSEW, **padding)
self.__startdt.grid (row=4, column=0, sticky=tkinter.N, **padding)
def __click(self):
if self.__total==0:
self.start_time=datetime.datetime.now().strftime("%H:%M")
self.start_date=datetime.datetime.now().strftime("%m/%d/%Y")
self.__time.set(self.start_time+" "+self.start_date)
if self.__button['text'] == 'Start':
self.__button['text'] = 'Stop'
self.__button['bg']='#ff0000'
self.__button['activebackground']='#ff3232'
self.__record['text']='Record'
self.__record['state']='disabled'
self.__record['relief']=tkinter.SUNKEN
self.__start = time.clock()
self.__counter = self.after_idle(self.__update)
else:
self.__button['text'] = 'Start'
self.__button['bg']='#008000'
self.__button['activebackground']='#329932'
self.__record['state']='normal'
self.__record['relief']=tkinter.RAISED
self.after_cancel(self.__counter)
def __save(self):
duration = int(self.__total//60)
if duration > 0:
subprocess.call("cp test_data.dat ./backup", shell=True)
data = np.loadtxt('test_data.dat', dtype="str")
time_data = data[:, 0]
date_data = data[:, 1]
duration_data = data[:, 2]
time_data=np.append(time_data,self.start_time)
date_data=np.append(date_data,self.start_date)
duration_data=np.append(duration_data,str(duration))
new_data=np.column_stack((time_data,date_data,duration_data))
np.savetxt('test_data.dat', new_data, header="*Time* | *Date* | *Duration*", fmt="%s")
self.__record['text']='Saved'
else:
self.__record['text']='Not Saved'
self.start_time=datetime.datetime.now().strftime("%H:%M")
self.start_date=datetime.datetime.now().strftime("%m/%d/%Y")
self.__time.set(self.start_time+" "+self.start_date)
self.__total=0
self.__time.set('00:00')
self.__record['state']='disabled'
self.__record['relief']=tkinter.SUNKEN
def __update(self):
now = time.clock()
diff = now - self.__start
self.__start = now
self.__total += diff
mins,secs=divmod(self.__total,60)
self.__time.set('{:02.0f}:{:02.0f}'.format(mins,secs))
self.start_dt.set(datetime.datetime.now().strftime("%H:%M %m/%d/%Y"))
self.__counter = self.after_idle(self.__update)
if __name__ == '__main__':
StopWatch.main()