I am trying to implement this time class to find the current time. I am getting wrong time. Can someone please take a look what am I doing wrong here?
import time
import datetime
class Time():
def __init__(self):
currentTime = time.time()
totalSeconds = int(currentTime)
self.__second = totalSeconds % 60
totalMinutes = totalSeconds // 60
self.__minute = totalMinutes %60
totalHours = totalMinutes// 60
self.__hour = totalHours % 12
def getSecond(self):
return self.__second
def getMinute(self):
return self.__minute
def getHour(self):
return self.__hour
def main():
t = Time()
print("Current Time is : ", t.getHour(), ":", t.getMinute(), ":", t.getSecond())
print(datetime.datetime.now().time())
print(time.ctime())
main()
Your code always deals with UTC times, but you are comparing the result with time in your time zone. Try this:
def main():
t = Time()
print("Current Time is : ", t.getHour(), ":", t.getMinute(), ":", t.getSecond())
print(datetime.datetime.utcnow().time())
print(time.asctime(time.gmtime()))
Related
I want to print list data on the specific delays which are on another list. I Want to loop this process for a specific time, but I'm unable to implement it in a thread.
from time import sleep
import datetime
now = datetime.datetime.now()
Start_Time = datetime.datetime.now()
Str_time = Start_Time.strftime("%H:%M:%S")
End_Time = '11:15:00'
class sampleTest:
#staticmethod
def test():
list1 = ["Hello", "Hi", "Ola"]
list2 = [5, 10, 7]
# print(f"{data} delay {delay} & time is {t} ")
# sleep(delay)
i = 0
while i < len(list1):
t = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{list1[i]} delay {list2[i]} & time is {t} ")
sleep(list2[i])
i += 1
else:
print("All Data is printed")
if __name__ == '__main__':
obj = sampleTest
while Str_time < End_Time:
obj.test()
Str_time = datetime.datetime.now().strftime("%H:%M:%S")
else:
print("Time Is done")
Expected output: On first, loop it should print all list data but in the second loop, it should run as per the delay.
1st time: Hello, Hi, Ola
after that
1. Every 5 seconds it should print Hello
2. Every 10 seconds it should print Hi
3. Every 7seconds it should print Ola
Actual Output: List of data is getting printed as per the delay.
Hello delay 5 & time is 11:41:45
Hi delay 10 & time is 11:41:50
Ola delay 3 & time is 11:42:00
All Data is printed
Hello delay 5 & time is 11:42:03
Hi delay 10 & time is 11:42:08
Ola delay 3 & time is 11:42:18
You can try comparing the current time with the start time, for example:
time.sleep(1);
diff = int(time.time() - start_time)
if (diff % wait_time == 0):
print(text_to_print)
Here is the full code implementing this:
from time import sleep
import time
import datetime
now = datetime.datetime.now()
Start_Time = datetime.datetime.now()
Str_time = Start_Time.strftime("%H:%M:%S")
End_Time = '11:15:00'
starttime=time.time()
diff = 0
class sampleTest:
#staticmethod
def test():
list1 = ["Hello", "Hi", "Ola"]
list2 = [5, 10, 7]
for i in range(len(list1)):
if (diff % list2[i] == 0):
t = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{list1[i]} delay {list2[i]} & time is {t} ")
if __name__ == '__main__':
obj = sampleTest
while Str_time < End_Time:
obj.test()
time.sleep(1);
diff = int(time.time() - starttime)
Str_time = datetime.datetime.now().strftime("%H:%M:%S")
else:
print("Time Is done")
In accordance with your desired output, I believe threads are the best option, which means:
from time import sleep
import datetime
import threading
now = datetime.datetime.now()
Start_Time = datetime.datetime.now()
Str_time = Start_Time.strftime("%H:%M:%S")
End_Time = '11:15:00'
class sampleTest:
def __init__(self):
self.run = True
print ("1st time: Hello, Hi, Ola")
print ("Now: " + datetime.datetime.now().strftime('%H:%M:%S'))
def test(self, i):
list1 = ["Hello", "Hi", "Ola"]
list2 = [5, 10, 7]
while self.run:
sleep(list2[i])
t = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{list1[i]} delay {list2[i]} & time is {t}")
def stop(self):
self.run = False
if __name__ == '__main__':
obj = sampleTest()
t1 = threading.Thread(target=obj.test,args=(0,))
t2 = threading.Thread(target=obj.test,args=(1,))
t3 = threading.Thread(target=obj.test,args=(2,))
t1.start()
t2.start()
t3.start()
while Str_time < End_Time:
Str_time = datetime.datetime.now().strftime("%H:%M:%S")
else:
obj.stop()
t1.join()
t2.join()
t3.join()
print("All data is printed")
print("Time Is done")
I'm trying to make the program output the time it took to complete fib(n) but during the time it's calculating, it continuously posts minute amounts of time. How do I get the program to just output the time once. Here if my program:
import time
def fib(n):
if n <= 1:
return 1
else:
start_time = time.time()
answer = fib(n-1) + fib(n-2)
end_time = time.time()
total_time = end_time - start_time
print(total_time)
return answer
Since your function is recursive, each call will print out its own time. If you want to know how much time the function took, I would suggest wrapping the main call to fib in a time statement, rather than putting the timing in the actual function code.
Instead of placing the code which calculates the time inside the fib() function, place it outside the function, like so:
import time
def fib(n):
if n <= 1:
return 1
else:
answer = fib(n-1) + fib(n-2)
return answer
#Place it all here
start_time = time.time()
fib(90) #Or some other number
end_time = time.time()
total_time = end_time - start_time
print(total_time)
You use my timing program that I wrote.
#!python3
import timeit
from os import system
system('cls')
# % % % % % % % % % % % % % % % % %
# times the code 100 times
runs = 100
totalTime = 0.0; average = 0.0
testTimes = []
for i in range(runs):
startTimer = timeit.default_timer()
# % % % % % % % % % % % % % % % %
# >>>>> code to be tested goes here <<<<<
def fib(n):
if n <= 1:
return 1
else:
answer = fib(n - 1) + fib(n - 2)
return answer
r = fib(26)
print('fib result is:', r)
# % % % % % % % % % % % % % % % %
endTimer = timeit.default_timer()
timeInterval = endTimer - startTimer
testTimes.append(timeInterval)
totalTime += timeInterval
print('\n', '{} {:.4f} {}'.format("This run's time is", timeInterval,
'seconds' + '\n'))
# print the results
print('{} {:.4f} {}'.format(' Total time:', totalTime, 'seconds'))
print('{} {:.4f} {}'.format('Shortest time:', min(testTimes), 'seconds'))
print('{} {:.4f} {}'.format(' Longest time:', max(testTimes), 'seconds'))
print('{} {:.4f} {}'.format(' Average time:', (totalTime / runs), 'seconds'))
As others noted, to time a recursive function, place the timings around the call to the function, not in the function. Here some additional code to time computing the first 30 number of the sequence.
import time
import numpy as np
def fib(n):
if n <= 1:
answer = 1
else:
answer = fib(n-1) + fib(n-2)
return answer
for i in np.arange(1,30):
start = time.time()
f = fib(i)
end = time.time()
total = end - start
print(i, fib(i), total)
I am having issues with properly implementing the following:
Remove __hours and __minutes.
Adjust the implementation of the mutator and accessor methods. For
example, for __init__(hr, min, sec), validate the values, then set
__seconds = hr * 60 * 60 + min * 60 + sec. This will store the time as seconds. Adjust all the methods to work with __seconds. getSecond()
can use __seconds mod 60 to return only the seconds in the time. Test
all the methods to make sure they still work. (mod is modulus, the
remainder after a division.)
I have used this in my code self.setSecond = (hour * 60 * 60) + (minute * 60 + second)
To properly represent hour, minute and seconds to just seconds I am however having issues with implementing the rest of the program. I'm not sure if I should be printing out just seconds? Also when I change my getSecond() function to return % 60 it is not doing so. I'm assuming because I'm not properly calling it?
Here is my code thus far:
class Clock(object):
def __init__(self, hour, minute, second):
self.setHour(hour)
self.setMinute(minute)
self.setSecond = (hour * 60 * 60) + (minute * 60 + second)
def setHour(self, hour):
self.__hour = hour
if self.__hour > 23:
self.__hour = 0
elif self.__hour < 0:
self.__hour = 0
def getHour(self):
return self.__hour
def setMinute(self, minute):
self.__minute = minute
if self.__minute > 60:
self.__minute = 0
elif self.__minute < 0:
self.__minute = 0
def getMinute(self):
return self.__minute
def setSecond(self, second):
self.__second = second
if self.__second > 60:
self.__second = 0
elif self.__second < 0:
self.__second = 0
def getSecond(self):
return self.__second
def __str__(self):
if self.__hour > 11:
return 'The Time is {}:{}:{} PM'.format(self.__hour, self.__minute, self.__second)
else:
return 'The Time is {}:{}:{} AM'.format(self.__hour, self.__minute, self.setSecond)
stopwatch = Clock(3, 2, 1)
print(stopwatch)
Note: I am aware that this code isn't very pythonic but that is how I was told to keep it (I apologize).
There are 6 changes required primarily:
You don't need to maintain hours and minutes in the class. You maintain only the seconds. So remove the setHour and setMinute methods.
Because you don't maintain the hours and minutes, the getHour and getMinute methods should do the required calculation.
def getHour(self):
return int(self.__second / 3600)
def getMinute(self):
return int(self.__second / 60) % 60
In the init function, call to self.setSecond is not correct. It should be:
def __init__(self, hour, minute, second):
if hour > 23 or hour < 0:
hour = 0
if minute > 60 or minute < 0:
minute = 0
if second > 60 or second < 0:
second = 0
self.setSecond((hour * 60 * 60) + (minute * 60 + second))
And although you mentioned, your getSecond() method does not do a seconds % 60. It should be:
def getSecond(self):
return self.__second % 60
In method def __str__, instead of directly accessing the hours, minutes, seconds, use the accessor methods:
def __str__(self):
if self.getHour() > 11:
return 'The Time is {}:{}:{} PM'.format(self.getHour(), self.getMinute(), self.getSecond())
else:
return 'The Time is {}:{}:{} AM'.format(self.getHour(), self.getMinute(), self.getSecond())
The setSeconds method should not have the check for > 60 because now you will be storing a large number here:
def setSecond(self, second):
self.__second = second
if self.__second < 0:
self.__second = 0
So I have this here.
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours = 2
if Hours == 12:
Hours = 1
Minutes = 0
break
ReadLine = ("\t{0:>2} : {1:>2}\r").format(Hours, Minutes)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
Just for the record, I have made sure that the indentations are correct, they look a little screwy here. And I realize that I have nothing set for A.M./P.M. as of yet.. Any help is appreciated for this noob.
Thank you - Matt.
Edit:
>>> 2: 0 2: 0 2: 0
This is what is printing out now, the minutes have not updated. I'm obviously missing something. Once again thanks for any help, and I am sorry if this is a repeat, I have searched for an answer, but none was found. Thanks - Matt.
Edit #2- I figured it out. I used a bit of both of the answers, and whilst I accept the fact that it will be slow it does what I want it to do.
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
AM_PM = "AM" if Hours < 12 else "P.M"
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours += 1
if Hours == 24:
Hours = 1
Minutes = 0
break
ReadLine = ("\t{:>2} : {:>2} {}\r").format(Hours, Minutes, AM_PM)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
You know, it seems no matter how hard I try, I cannot get this darned indentation to look right. Oh well, I hope you can understand it's just tabbed a bit to the right.
your code print nothing because you put the code that print to stdout inside the if statements. so it would print only when Minutes == 60 and Hours == 12 (which will never happend because of you dont increament Hours as meantioned in the comments.
try this:
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
ampm = "AM"
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours += 1
if Hours == 12:
Hours = 1
Minutes = 0
ampm = ("AM" if (ampm == "PM") else "PM")
ReadLine = ("\t{0:>2} : {1:>2} {2} \r").format(Hours, Minutes,ampm)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
import datetime
then = now = datetime.datetime.now()
minutes = 0
hours = 0
while True:
now = datetime.datetime.now()
if (now-then).total_seconds() > 60:
then += datetime.timedelta(minutes=1)
minutes += 1
if minutes == 60:
minutes = 0
hours += 1
if hours == 24:
hours = 0
am_pm = "AM" if hours < 12 else "PM"
print("{:>2}:{:>02} {}".format((hours+11)%12+1, minutes, am_pm))
Note that I do away with time.sleep as it's not guaranteed to sleep for exactly the time requested (indeed you will always be running slightly slow by that clock) and instead compare a current time to the last time a minute passed and see if the total seconds are more than 60. If so, increment minutes, if minutes is 60, increment hours and check for rollover and am_pm switch. Afterwards, print the time.
If you're wanting to stretch your legs a little, try implementing it in a class! Ooh ooh, and threading too!
import datetime
import threading
import queue
class Clock(object):
def __init__(self, current_time=None):
if isinstance(current_time, datetime.datetime):
hours, minutes = current_time.hour, current_time.minute
else:
hours = minutes = 0
self.hours = hours
self.minutes = minutes
self.q = queue.Queue()
def checkTime(self):
try:
self.q.get_nowait() # time has updated, or exception thrown
self.updateTime()
self.q.task_done()
except queue.Empty:
pass # time hasn't updated
def updateTime(self, num_mins=1):
self.minutes += 1
if self.minutes == 60:
self.minutes = 0
self.hours += 1
if self.hours == 24:
self.hours = 0
print(self)
def minutePassed(self):
then = datetime.datetime.now()
while True:
now = datetime.datetime.now()
if (now-then).total_seconds() > 60:
then += datetime.timedelta(minutes=1)
self.q.put('_') # put something there, doesn't matter what
def __str__(self):
am_pm = "AM" if self.hours < 12 else "PM"
return "{:>2}:{:>02} {}".format((self.hours+11)%12+1,
self.minutes, am_pm)
def start(self):
t = threading.Thread(target=self.minutePassed)
t.daemon=True
t.start()
while True:
self.checkTime()
clock = Clock(datetime.datetime.now())
clock.start()
I'm trying to create a simple game where the point is to collect as many blocks as you can in a certain amount of time, say 10 seconds. How can I get a timer to begin ticking at the start of the program and when it reaches 10 seconds, do something (in this case, exit a loop)?
import time
now = time.time()
future = now + 10
while time.time() < future:
# do stuff
pass
Alternatively, if you've already got your loop:
while True:
if time.time() > future:
break
# do other stuff
This method works well with pygame, since it pretty much requires you to have a big main loop.
Using time.time()/datetime.datetime.now() will break if the system time is changed (the user changes the time, it is corrected by a timesyncing services such as NTP or switching from/to dayligt saving time!).
time.monotonic() or time.perf_counter() seems to be the correct way to go, however they are only available from python 3.3. Another possibility is using threading.Timer. Whether or not this is more reliable than time.time() and friends depends on the internal implementation. Also note that creating a new thread is not completely free in terms of system resources, so this might be a bad choice in cases where a lot of timers has to be run in parallel.
I use this function in my python programs. The input for the function is as example:
value = time.time()
def stopWatch(value):
'''From seconds to Days;Hours:Minutes;Seconds'''
valueD = (((value/365)/24)/60)
Days = int (valueD)
valueH = (valueD-Days)*365
Hours = int(valueH)
valueM = (valueH - Hours)*24
Minutes = int(valueM)
valueS = (valueM - Minutes)*60
Seconds = int(valueS)
print Days,";",Hours,":",Minutes,";",Seconds
start = time.time() # What in other posts is described is
***your code HERE***
end = time.time()
stopWatch(end-start) #Use then my code
The threading.Timer object (documentation) can count the ten seconds, then get it to set an Event flag indicating that the loop should exit.
The documentation indicates that the timing might not be exact - you'd have to test whether it's accurate enough for your game.
In this example the loop is run every second for ten seconds:
import datetime, time
then = datetime.datetime.now() + datetime.timedelta(seconds=10)
while then > datetime.datetime.now():
print 'sleeping'
time.sleep(1)
For a StopWatch helper class, here is my solution which gives you precision on output and also access to the raw start time:
class StopWatch:
def __init__(self):
self.start()
def start(self):
self._startTime = time.time()
def getStartTime(self):
return self._startTime
def elapsed(self, prec=3):
prec = 3 if prec is None or not isinstance(prec, (int, long)) else prec
diff= time.time() - self._startTime
return round(diff, prec)
def round(n, p=0):
m = 10 ** p
return math.floor(n * m + 0.5) / m
Asks you when to stop [seconds]
Adds '0' at starting [1-9]
import time
import sys
stop = int(input('> '))
second = 0
print('> Stopwatch Started.')
while stop > second:
if second < 9:
second = second + 1
time.sleep(1)
sys.stdout.write('\r> ' + '0' + str(second))
else:
second += 1
time.sleep(1)
sys.stdout.write('\r' + '> ' + str(second))
print('\n> Stopwatch Stopped.')
As a learning exercise for myself, I created a class to be able to create several stopwatch timer instances that you might find useful (I'm sure there are better/simpler versions around in the time modules or similar)
import time as tm
class Watch:
count = 0
description = "Stopwatch class object (default description)"
author = "Author not yet set"
name = "not defined"
instances = []
def __init__(self,name="not defined"):
self.name = name
self.elapsed = 0.
self.mode = 'init'
self.starttime = 0.
self.created = tm.strftime("%Y-%m-%d %H:%M:%S", tm.gmtime())
Watch.count += 1
def __call__(self):
if self.mode == 'running':
return tm.time() - self.starttime
elif self.mode == 'stopped':
return self.elapsed
else:
return 0.
def display(self):
if self.mode == 'running':
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.elapsed = 0.
elif self.mode == 'stopped':
pass
else:
pass
print "Name: ", self.name
print "Address: ", self
print "Created: ", self.created
print "Start-time: ", self.starttime
print "Mode: ", self.mode
print "Elapsed: ", self.elapsed
print "Description:", self.description
print "Author: ", self.author
def start(self):
if self.mode == 'running':
self.starttime = tm.time()
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.starttime = tm.time()
self.mode = 'running'
self.elapsed = 0.
elif self.mode == 'stopped':
self.mode = 'running'
#self.elapsed = self.elapsed + tm.time() - self.starttime
self.starttime = tm.time() - self.elapsed
else:
pass
return
def stop(self):
if self.mode == 'running':
self.mode = 'stopped'
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.mode = 'stopped'
self.elapsed = 0.
elif self.mode == 'stopped':
pass
else:
pass
return self.elapsed
def lap(self):
if self.mode == 'running':
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.elapsed = 0.
elif self.mode == 'stopped':
pass
else:
pass
return self.elapsed
def reset(self):
self.starttime=0.
self.elapsed=0.
self.mode='init'
return self.elapsed
def WatchList():
return [i for i,j in zip(globals().keys(),globals().values()) if '__main__.Watch instance' in str(j)]
This is the Shortest Way I know of doing it:
def stopWatch():
import time
a = 0
hours = 0
while a < 1:
for minutes in range(0, 60):
for seconds in range(0, 60):
time.sleep(1)
print(hours,":", minutes,":", seconds)
hours = hours + 1
New to the python world!
I need a System Time independent Stopwatch so I did translate my old C++ class into Python:
from ctypes.wintypes import DWORD
import win32api
import datetime
class Stopwatch:
def __init__(self):
self.Restart()
def Restart(self):
self.__ulStartTicks = DWORD(win32api.GetTickCount()).value
def ElapsedMilliSecs(self):
return DWORD(DWORD(win32api.GetTickCount()).value-DWORD(self.__ulStartTicks).value).value
def ElapsedTime(self):
return datetime.timedelta(milliseconds=self.ElapsedMilliSecs())
This has no 49 days run over issue due to DWORD math but NOTICE that GetTickCount has about 15 milliseconds granularity so do not use this class if your need 1-100 milliseconds elapsed time ranges.
Any improvement or feedback is welcome!