python threading.Timer(second, func).start() - python

import threading
import datetime
def showA():
now = datetime.datetime.utcnow() + datetime.timedelta(hours=9)
now_time = datetime.time(now.hour,now.minute,now.second)
a = 'timer_checking...'
print(f'{a} {now_time}')
second = 5
threading.Timer(second, showA).start()
showA()
This code shows me 'timer_checking.. 11:11:27'
second will add +5 for good.
I want to make showA() operate
first 5 seconds
second 4 seconds
third 3 seconds
fourth 2 seconds
fifth 1 second
second == 0
start again 5 seconds.
please Help me.

timer interval change after per operate, so interval must be an argument.
well, showA create a thread for each operate, thread is costly. showA2 may be better.
import threading
import datetime
# I want to make showA() operate
# first 5 seconds second 4 seconds third 3 seconds fourth 2 seconds fifth 1 second, second == 0 start again 5 seconds.
def loop_interval(old_interval):
if old_interval == 1:
return 5
return old_interval - 1
def showA(interval):
now = datetime.datetime.utcnow() + datetime.timedelta(hours=9)
now_time = datetime.time(now.hour, now.minute, now.second)
a = 'timer_checking...'
print(f'{a} {now_time}')
threading.Timer(interval, showA, args=(loop_interval(interval),)).start()
def showA2():
threading.Thread(target=_show).start()
def _show():
e = threading.Event()
interval = 5
while 1:
e.wait(interval)
now = datetime.datetime.utcnow() + datetime.timedelta(hours=9)
now_time = datetime.time(now.hour, now.minute, now.second)
a = 'timer_checking...'
print(f'{a} {now_time}')
interval = loop_interval(interval)
if __name__ == '__main__':
showA(5)
# showA2()
print(1)

Related

How do I receive the updated time every time it is called in this function?

import time
seconds = time.time()
local_time = time.ctime(seconds)
print("Start Time:", local_time)
def bot():
x = 0
while x < 16:
time.sleep(1)
print("Time:", local_time)
x += 1
When I run this code it prints the initial time take before the function every time, I would like it to show the updated time every time local time is printed, can someone point me in the right direction?
Using a variable will not re-evaluate it. You'll need to calculate the time again each loop iteration
import time
def bot():
for x in range(16):
time.sleep(1)
seconds = time.time()
local_time = time.ctime(seconds)
print("Time:", local_time)
bot()

EOF error while taking input using multiprocessing

I am making a stop watch in python which prints out the seconds passed and as soon as the user presses enter, it stops.
I am using multiprocessing to ask for an input and keep printing until an input is received. but the code is giving an EOF error for the input statement when I run it, what am I doing wrong?
import os
import multiprocessing
end = multiprocessing.Value('i',0)
def get_input(end):
x = input('')
end.value = 1
def print_time(end):
secs = 0
mins = 0
hrs = 0
x = input('start: ')
while True:
mins, secs = divmod(secs, 60)
hrs = 0
if mins > 60:
hrs, mins = divmod(mins, 60)
timer_display = '{:02d}:{:02d}:{:02d}'.format(hrs, mins, secs)
print(timer_display)
if end.value == 1:
break
time.sleep(1)
secs += 1
if __name__ == "__main__":
func1 = multiprocessing.Process(target = get_input, args = (end,))
func2 = multiprocessing.Process(target = print_time, args = (end,))
func1.start()
func2.start()
func1.join()
func2.join()
It's probably better to start/stop the stopwatch in the main program and just use one Process to display the timer. Something like this:
from multiprocessing import Process, Value
import time
def showTime(end):
start = time.time()
while end.value == 0:
elapsed = int(time.time() - start)
ss = elapsed % 60
mm = elapsed // 60 % 60
hh = elapsed // 3600
print(f'{hh:02d}:{mm:02d}:{ss:02d}')
time.sleep(1)
def main():
input('Press enter to start: ')
end = Value('i', 0)
Process(target=showTime, args=(end,)).start()
input('Press enter to stop: ')
end.value = 1
if __name__ == '__main__':
main()
Also, this technique allows for any potential drift due to processing time

How to match current date and specific date in Python

