Python time.sleep() being ignored in timer program - python

I have been trying to create an extremely simple timer program for the past few days.
However, I have come across a major roadblock, in which the second delay countdown is just completely ignored when running the program.
I have tried replacing time.sleep(1) with time.sleep(1000), rearranging it all over the while loop it is in, but to no avail. The program just runs, with no delay neither in the beginning nor during the loop.
import time
hour, minute, second = 1, 2, 10
print("Starting now.")
x = 1
while x < 2:
print(str(hour) + ":" + str(minute) + ":" + str(second))
time.sleep(1)
second = second - 1
if second == 0:
minute = minute - 1
second = second + 60
if minute ==0:
hour = hour - 1
minute = minute + 60
if hour == 0:
x = x + 1
It would be a great help if someone could figure this out. Thank you!

As others have commented the code as given in original question does correctly sleep in a properly configured environment, this answer addresses the logic issue in the time handling by using datetime. The timedelta from subtracting two datetimes does not provide hours and minutes so these are calculated from the seconds.
import time, datetime,math
d = datetime.timedelta(hours=1,minutes=2,seconds=10)
endtime = (datetime.datetime.now()+ d)
print("Starting now.")
while datetime.datetime.now().time() <endtime.time():
td = endtime - datetime.datetime.now()
print(str(math.floor(td.seconds / 3600)) + ":" +
str(math.floor(td.seconds / 60) - math.floor(td.seconds / 3600)*60 ) + ":" +
str(td.seconds - math.floor(td.seconds / 60)*60) )
time.sleep(1)
You can also correct the logic in the original in the following manner
import time
hour, minute, second = 1, 2, 10
print("Starting now.")
x = 1
while x < 2:
print(str(hour) + ":" + str(minute) + ":" + str(second))
time.sleep(1)
second = second - 1
if second < 0:
minute = minute - 1
if minute >= -1:
second = second + 60
if minute < 0:
hour = hour - 1
if hour >= 0:
minute = minute + 60
if hour <= 0 and minute <= 0 and second <= 0:
x = x + 1

Related

Create clock pulse with python

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)

Conditional Formatted Strings in Python

