mirror of
https://bitbucket.org/Mattrixwv/pyclasses.git
synced 2025-12-06 18:33:58 -05:00
176 lines
5.2 KiB
Python
176 lines
5.2 KiB
Python
#Python/pyClasses/Stopwatch.py
|
|
#Matthew Ellison
|
|
# Created: 01-27-19
|
|
#Modified: 07-19-20
|
|
#This is a class that is used to time program run times
|
|
"""
|
|
Copyright (C) 2020 Matthew Ellison
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
|
|
import time
|
|
import math
|
|
|
|
|
|
class Stopwatch:
|
|
#Initialize the class and all the variables you will need
|
|
def __init__(self):
|
|
self.timeStarted = 0.0 #This variable holds the time that the start function was called
|
|
self.timeStopped = 0.0 #This variable holds the time that the stop function was called
|
|
self.started = False #This variable holds true after the start function has been called
|
|
self.finished = False #This variable holds true after the start and stop functions have been called
|
|
|
|
#Save the time at this point. Simulates starting a stopwatch
|
|
def start(self):
|
|
self.started = True
|
|
self.finished = False
|
|
self.timeStarted = time.perf_counter_ns()
|
|
|
|
#Save the time at this point. Simulates stopping a stopwatch
|
|
def stop(self):
|
|
#If the stopwatch has been started then you record the stopping time
|
|
if(self.started):
|
|
self.timeStopped = time.perf_counter_ns()
|
|
self.finished = True
|
|
#Otherwise just ignore the function call
|
|
|
|
#Returns the difference between two times, usually start and stop times, but can be start time and now
|
|
#Simulates looking at the stopwatch; it can still be running when you look at it
|
|
def getTime(self):
|
|
#If the start and stop function have been called then calculate the time between the calls
|
|
if(self.finished):
|
|
return (self.timeStopped - self.timeStarted)
|
|
#If start was called but not stop calculate the time between start and now. Simulates looking at the watch while still running
|
|
elif(self.started):
|
|
return (time.perf_counter_ns() - self.timeStarted)
|
|
#If start was never called return a negative number. In this context time can never be negative
|
|
else:
|
|
return -1
|
|
|
|
#Return a specific resolution of time. This is done as a floating point number
|
|
#Returns the result of getTime() in terms of nanoseconds
|
|
def getNanoseconds(self):
|
|
return self.getTime()
|
|
|
|
#Returns the result of getTime() in terms of microseconds
|
|
def getMicroseconds(self):
|
|
micro = self.getTime()
|
|
if(micro < 0):
|
|
return micro
|
|
else:
|
|
return (micro / 1000)
|
|
|
|
#Returns the result of getTime() in terms of milliseconds
|
|
def getMilliseconds(self):
|
|
milli = self.getTime()
|
|
if(milli < 0):
|
|
return milli
|
|
else:
|
|
return (milli / 1000000)
|
|
#Returns the result of getTime() in terms of seconds
|
|
def getSeconds(self):
|
|
second = self.getTime()
|
|
if(second < 0):
|
|
return second
|
|
else:
|
|
return (second / 1000000000)
|
|
|
|
#Returns the result of getTime() in terms of minutes
|
|
def getMinutes(self):
|
|
minute = self.getTime()
|
|
if(minute < 0):
|
|
return minute
|
|
else:
|
|
return (minute / 60000000000)
|
|
|
|
#Returns the result of getTime() in terms of hours
|
|
def getHours(self):
|
|
hour = self.getTime()
|
|
if(hour < 0):
|
|
return hour
|
|
else:
|
|
return (hour / 3600000000000)
|
|
|
|
#Returns a string with the result of getTime() at the appropriate resolution
|
|
def getString(self):
|
|
#Get the time
|
|
return Stopwatch.getStr(self.getTime())
|
|
|
|
#Reset the timer so it can be used again
|
|
def reset(self):
|
|
self.timeStarted = 0.0
|
|
self.timeStopped = 0.0
|
|
self.started = False
|
|
self.finished = False
|
|
|
|
def __str__(self):
|
|
return self.getString()
|
|
|
|
def __add__(self, other):
|
|
return self.getString() + other
|
|
|
|
def __radd__(self, other):
|
|
return other + self.getString()
|
|
|
|
@staticmethod
|
|
def getStr(time: float) -> str:
|
|
#Divide by 1000 until you reach an appropriate resolution or run out of types of seconds
|
|
resCnt = 0
|
|
while((time >= 1000) and (resCnt < 3)):
|
|
time /= 1000
|
|
resCnt += 1
|
|
|
|
#If the resolution counter reached 3 we may need to change to minutes or hours
|
|
if(resCnt == 3):
|
|
#Check if seconds is low enough resolution
|
|
if(time >= 120):
|
|
#If not, change it to minutes
|
|
time /= 60
|
|
resCnt += 1
|
|
|
|
#Check if minutes is low enough resolution
|
|
if(time >= 120):
|
|
#If not, change it to hours
|
|
time /= 60
|
|
resCnt += 1
|
|
|
|
#Create a string with the number at ___.___ resolution
|
|
timeString = ""
|
|
#If nanoseconds was used we don't need the fractional part
|
|
if(resCnt == 0):
|
|
timeString = str(time) + ' '
|
|
else:
|
|
timeString = "{0}.{1:03d} ".format(math.floor(time), round((time % 1) * 1000))
|
|
|
|
#Determine the resolution of the number and add the appropriate word
|
|
if(resCnt == 0):
|
|
timeString += "nanoseconds"
|
|
elif(resCnt == 1):
|
|
timeString += "microseconds"
|
|
elif(resCnt == 2):
|
|
timeString += "milliseconds"
|
|
elif(resCnt == 3):
|
|
timeString += "seconds"
|
|
elif(resCnt == 4):
|
|
timeString += "minutes"
|
|
elif(resCnt == 5):
|
|
timeString += "hours"
|
|
else:
|
|
timeString = "error"
|
|
|
|
#Return the string
|
|
return timeString
|