How to find the duration between two 'true' values in a loop - python

I want to find out the charging duration between when the loop finds its first value of '1' and the last value of '1' it detects. I figured out how to find out the duration between 2 timings, but i am unsure of where i can put the 'timestamp' variable.
Here is my current code
from datetime import datetime
#Duration loop
date_format_str = '%H:%M:%S %p'
foundEnd = False
for i in range(len(dfDur01Mar22)):
#only display bus 'SG3079S'
if dfDur01Mar22.iloc[i,1] == 'SG3079S':
#print 'end' when first '0' appears
if not foundEnd and dfDur01Mar22.iloc[i,2] == 0:
print('end')
foundEnd = True
#prints the first time its 0
timestamp = dfDur01Mar22.DateTime[i]
#print(timestamp + " first")
#if charging type is 1
elif dfDur01Mar22.iloc[i,2] == 1:
print(dfDur01Mar22.iloc[i,0],dfDur01Mar22.iloc[i,1],dfDur01Mar22.iloc[i,2])
foundEnd = False
timestamp_2 = dfDur01Mar22.DateTime[i]
#print(timestamp_2 + "last")
#Duration between the first '1' and the last '1' detected
given_time = datetime.strptime(timestamp, date_format_str)
given_time2 = datetime.strptime(timestamp_2, date_format_str)
total = given_time2 - given_time
#print(total)
and here is the values that i need to find the duration from

You need 2 variables like start_time , end_time . after your loop you can calculate this duration.
So new concept of your code is like below .
FOUND_1_SITUATION is your '1' condition in your loop.
from datetime import datetime
#Duration loop
date_format_str = '%H:%M:%S %p'
foundEnd = False
start_time = False
end_time = False
for i in range(len(dfDur01Mar22)):
if FOUND_1_SITUATION and not start_time:
start_time = dfDur01Mar22.DateTime[i]
else :
end_time = dfDur01Mar22.DateTime[i]
duration_between_start_end = end_time - start_time
It means whenever your loop is on '1' condition start_time will be initialized once. in other conditions end_time will be updated till end of loop.
After all , you can put duration_between_start_end calculation below your loop.

Related

TypeError: '>=' not supported between instances of 'str' and 'tuple'

It works if I type if int(hour) >= 19: but I would like it to work with something similar to this line if current_time >= exit_time:
import time
current_time = time.strftime('%H:%M:%S')
exit_time = ('19:00:00','%H:%M:%S')
hour = time.strftime('%H')
minute = time.strftime('%M')
second = time.strftime('%S')
if current_time >= exit_time:
print ("It's time to go home")
else:
print ("{} hours, {} minutes and {} seconds to go home".format(18-int(hour),
59-int(minute), 59-int(second)))
Notice that you're comparing current_time (which is a string) and exit_time (which is a tuple containing 2 strings).
Maybe try something like:
if current_time >= exit_time[0]:
# your code
Since the first member of the tuple is probably what you want to compare to current_time.
Hope this helps!
The best alternative to this is.
from datetime import datetime
current_time = datetime.now().replace(microsecond=00)
exit_time = current_time.replace(hour=19, minute=00, second=00, microsecond=00)
if current_time >= exit_time:
print ("It's time to go home")
else:
time_delta = (exit_time - current_time).total_seconds()
hours_left = int(time_delta // 60 // 60)
minutes_left = int(time_delta // 60) - hours_left*60
seconds_left = int(time_delta) - hours_left*3600 - minutes_left*60
print ("{} hours, {} minutes and {} seconds to go home".format(hours_left,
minutes_left, seconds_left))

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)

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

Don't understand this timed while loop attribute error

So I have been trying to make a while loop that will run for 10 minutes. But is keeps erroring out on the line with the while loop. It says 'str' object has no attribute 'time'.
I have discovered that if i remove the lines with now.strftime() in them that the code runs but I don't know why it runs without those lines or how to fix it.
I did also try to do something using the datetime module instead of importing the time module but this also fails.
import math
from datetime import datetime
import time
test_num = 1
largest_loop = 0
delay = 60 * 10
end_time = time.time() + delay
def even_number(value):
if value == 2:
return True
def divide_five(value):
if value == 5:
return True
def is_square(value):
if math.sqrt(value).is_integer():
return False
def multiple_of(value):
if value == 2:
return True
def is_happy():
global check
if check == 1:
return True
while time.time() <= end_time:
test_num += 1
check = test_num
now = datetime.now()
loop_counter = 0
record_loop = 6
date = now.strftime("%m/%d/%Y")
time = now.strftime("%H:%M:%S")
if even_number(test_num) == True:
if divide_five(test_num) == True:
if is_square(test_num) == True:
for _ in range(record_loop + 4):
loop_counter += 1
if is_happy() == True:
if multiple_of(test_num) == True:
#print(test_num)
record_loop = loop_counter
break
else:
pass
else:
pass
else:
pass
else:
pass
else:
pass
As #CoryKramer pointed out, you named a variable time, which is also the name of the module you are importing. All I really did was change the time variable to something like currTime. Try the code below (runs for me):
import math
from datetime import datetime
import time
test_num = 1
largest_loop = 0
delay = 60 * 10
end_time = time.time() + delay
def even_number(value):
if value == 2:
return True
def divide_five(value):
if value == 5:
return True
def is_square(value):
if math.sqrt(value).is_integer():
return False
def multiple_of(value):
if value == 2:
return True
def is_happy():
global check
if check == 1:
return True
while time.time() <= end_time:
test_num += 1
check = test_num
now = datetime.now()
loop_counter = 0
record_loop = 6
date = now.strftime("%m/%d/%Y")
currTime = now.strftime("%H:%M:%S")
if even_number(test_num) == True:
if divide_five(test_num) == True:
if is_square(test_num) == True:
for _ in range(record_loop + 4):
loop_counter += 1
if is_happy() == True:
if multiple_of(test_num) == True:
#print(test_num)
record_loop = loop_counter
break
else:
pass
else:
pass
else:
pass
else:
pass
else:
pass
Additionally, consider reading up on:
How to name a module without conflict with variable name?
https://en.wikipedia.org/wiki/Variable_shadowing
dont name your variable in your while loop time when you import the time library:
time = now.strftime("%H:%M:%S")
in your while loop you want to use the time function of the time library but as soon as you run the while loop once it will try to use time() on the string time you defined in the while loop.
I think the problem is here:
time = now.strftime("%H:%M:%S")
Thus, you converted time into a string variable. Name this variable in a different way!
Apart from this, running for 10 minutes at "full throttle" is a lot! Consider to introduce a "sleep" time at the end of the while loop (just suggesting)

Categories

Resources