I'm developing a reminder app in Python. My question is when I execute my code. It should wait until current date equals to specific date. But it's not working, here's my code.
CODE:
from threading import Thread
from datetime import datetime, timedelta
# Current date, 8/15/2020 - 10:00
a = datetime.now()
# Specific date (1 minute later from current date), 8/15/2020 - 10:01
b = a + timedelta(minutes = 1)
# Reminder name
d = "stack reminder"
# Reminder list
c = {}
# Target function
def createThread():
while True:
if(b.second == a.second and
b.minute == a.minute and
b.hour == a.hour and
b.day == a.day and
b.month == a.month and
b.year == a.year):
print("worked")
# If thread name in reminder list
if d in c:
print("canceling")
t.cancel()
break
# Set thread and thread name and print thread name
t = Thread(target = createThread)
t.setName(d)
print(t.getName())
# Append reminder name to reminder list and print
c[d] = b
print(c)
# Start thread
t.start()
This code isn't working. Is if statement wrong? I'm creating Thread because while program waiting for specific date, I want to do different things. Where is my fault and how to run this code?
You are never updating the a variable again.
datetime.now() doesn't constantly update so you will have to call this in your thread.
a = datetime.now() in every iteration of your while loop.
At the moment you are never getting get your if condition to match as the time in a stays in the past.
Also you should be able to simplify this.
(b.second == a.second and
b.minute == a.minute and
b.hour == a.hour and
b.day == a.day and
b.month == a.month and
b.year == a.year):
To just simply
if b == a:
As both should be datetimes.
But its probably better to do use > in your condition as by using == you would have to match to the millisecond. Even matching to the second could cause issues and the condition might be missed.
i.e
If "a" (i.e the current time) >= "b" the time you want to check for.
Then fire the condition.
or put another way... If the current time is greater than or equal to the calendar entry time - then its time to alert the user.
if a >= b:
Complete Example:
from threading import Thread
from datetime import datetime, timedelta
# Current date, 8/15/2020 - 10:00
# Specific date (1 minute later from current date), 8/15/2020 - 10:01
b = datetime.now() + timedelta(minutes = 1)
# Reminder name
d = "stack reminder"
# Reminder list
c = {}
# Target function
def createThread():
while True:
a = datetime.now()
if a > b :
print("worked")
# If thread name in reminder list
if d in c:
print("canceling")
t.cancel()
break
# Set thread and thread name and print thread name
t = Thread(target = createThread)
t.setName(d)
print(t.getName())
# Append reminder name to reminder list and print
c[d] = b
print(c)
# Start thread
t.start()

Python if condition true for x amount of time

