I have a for loop and I want each iteration to be executed every 5 minutes. Essentially, I want to freeze/sleep the loop for 5 minutes and then continue from where it left 5 minutes ago, NOT to start from the beginning. In total, I want to do this for an entire day (24hours).
Something like this? The loop runs for (a little more than) twenty-four hours and sleeps for five minutes after each iteration.
from time import sleep, time
ONE_DAY = 24 * 60 * 60 # seconds
FIVE_MINUTES = 5 * 60 # seconds
start_time = time()
current_time = start_time
while current_time <= start_time + ONE_DAY - FIVE MINUTES:
# Do something loopy here...
time.sleep(FIVE_MINUTES)
current_time = time()
You could define a method that simply calls sleep for 5 minutes and then call that in your loop. Kind of like this
import time
# main loop
for i in .....:
# do your stuff
wait5Mins()
# continue doing stuff
def wait5Mins():
time.sleep(300)
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I have a function that returns seconds into days, hours, mins and sec. But I need to However, not print if outputs are 0. For example, if I enter 176400 seconds I want output would be "2 day 1 hours" not "2 day, 2 hours, 0 minutes, 0 seconds".
I did so far:
sec = int(input("Enter time in Seconds: "))
temp = sec
day = sec // 86400
sec %= 86400
hour = sec // 3600
sec %= 3600
mins = sec // 60
sec %= 60
if day >= 1:
print(f'time in minutes is {day}days {hour}hour {mins}min {sec}sec')
elif hour >= 1:
if mins == 0 and sec == 0:
print(f'time in minutes is {hour}hour')
elif mins == 0:
print(f'time in minutes is {hour}hour {sec}sec')
elif sec == 0:
print(f'time in minutes is {hour}hour {mins}min')
else:
print(f'time in minutes is {hour}hour {mins}min {sec}sec')
elif mins >= 1:
if sec == 0:
print(f'time in minutes is {mins}min')
else:
print(f'time in minutes is {mins}min {sec}sec')
elif sec >= 1:
print(f'time sec == {sec} sec')
I could be continue This code using bunch of "if" statement, but is there shorter way to do this?
It looks like you're trying to do something like:
result = "time in minutes is"
if days >0:
result += f" {days} days"
if hours > 0:
result += f" {hours} hours"
if mins > 0:
result += f" {mins} minutes"
if secs > 0:
result += f" {secs} seconds"
IIUC, you want shorter way then you can use datetime.timedelta like below:
import datetime
sec = int(input('Enter the number of seconds: '))
print(datetime.timedelta(seconds=sec))
Output:
Enter the number of seconds: 86600
1 day, 0:03:20
You can add these lines to get what you want:
import datetime
sec = int(input('Enter the number of seconds: '))
str_tm = str(datetime.timedelta(seconds=sec))
day = str_tm.split(',')[0]
hour, minute, second = str_tm.split(',')[1].split(':')
print(f'{day}{hour} hour {minute} min {second} sec')
Output:
Enter the number of seconds: 176400
2 days 1 hour 00 min 00 sec
You can assemble the non-zero parts in a list and join it at the end. You can also use the divmod function to extract the days,hours,minutes and seconds:
sec = int(input("Enter time in Seconds: "))
time = []
days,sec = divmod(sec,86400) # sec will get seconds in partial day
if days:
time.append(f"{days} day"+"s"*(days>1))
hours,sec = divmod(sec,3600) # sec will get seconds in partial hour
if hours:
time.append(f"{hours} hour"+"s"*(hours>1))
minutes,sec = divmod(sec,60) # sec will get seconds in partial minute
if minutes:
time.append(f"{minutes} minute"+"s"*(minutes>1))
if sec:
time.append(f"{sec} second"+"s"*(sec>1))
Sample runs:
Enter time in Seconds: 176400
time is: 2 days, 1 hour
Enter time in Seconds: 1767671
time is: 20 days, 11 hours, 1 minute, 11 seconds
Enter time in Seconds: 259321
time is: 3 days, 2 minutes, 1 second
The whole thing could be simplified using a loop that goes through the divisors and time units:
sec = int(input("Enter time in Seconds: "))
time = []
for d,u in [(86400,"day"),(3600,"hour"),(60,"minute"),(1,"second")]:
n,sec = divmod(sec,d)
if n: time.append(f"{n} {u}"+"s"*(n>1))
print("time is:",", ".join(time))
Personally, I prefer using values that are more familiar (like 60 minutes in an hour) which would change the sequence a bit. Also, the time string could be assembled directly rather than use a list and join at the end:
sec = int(input("Enter time in Seconds: "))
time = ""
for d,u in [(60,"second"),(60,"minute"),(24,"hour"),(sec,"day")]:
sec,n = divmod(sec,d)
if n: time = f"{n} {u}" + "s"*(n>1) + ", "*bool(time) + time
print("time is:",time)
I want to work with exactly 20ms sleep time. When i was using time.sleep(0.02), i am facing many problems. It is not working what i want. If I had to give an example;
import time
i = 0
end = time.time() + 10
while time.time() < end:
i += 1
time.sleep(0.02)
print(i)
We wait to see "500" in console. But it is like "320". It is a huge difference. Because sleep time is not working true and small deviations occur every sleep time. It is increasing cumulatively and we are seeing wrong result.
And then, i want to create my new project for clock pulse. Is it that possible with time.time()?
import time
first_time = time.time() * 100 #convert seconds to 10 * miliseconds
first_time = int(first_time) #convert integer
first_if = first_time
second_if = first_time + 2 #for sleep 20ms
third_if = first_time + 4 #for sleep 40ms
fourth_if = first_time + 6 #for sleep 60ms
fifth_if = first_time + 8 #for sleep 80ms
end = time.time() + 8
i = 0
while time.time() < end:
now = time.time() * 100 #convert seconds to 10 * miliseconds
now = int(now) #convert integer
if i == 0 and (now == first_if or now > first_if):
print('1_' + str(now))
i = 1
if i == 1 and (now == second_if or now > second_if):
print('2_' + str(now))
i = 2
if i == 2 and (now == third_if or now > third_if):
print('3_' + str(now))
i = 3
if i == 3 and (now == fourth_if or now > fourth_if):
print('4_' + str(now))
i = 4
if i == 4 and (now == fifth_if or now > fifth_if):
print('5_' + str(now))
break
Out >> 1_163255259009
2_163255259011
3_163255259013
4_163255259015
5_163255259017
Is this project true logic? And If it is true logic, how can finish this projects with true loops?
Because i want these sleeps to happen all the time. Thank you in advice.
Let's say you want to count in increments of 20ms. You need to sleep for the portion of the loop that's not the comparison, increment, and print. Those operations take time, probably about 10ms based on your findings.
If you want to do it in a loop, you can't hard code all the possible end times. You need to do something more general, like taking a remainder.
Start with the time before the loop:
t0 = time.time()
while time.time() < end:
i += 1
Now you need to figure out how long to sleep so that the time between t0 and the end of the sleep is a multiple of 20ms.
(time.time() - t0) % 0.02 tells you how far past a 20ms increment you are because python conveniently supports floating point modulo. The amount of time to wait is then
time.sleep(0.02 - (time.time() - t0) % 0.02)
print(i)
Using sign rules of %, you can reduce the calculation to
time.sleep(-(time.time() - t0) % 0.02)
I am trying to create a countdown in python and I want very simple way of creating that. I watched a couple of videos but couldn't find a right solution for it.
This is the code which I am using right now.
import time
def countdown(t):
while t:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
time.sleep(1)
t -= 1
print('Time Over!!!!')
t = input("Enter the time in seconds: ")
countdown(int(t))
The problem is that when you sleep for 1 second, it will not be for exactly 1 second and theoretically over long enough time the errors could propagate enough such that you could conceivably be printing out an incorrect time. To correct this, your code needs to actually check in its loop how much time has actually elapsed since the start of the program running and use that to compute what the new value of t is, and it should do this frequently so that the countdown is smooth. For example:
import time
def countdown(t):
start_time = time.time()
start_t = t
# compute accurate new t value aprroximately every .05 seconds:
while t > 0:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
time.sleep(.05) # finer timing
now = time.time()
elapsed_time = int(now - start_time) # truncated to seconds
t = start_t - elapsed_time
print('Time Over!!!!')
t = input("Enter the time in seconds: ")
countdown(int(t))
so i tried to create a countdown in python. It works fine, but I want to have a better print output. At the moment it prints the remaining time line by line, so my output is overfilled after some time. I then tried to do:
import time
def countdown(t):
while t:
print(t, end="\r")
time.sleep(1)
t -= 1
print('finished')
countdown(60)
but it outputs for me:
5
4
3
2
1
finished
I'd like to have it that it prints the countdown and the finished all in one line and deletes the number before it...
Thanks for helping :)
Here's what it should look like:
But i dont need the 00:00 format, the seconds are fine for me
almost there, below code will print your timer value side by side. not sure what 'deletes the number before it.' is!
import time
def countdown(t):
while t:
print(t, end=" ")
time.sleep(1)
t -= 1
print('finished')
countdown(60)
Delete the previous character using '\b'
import time
def countdown(t):
# how many digits
digits = int(t / 10) + 1
while t:
print('\b{}'.format(str(t).zfill(digits)), end="\r")
time.sleep(1)
t -= 1
print('finished')
countdown(10)
The following will work if called from Windows CMD
import time, sys, os
def pretty_format(seconds):
seconds = seconds % (24 * 3600)
hour = seconds // 3600
seconds %= 3600
minutes = seconds // 60
seconds %= 60
# Here's the formatting you asked for! 00:00:59 etc...
return "%d:%02d:%02d" % (hour, minutes, seconds)
def count_down(seconds):
os.system("cls") # Windows -> clear the cmd screen
while seconds:
sys.stdout.write("{}{}".format(pretty_format(seconds), "\b"*100)) # \b replaces the previous value. if we have a bunch of values we need to do multiple \b. Here's 100!
time.sleep(1)
seconds -=1
print('finished')
count_down(60)
I have a while loop, and I want it to keep running through for 15 minutes. it is currently:
while True:
#blah blah blah
(this runs through, and then restarts. I need it to continue doing this except after 15 minutes it exits the loop)
Thanks!
Try this:
import time
t_end = time.time() + 60 * 15
while time.time() < t_end:
# do whatever you do
This will run for 15 min x 60 s = 900 seconds.
Function time.time returns the current time in seconds since 1st Jan 1970. The value is in floating point, so you can even use it with sub-second precision. In the beginning the value t_end is calculated to be "now" + 15 minutes. The loop will run until the current time exceeds this preset ending time.
If I understand you, you can do it with a datetime.timedelta -
import datetime
endTime = datetime.datetime.now() + datetime.timedelta(minutes=15)
while True:
if datetime.datetime.now() >= endTime:
break
# Blah
# Blah
Simply You can do it
import time
delay=60*15 ###for 15 minutes delay
close_time=time.time()+delay
while True:
##bla bla
###bla bla
if time.time()>close_time
break
For those using asyncio, an easy way is to use asyncio.wait_for():
async def my_loop():
res = False
while not res:
res = await do_something()
await asyncio.wait_for(my_loop(), 10)
I was looking for an easier-to-read time-loop when I encountered this question here. Something like:
for sec in max_seconds(10):
do_something()
So I created this helper:
# allow easy time-boxing: 'for sec in max_seconds(42): do_something()'
def max_seconds(max_seconds, *, interval=1):
interval = int(interval)
start_time = time.time()
end_time = start_time + max_seconds
yield 0
while time.time() < end_time:
if interval > 0:
next_time = start_time
while next_time < time.time():
next_time += interval
time.sleep(int(round(next_time - time.time())))
yield int(round(time.time() - start_time))
if int(round(time.time() + interval)) > int(round(end_time)):
return
It only works with full seconds which was OK for my use-case.
Examples:
for sec in max_seconds(10) # -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
for sec in max_seconds(10, interval=3) # -> 0, 3, 6, 9
for sec in max_seconds(7): sleep(1.5) # -> 0, 2, 4, 6
for sec in max_seconds(8): sleep(1.5) # -> 0, 2, 4, 6, 8
Be aware that interval isn't that accurate, as I only wait full seconds (sleep never was any good for me with times < 1 sec). So if your job takes 500 ms and you ask for an interval of 1 sec, you'll get called at: 0, 500ms, 2000ms, 2500ms, 4000ms and so on. One could fix this by measuring time in a loop rather than sleep() ...
The best solution for best performance is to use #DrV answer and the suggestion from #jfs to use time.monotonic():
import time
from datetime import datetime, timedelta
count = 0
end_time = time.monotonic() + 10
while time.monotonic() < end_time:
count += 1
print(f'10 second result: {count=:,}')
# 10 second result: count=185,519,745
count = 0
end_time = time.time() + 10
while time.time() < end_time:
count += 1
print(f'10 second result: {count=:,}')
# 10 second result: count=158,219,172
count = 0
end_time = datetime.now() + timedelta(seconds=10)
while datetime.now() < end_time:
count += 1
print(f'10 second result: {count=:,}')
# 10 second result: count=39,168,578
try this:
import time
import os
n = 0
for x in range(10): #enter your value here
print(n)
time.sleep(1) #to wait a second
os.system('cls') #to clear previous number
#use ('clear') if you are using linux or mac!
n = n + 1