Python 3: Nested while loops based time - python

I am trying to run two while loops based on an input condition. In this example, that is taken out and replaced by a 1 == 0 so that 0 can be changed back and forth for testing. Once selected, each while loop should run for 10 seconds and then the input condition checked (replaced by 1 == 0) again.
The problem appears to be in the time comparison, since it never evaluates correctly. What am I missing?
#!/usr/bin/env python3
import time
import os
import bellmod
while True:
starttime = time.time()
print("Start time " + str(starttime)) #Time check
elapsedtime = 0 #Reset elasped time to 0 for each loop iteration.
if 1 == 0: #Change this to run either loop. See if remote or local has precidence.
while(elapsedtime < 10):
print("Inside remote while " + time.strftime("%H:%M:%S")) #Time check
elapsedtime = time.time() - starttime #Calculate elasped time.
else:
elapsedtime = 0
while(elapsedtime < 10):
print("inside bottom of local while " + str(int(time.time() - starttime))) #Time check
elapsedtime = time.time() - starttime #Calculate elasped time.

Your inner while loops are endless, because elapsedtime is never updated:
while(elapsedtime < 10):
print("inside bottom of local while " + str(int(time.time() - starttime))) #Time check
elapsedtime = time.time() - starttime #Calculate elasped time.
elapsedtime is updated after the while loop ends, but that is never reached.
You need to fix your indentation so elapsedtime is calculated each loop iteration:
while(elapsedtime < 10):
print("inside bottom of local while " + str(int(time.time() - starttime))) #Time check
elapsedtime = time.time() - starttime #Calculate elasped time.
Note that while is not a function. Using (...) groups the test expression, but is not needed or normally used. If you pass in values as separate arguments to print(), that takes care of including a separator and conversion to string for you:
while elapsedtime < 10:
print("inside bottom of local while", int(time.time() - starttime))
elapsedtime = time.time() - starttime
If you don't need to use elapsedtime in the loop, just inline the calculation:
while time.time() - starttime < 10:
print("inside bottom of local while", int(time.time() - starttime))

You don't change elapsedtime inside the loop ... it's stuck at 0.
Indent the last line:
if 1 == 0: #Change this to run either loop. See if remote or local has precidence.
while(elapsedtime < 10):
print("Inside remote while " + time.strftime("%H:%M:%S")) #Time check
elapsedtime = time.time() - starttime #Calculate elasped time.
else:
elapsedtime = 0
while(elapsedtime < 10):
print("inside bottom of local while " + str(int(time.time() - starttime))) #Time check
elapsedtime = time.time() - starttime #Calculate elasped time.

Related

Check a condition every 3 minutes without functions and without interrupting the loop

I have this working code that checks a conditions every 3 minutes considering the local time, so every 0, 3, 6, 9.....It prints "checking condition".
import time
def get_next_time():
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
return result
next_run = get_next_time()
while True:
now = time.localtime()
if next_run == now.tm_min:
print("checking condition")
#some condition
next_run = get_next_time()
time.sleep(1)
The problem is that I need the code without functions, so I need to find a way to write this code without using any funcion, and I cannot use break or interrput the loop
I tried:
while True:
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
now = time.localtime()
if result == now.tm_min:
print("checking conditions")
time.sleep(1)
But it does not work: it does not do nothing.
Any ideas?
you can compact the function in one statement:
import time
next_run = (3 - (time.localtime().tm_min % 3) + time.localtime().tm_min)%60
while True:
now = time.localtime()
if next_run == now.tm_min:
print("checking condition")
#checking conditions...
next_run=(3 - (time.localtime().tm_min % 3) + time.localtime().tm_min)%60
time.sleep(1)
The first time, the get_next_time() will only be executed when next_run == now.tm_min. The second time, you execute it each loop
import time
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
while True:
now = time.localtime()
if result == now.tm_min:
print("checking conditions")
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
time.sleep(1)
Rounding to the next multiple of 3 minutes contradicts the specification "every 0...".
It is enough to do
import time
first= True
while True:
minute= time.localtime().tm_min
if first or minute == target:
print("checking condition")
first= False
target= (minute + 3) % 60
time.sleep(1)
Update:
I modified the code so that a single call to localtime is made on every iteration, to make fully sure that the minutes do not change between the calls.
More compact but less efficient:
import time
while True:
minute= time.localtime().tm_min
if 'target' not in locals() or minute == target:
print("checking condition")
target= (minute + 3) % 60
time.sleep(1)

When the time expires, the function starts again from the beginning

import pygame as pg
pg.init()
def fixTime():
totalTime = 4
return totalTime
while 1:
flowTime = int(pg.time.get_ticks()/1000)
elapsed_time = (fixTime() - flowTime)
if elapsed_time <=0:
fixTime()
else:
print(elapsed_time)
When the current ends, 1 is repeated, but I want to make a function that returns the time to the beginning.
Just use pygame.time.get_ticks():
Return the number of milliseconds since pygame.init() was called.
You can just subtract 2 time values:
def get_elapsed_time(from_time = 0):
to_time = pygame.time.get_ticks()
return to_time - from_time
start_time = pygame.time.get_ticks():
while run:
elapsed = get_elapsed_time(start_time)
# [...]
pygame.time.get_ticks() returns the time in milliseconds. If you want the time in seconds you must divide by 1000. e.g.: return (to_time - from_time) / 1000