I would like to create a condition that only gets executed if a is True for more than 3 seconds. I would like it to work like this.
if a == True for more than 3 seconds:
dosomething
If you want to check if the value hasn't change for 3 seconds.
import time
id_a_old = id(a)
time.sleep(3)
id_a_new = id(a)
if id_a_old == id_a_new: # assumes that a is initially true
dosomething
Since bool type is immutable the object id changes if it gets changed.
If you want to check if is has changed after 3 seconds do the following. If any thread changes a within 3 seconds it will capture that.
import time
time.sleep(3)
if a:
dosomething
Simple solution (motivated from Marlon Abeykoon's solution):
import time
startTime = time.time()
while a == True:
endTime = time.time()
#do other stuff
if (endTime - startTime > 3):
print("Longer than 3 seconds")
break
import time
a = True
x = int(time.time())
xa = a
while 1:
if a == True and xa == a and int(time.time()) == x + 3:
# dosomething
print "A is True for 3 seconds"
break
if(xa != a):
# dosomething
print "Value of alfa changed from %s to %s in less than 3 seconds" %(xa, a)
break

Creating a timer in python

import time
def timer():
now = time.localtime(time.time())
return now[5]
run = raw_input("Start? > ")
while run == "start":
minutes = 0
current_sec = timer()
#print current_sec
if current_sec == 59:
mins = minutes + 1
print ">>>>>>>>>>>>>>>>>>>>>", mins
I want to create a kind of stopwatch that when minutes reach 20 minutes, brings up a dialog box, The dialog box is not the problem. But my minutes variable does not increment in this code.
See Timer Objects from threading.
How about
from threading import Timer
def timeout():
print("Game over")
# duration is in seconds
t = Timer(20 * 60, timeout)
t.start()
# wait for time completion
t.join()
Should you want pass arguments to the timeout function, you can give them in the timer constructor:
def timeout(foo, bar=None):
print('The arguments were: foo: {}, bar: {}'.format(foo, bar))
t = Timer(20 * 60, timeout, args=['something'], kwargs={'bar': 'else'})
Or you can use functools.partial to create a bound function, or you can pass in an instance-bound method.
You can really simplify this whole program by using time.sleep:
import time
run = raw_input("Start? > ")
mins = 0
# Only run if the user types in "start"
if run == "start":
# Loop until we reach 20 minutes running
while mins != 20:
print(">>>>>>>>>>>>>>>>>>>>> {}".format(mins))
# Sleep for a minute
time.sleep(60)
# Increment the minute total
mins += 1
# Bring up the dialog box here
I'd use a timedelta object.
from datetime import datetime, timedelta
...
period = timedelta(minutes=1)
next_time = datetime.now() + period
minutes = 0
while run == 'start':
if next_time <= datetime.now():
minutes += 1
next_time += period
Your code's perfect except that you must do the following replacement:
minutes += 1 #instead of mins = minutes + 1
or
minutes = minutes + 1 #instead of mins = minutes + 1
but here's another solution to this problem:
def wait(time_in_seconds):
time.sleep(time_in_seconds) #here it would be 1200 seconds (20 mins)
mins = minutes + 1
should be
minutes = minutes + 1
Also,
minutes = 0
needs to be outside of the while loop.
I want to create a kind of stopwatch that when minutes reach 20 minutes, brings up a dialog box.
All you need is to sleep the specified time. time.sleep() takes seconds to sleep, so 20 * 60 is 20 minutes.
import time
run = raw_input("Start? > ")
time.sleep(20 * 60)
your_code_to_bring_up_dialog_box()
# this is kind of timer, stop after the input minute run out.
import time
min=int(input('>>'))
while min>0:
print min
time.sleep(60) # every minute
min-=1 # take one minute
import time
...
def stopwatch(mins):
# complete this whole code in some mins.
time.sleep(60*mins)
...
import time
mintt=input("How many seconds you want to time?:")
timer=int(mintt)
while (timer != 0 ):
timer=timer-1
time.sleep(1)
print(timer)
This work very good to time seconds.
You're probably looking for a Timer object: http://docs.python.org/2/library/threading.html#timer-objects
Try having your while loop like this:
minutes = 0
while run == "start":
current_sec = timer()
#print current_sec
if current_sec == 59:
minutes = minutes + 1
print ">>>>>>>>>>>>>>>>>>>>>", mins
import time
def timer(n):
while n!=0:
n=n-1
time.sleep(n)#time.sleep(seconds) #here you can mention seconds according to your requirement.
print "00 : ",n
timer(30) #here you can change n according to your requirement.
import time
def timer():
now = time.localtime(time.time())
return now[5]
run = raw_input("Start? > ")
while run == "start":
minutes = 0
current_sec = timer()
#print current_sec
if current_sec == 59:
mins = minutes + 1
print ">>>>>>>>>>>>>>>>>>>>>", mins
I was actually looking for a timer myself and your code seems to work, the probable reason for your minutes not being counted is that when you say that
minutes = 0
and then
mins = minutes + 1
it is the same as saying
mins = 0 + 1
I'm betting that every time you print mins it shows you "1" because of what i just explained, "0+1" will always result in "1".
What you have to do first is place your
minutes = 0
declaration outside of your while loop. After that you can delete the
mins = minutes + 1
line because you don't really need another variable in this case, just replace it with
minutes = minutes + 1
That way minutes will start off with a value of "0", receive the new value of "0+1", receive the new value of "1+1", receive the new value of "2+1", etc.
I realize that a lot of people answered it already but i thought it would help out more, learning wise, if you could see where you made a mistake and try to fix it.Hope it helped. Also, thanks for the timer.
from datetime import datetime
now=datetime.now()
Sec=-1
sec=now.strftime("%S")
SEC=0
while True:
SEC=int(SEC)
sec=int(sec)
now=datetime.now()
sec=now.strftime("%S")
if SEC<sec:
Sec+=1
SEC=sec
print(Sec) #the timer is Sec

Categories