def secondCalculator(days, hours, minutes, seconds):
days = int(input("Days: ")) * 3600 * 24
hours = int(input("Hours: ")) * 3600
minutes = int(input("Minutes: ")) * 60
seconds = int(input("Seconds: "))
allSec = days + hours + minutes + seconds
if days == 1:
print(f"{days} Days,{hours} Hours, {minutes} Minutes, {seconds} Seconds are equal to {allSec} seconds.")
#### same use of if, for hours, minutes and seconds.
If user enters
secondCalculator(0,1,2,5)
Output should be:
0 Day, 1 Hour, 2 Minutes, 5 Seconds is equal to 3725 seconds.
When user enters 1 day, it should be printing "day" not "days", same goes for hour, minutes, second.
The things is making it with an if is doable yes but i thought maybe there are easier ways to do it.
How can i make it put the "s" suffix depending on the entered number by the user.
Can we implement conditional string formatting for it?
Something like this possibly? Might make sense to wrap it in a function:
>>> days = 1
>>> f"day{('s', '')[days==1]}"
'day'
>>> days = 2
>>> f"day{('s', '')[days==1]}"
'days'
>>>
Use:
if days > 1:
suffix_day = 'days'
elif days == 0:
suffix_day = 'days'
else:
suffix_day = 'day'
then use:
print(f'{days} {suffix_day})
Define:
def s(val):
if val > 1:
return "s"
return ""
And use it as:
print(f"{days} Day{s(days)}

Get seperate two values and add together in every hour when the code is running using python

Here I have two values 40 and 50 in the csv file. Then I want to decrement the value in every hour separately and this will continuously running the code up to 24 hours.
So what I need to do is , I want to read that two changing values in every hour and do summation and read it as one output. I need this happened in every hour up to 24 hours.
So here I wrote the code for to read that two values and decrement in every one hour upto 24 hours.
50 will decrement in every hour 2.567
40 will decrement in every hour 1.234
Here is the code for the decrement process of two values. But unfortunately I have no idea how I can add that two values from taking that running code and read it as one input .
Can anyone help me to solve this process?
x = data[data['a'] == 50]
x now = x.iloc[0].loc['a']
last_x_value = 0
current_time = x.iloc[0].loc['date']
x_decrement_constant = math.exp((-2.567 * 1))
required_hours_of_generated_data = 24 # Generate data for this many hours.
X' = [{'date':current_time, 'a':x now }]
while True:
next_record_time = current_time + timedelta(0,3600)
if(last_x_value < len(x)-1):
if(next_record_time < x.iloc[last_x_value + 1].loc['date']):
new_x = (x_now* x_decrement_constant)
else:
new_x = (x_now* x_decrement_constant) + x.iloc[last_x_value + 1].loc['a']
last_x_value = last_x_value + 1
else:
break
y = data[data['b'] == 40]
y now = x.iloc[0].loc['b']
last_y_value = 0
current_time = x.iloc[0].loc['date']
x_decrement_constant = math.exp((-1.234* 1))
required_hours_of_generated_data = 24 # Generate data for this many hours.
Y' = [{'date':current_time, 'b':y now }]
while True:
next_record_time = current_time + timedelta(0,3600)
if(last_y_value < len(y)-1):
if(next_record_time < y.iloc[last_y_value + 1].loc['date']):
new_y = (y_now* y_decrement_constant)
else:
new_y = (y_now* y_decrement_constant) + y.iloc[last_y_value + 1].loc['b']
last_y_value = last_y_value + 1
else:
break

Developing a function to show time without imports

def show_time(hour,min):
hour = int(input())
min = ''
for hour in (hour,min):
while 24 >= hour > 12:
hour -= 12
min == min
return hour, ":" min,'pm'
if hour < 12:
if 0 <= min <= 59
hour == hour
min == min
return hour, ":" min,'am'
So this is my code so far.^^
When I run this code, i keep getting an infinite loop for one... another thing is.. I feel like i am totally off. Btw.. I am trying to do this without importing anything and using the string formatting method. Please HELP!
Here were my instructions...
def show_time(hour,min): Accept integers for the hour (values from 0 to 23) and the minute
(values from 0 to 59). Construct the correct clock representation, such as the examples below.
o you must use the format method.
o Examples:
! show_time(9,15) → "9:15am"
! show_time(0,0) → "12:00am"
! show_time(12,0) → "12:00pm"
! show_time(22,5) → "10:05pm"
I can't get what you're trying to achieve using loops, but here's a simple solution.
def show_time(hour, minutes):
if hour >= 12:
suffix = "pm"
if hour != 12:
hour -= 12
else:
suffix = "am"
if hour == 0:
hour = 12
return "{0}:{1:02}{2}".format(hour, minutes, suffix)
Hope it helps.
Correct code should be like this:
def show_time(hour,min):
hour = int(hour)
min = int(min)
if hour > 12:
hour -= 12
return str(hour) + ":" + str(min) + 'pm'
else:
return str(hour) + ":" + str(min) + 'am'
print show_time(9,15)
You should think on simple level. For and while loops are unnecessary.
How about this:
def show_time(hour, min):
if hour > 24 or min > 59 or hour < 0 or min < 0:
raise ValueError("Invalid input")
# which half of day is this?
is_pm = (hour / 12.0) > 1
# normalize time in 0 to 11
hour = hour % 12
# get the correct half of day readable form
half_day = "pm" if is_pm else "am"
# print it out
print "%02d:%02d%s" % (hour, min, half_day)
Always try too keep things simple when possible, loops are useful but try to question whether they are really necessary.

Python loop to run for certain amount of seconds

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

Categories

Resources