trying to get an if statement to be triggered during certain times of day

im fairly new with python but im tring to get a device to turn on for one minute and off for 3 minutes repeatedly from the times of 9am to 5pm and i can't get the if statement to reference the updated time from the loop any help would be greatly appreciated!!!
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
now = datetime.datetime.now()
hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.second
total = 1
if hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
for i in range(1,100):
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
else :
for i in range(1,100):
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
You could fix it with a while loop instead, it would look like this, just put all of it inside your function
now = datetime.datetime.now()
hour = now.hour
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run:
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run == False:
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
Maybe using a while statement. In addition, you have hour = now.second on the second line of the function count and I think it should be hour = now.hour.
See the code with comments:
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
#Next lines are redundant, commented out.
#now = datetime.datetime.now()
#hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.hour #now.second
total = 1
while hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
# for i in range(1,100): -> why you need this?
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.hour #now.second
print (hour)
for i in range(1,100): #I don't know why you need a loop here
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
Edited for correcting another hour = now.second inside the while loop
I don't know how are you planning on running the code, but the main problem I see is that you do not have any loop for your code to run infinitely and check the time condition.
Also it's not clear for me why you need this total variable that gets doubled.
Another thing is your for loops - the condition is not clear. Why do you want to run it in this specific range?
What I would do is I would create an infinite loop and inside it make some decisions based on a clear time conditions - the conditions that are specified by you.
So if I understood your case correctly I'd rather write something like this:
# between 9am to 5pm turn on the device for 60 seconds and off for 180 seconds repeatedly
from datetime import datetime
import time
def update_device_state(state):
# TODO: implement GPIO output code
pass
def run():
device_state = 'off'
new_state = device_state
on_timer = 0
off_timer = time.time() - 180 # initial value must be over 180 seconds to trigger device on a first run
while True:
hour = datetime.now().hour
if 5 <= hour <= 17:
if device_state == 'off' and time.time() - off_timer > 180:
on_timer = time.time()
new_state = 'on'
off_timer = 0
elif device_state == 'on' and time.time() - on_timer > 60:
off_timer = time.time()
new_state = 'off'
on_timer = 0
else:
if device_state = 'on'
new_state = 'off'
on_timer = 0
off_timer = time.time()
if device_state != new_state:
update_device_state(new_state)
device_state = new_state
time.sleep(1)
run()
But the code requires some testing as I just quickly drafted it and I just briefly red it.

for-loop with a timeout inside the loop?

I'm trying to find a way to do a for loop, and if the iteration of the for loop is more than the timeout, then it break and go to the next iteration.
Example :
timeout = 60
for i in mylist:
i += 1
if time > timeout:
break
I think you can use the time module as shown here:
import time
#get the time at the start of the program
x = time.localtime(time.time())
start_time = time.strftime('%S', x)
#the loop
timeout = 5
for i in range(10000000):
i += 1
y = time.localtime(time.time())
now_time = time.strftime('%S', y)
run_time = int(now_time) - int(start_time)
print(run_time) #to see the run_time
if run_time > timeout:
break
Assuming that a single iteration doesn't take so much, just use time module and a while loop as follows:
mylist = [1,2,3]
import time
timeout = 60
time_start = time.time()
i = 0
while i < len(mylist) and time.time() - time_start < timeout:
# do your stuff
i += 1
if i == len(mylist):
# this code runs if the iteration has completed, pass does nothing
pass
else:
# and this code runs if there was a timeout
pass

Get execution time of code x amount of times

What I am trying to do is run this program, get the execution time of it, and then continue to do that 9 more times. How would I go about iterating over it to get it to print out 10 different execution times? I'm not quite sure how I need to structure the program in order to accomplish this.
import time
start_time = time.time()
def fibonacci():
previous_num, result = 0, 1
user = 1000
iteration = 10
while len(str(result)) < user:
previous_num, result = result, previous_num + result
while iteration != 0:
iteration -= 1
end = time.time()
print(start_time - end)
return result
print(fibonacci())
print("--- %s seconds ---" % (time.time() - start_time))
All you need to do is create a for loop and put your code in it.
import time
def fibonacci(start_time):
previous_num, result = 0, 1
user = 1000
iteration = 10
while len(str(result)) < user:
previous_num, result = result, previous_num + result
while iteration != 0:
iteration -= 1
end = time.time()
print(start_time - end)
return result
for i in range(0, 10):
start_time = time.time()
print(fibonacci(start_time))
print("--- %s seconds ---" % (time.time() - start_time))

Categories

Resources