this may be something simple, yet I can't figure out a way to do this; I am trying to print the seconds. I use:
r = int(pygame.time.get_ticks)
print(r/1000)
It prints out the seconds but what I want it to do is to print out the seconds just once. So basically it would output something like: 11111112222222233333333..., when I am looking for something like: 1 2 3...
If anyone can help me out, Id really appreciate it. Thank you.
You need to track the last value for seconds, and only print if the new value for seconds changes.
last_seconds = None
while True:
# Run game
r = int(pygame.time.get_ticks)
seconds = r / 1000
if seconds != last_seconds:
print(seconds)
last_seconds = seconds
You could do this with a closure by writing a function that captures the "last ticks" and compares this with the "current ticks". This way you only print the "time since init" every 1s.
Example:
def get_time_since_init():
last_ticks = int(pygame.time.get_ticks())
def wrapper()
ticks = int(pygame.time.get_ticks())
delta = (ticks - last_ticks) / 1000
if delta > 1:
last_ticks = ticks
print(ticks / 1000)
return wrapper
Related
This question already has answers here:
How to increase sleep/pause timing accuracy in python?
(4 answers)
Closed 5 months ago.
I've tried a few solutions from here with no luck. My Python timers are 10-30 seconds behind my smartphone stop watch after 10 minutes. I've tried the following:
def background3():
while True:
second = 0
minute = 0
hours = 0
while(True):
print('%d : %d : %d'%(hours,minute,second))
time.sleep(1)
second+=1
if(second == 60):
second = 0
minute+=1
if(minute == 60):
minute = 0
hour+=1;
and I also tried this:
def showCounter(self):
# Check the value of startWatch variable to start or stop the Stop Watch
if self.startWatch:
# Increment counter by 1
self.counter += 1
# Count and set the time counter value
cnt = int((self.counter/10 - int(self.counter/10))*10)
self.count = '0' + str(cnt)
# Set the second value
if int(self.counter/10) < 10 :
self.second = '0' + str(int(self.counter / 10))
else:
self.second = str(int(self.counter / 10))
# Set the minute value
if self.counter / 10 == 60.0 :
self.second == '00'
self.counter = 0
min = int(self.minute) + 1
if min < 10 :
self.minute = '0' + str(min)
else:
self.minute = str(min)
# Merge the mintue, second and count values
text = self.minute + ':' + self.second
# Display the stop watch values in the label
self.label.setText('<h1 style="color:white">' + text + '</h1>')
I'd like to be able to update a pyqt5 qlabel as time goes by every second, and I'd like to be able to display hours, minutes, and seconds in the qlabel. This has to be accurate as it is for work logging purposes. Eventually, I want to implement a qlabel that takes my overtime rate into consideration, and updates $ earned as time goes by. Does anybody have an example of what this may look like in pyqt5 using perhaps OS time ? Or is there some better way to do this?
EDIT:
This question is not a duplicate. The suggested articles were not helpful. I essentially need a way to count up from 0 using datetime. I tried replacing datetime.now but that did not work. The solutions suggested do not update my value in real time. They just take a stamp at the beginning, and subtract it from the end time. this is not what I am looking for. Does anybody know how I can watch seconds, minutes, and hours go by in real time through a pyqt5 qlabel?
def showCounter(self):
if self.startWatch:
text = str(datetime.now().strftime("%H:%M:%S"))
self.label.setText('<h1 style="color:white">' + str(text) + '</h1>')
Here's some code that prints every passing second without accumulating any lag. Just check the built-in clock at least once per second and update if the second has changed.
from datetime import datetime
import time
def time_to_str(time):
return str(time.hour) + ':' + str(time.minute) + ':' + str(time.second)
cur_time = datetime.now()
cur_str = time_to_str(cur_time)
while True:
time.sleep(0.2) # 200 ms, arbitrary
new_time = datetime.now()
new_str = time_to_str(new_time)
if new_str != cur_str:
print(new_str)
cur_str = new_str
The more often you check the time, the faster you can respond to the start of a new second. You'll never accrue lag regardless because you only print the time immediately after getting it from the system.
You should not expect a manufactured timer that relies on sleep() to be accurate for accrued time (stopwatch). Even if sleep() were 100% accurate, you are losing time outside of that in all of the function calls and other parts of the loop, which adds up over time (pun intended.)
The system time should be used. You can either use:
time.time()
or
datetime.now()
both have methods to peel out H:M:S.
As far as your "update loop"... well that is another story, you could use sleep there or whatever PyQt has to offer to refresh, but when you need to pull the time, do it as above.
If you want to use either as a "stopwatch" just capture the start time, do the subtraction. If you do this with datetime objects, the delta is a timedelta object that you can query. Do a little googling on timedelta and datetime.
Example:
In [1]: from datetime import datetime, timedelta
In [2]: tic = datetime.now()
In [3]: toc = datetime.now()
In [4]: td = toc - tic
In [5]: type(td)
Out[5]: datetime.timedelta
In [6]: td.seconds
Out[6]: 8
I am very very new to python and I am trying to make a simple timer app with it.
So if I input a number, like 30, the code should start counting down and output
>>> 30
>>> 29
>>> 28
>>> 27
and so on..
I am trying to get some logic into my brain. I was trying to do this since to days with same code in different places.
import time
x = input("seconds to blast off: ")
for z in range(x):
timer.sleep(x)
print("blast off")
This is all I have written and I am stuck here.
There's a few things here that need a little work.
First, input will always returns a string, so x is also a string. So if the user were to input '30', you would run for z in range('30'): which will error. Instead, you should cast x to an int with int(x).
Next, it's time.sleep, not timer.sleep
The way I'd implement the counter part personally would be to keep track of the start time, then calculate the end time. Then, find the difference between the time in the iteration and the end time and loop while that is greater than 0. It might look like this:
import time
x = int(input('Number of seconds: '))
end = time.time() + x
while end - time.time() > 0:
print(round(end - time.time()))
time.sleep(1)
Try this:
import time
sec = int(input('No. of seconds: '))
print(sec)
for s in range(sec):
sec = int(sec) - 1
time.sleep(1)
if sec == 0:
print("Blast Off")
else:
print(str(sec))
You got quite close to the solution.
timer.sleep() takes in the number of seconds.
Although, you could have found such answers on the web.
So I'm working with time to format seconds to the format MM:SS:TSHSTS, meaning minutes:seconds:1/10 second 1/100 second 1/1000 second. This is basicly to calculate lap times for a racing simulator.
My input comes in seconds so for instance 124.6073 seconds -> 02:04:607.
I've produced this function and it works, I just want to know how can I optimize this since in my head this is kinda hammered as I couldn't think of something better at the time.
def convert_lap_times(seconds_per_lap):
minutes = seconds_per_lap // 60
seconds = seconds_per_lap % 60
rest = seconds_per_lap % 1
rest_str = str(rest).split('0.')
decimal_rest = rest_str[1]
return "%02i:%02i.%0.3s" % (minutes, seconds, decimal_rest)
So the rest is the decimal part of said number and all worked fine until that point. The "big" issue becomes when I want to get rid of the integer part, for instance 0.607, I just wanted 607 so I parsed it as a string... is there a better way?
Thanks a lot and all the best!
You could do it like this:
def convert_lap_times(seconds_per_lap):
return "{:02.0f}:{:06.3f}".format(*divmod(seconds_per_lap,60))
print(convert_lap_times(124.6073)) # 02:04.607
I was testing a program to do something every N seconds, but I bumped into a weird problem.
If I use something simple like this:
import time
def main():
start_t = time.time()
while(True):
if (time.time()-start_t)%10 == 0:
print("Test")
if __name__ == "__main__":
main()
the program works as expected, i.e. it prints "Test" every 10 seconds.
However, I made a small modification, because I need to check at every iteration the current date...if I change the program to this:
import time
from datetime import datetime
def main():
start_t = time.time()
path_screenshots = "screenshots"
while(True):
path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
if (time.time()-start_t)%10 == 0:
print(f"Checking folder {path_screenshots_today}...")
if __name__ == "__main__":
main()
I would expect the program to print "Checking folder {path_screenshots_today}" every 10 seconds again, but instead it keeps running, without printing anything.
I understand that the result of the operation (time.time()-start_t)%10 is never precisely equal to 0, which might be creating the issue...but then, why does it even work in the first case?
I suspect it is working in the first case because the loop is running fast enough that it happens to line up. The lag created by creating path_screenshots_today (particularly the datetime.now() call) causes it not to line up as often. To actually do what you want, try:
import time
from datetime import datetime
def main():
last = time.time()
path_screenshots = "screenshots"
while True:
path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
if time.time() - last >= 10:
last = time.time()
print(f"Checking folder {path_screenshots_today}...")
if __name__ == "__main__":
main()
The first case works because the time is checked frequently enough, which does not happen in the second case because of the delay introduced by the string formatting. A more robust way is the following:
start_t = time.time()
while True:
path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
tt = time.time()
if tt - start_t >= 10:
print(f"Checking folder {path_screenshots_today}...")
start_t = tt # set last check time to "now"
And an even better way would be:
while True:
path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
print(f"Checking folder {path_screenshots_today}...")
time.sleep(10)
This avoids "busy waiting", i.e. keeping the CPU running like crazy.
It's a coincidence of how often the check is happening. If you actually loop over and print your value, you'll notice it's floating point:
while(True):
print('Current value is, ', (time.time()-start_t)%10)
You'll see output like this:
Current value is, 0.45271849632263184
Current value is, 0.45272231101989746
Given that you're doing so little in your loop, the odds are good that you'll coincidentally do that evaluation when the current value is exactly 0.0. But when you add some extra computation, even just the string formatting in datetime, each iteration of your loop will take a little longer and you might just happily skip over 0.0.
So strictly speaking, you should cast your value to an int before comparing it to 0. Eg, int((time.time() - start_t) % 10) == 0. That will be true for an entire second, until the modulus value is once again not zero, a second after it's first true.
A better solution, however, is to probably just use the time.sleep() function. You can call time.sleep to sleep for a number of seconds:
time.sleep(10) # Sleep for 10 seconds
Bright minds of Stackoverflow, I have a quest for you.
Currently I am running a loop in which calculations and data aquisition happen. These get more and more complicated over time. I want each run of the loop to last exactly one second. Due to the growing time of the calculations a simple "sleep(1)" at the end does not really help.
while True:
#here calculations happen that take more and more time
print 'some of the data'
sleep(1)
I was hoping to use datetime to calculate the seconds/milliseconds before these calculations and after to enter the difference into the sleep command. But i can't quite get my head around it. Can anyone help me out?
a=datetime.now()
#calculations
b=datetime.now()
calctime=(b-a).total_seconds()
sleep(1-calctime)
Try this:
from datetime import datetime
import time
def test():
a = datetime.now()
# calculations
b = datetime.now()
calctime = (b - a).total_seconds()
print("one")
time.sleep((1 - calctime) if (1-calctime)>0.0 else 0) #if your calculation already took 1 or more than 1 second then then make the waiting time 0
print("two")
test()
a=datetime.now()
#calculations
b=datetime.now()
calctime=b-a
ms = calctime.microseconds
if calctime.seconds == 0:
sleep(1-ms/1000000)
Additional info here: Python speed testing - Time Difference - milliseconds