How to match current date and specific date in Python - 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()

Related

Detect long-press using Keybow

I'm trying to use this python library https://github.com/pimoroni/keybow-python to control a raspberry pi (initiate events, e.g. launch a script or shutdown the pi).
This works will so far. I'm struggling to detect a long press. The API linked above allows 'catching' the event of pressing the button or releasing it. Not sure how I go about measuring the time between one and the other... I tried this:
`
def time_string_to_decimals(time_string):
fields = time_string.split(":")
hours = fields[0] if len(fields) > 0 else 0.0
minutes = fields[1] if len(fields) > 1 else 0.0
seconds = fields[2] if len(fields) > 2 else 0.0
return float(hours) + (float(minutes) / 60.0) + (float(seconds) / pow(60.0, 2))
while True:
t = datetime.now().strftime('%H:%M:%S')
now = time_string_to_decimals(t)
#keybow.on()
def handle_key(index, state):
key0Up = 0
key0Down = 0
if index == 0 and state:
key0Down = now
print ("down: " + str(now))
if index == 0 and not state:
key0Up = now
downtime = key0Up - key0Down
print ("down: " + str(now))
print ("up: " + str(now))
print ("downtime: " + str(downtime))
if downtime >= 0.001:
print ("shutdown!")
if index == 3 and not state:
print ("Hello!")
if index == 6 and not state:
print ("World!")
`
... the print commands are just to follow what's going on. The problem is that the key0Down also get's set to the current time when the button is released. I'm stumped. Can anyone point me in the right direction?
Thanks!
Best regards,
Andrew
See above... I keep getting the same 'timestamp' for the key Down und key Up event...
It sounds like your issue is that when the #keybow.on decorator attaches the callback it has a static value for now that doesn't get updated by the while loop which will be in a different scope. Repeatedly declaring the callback during the while loop looks wrong also.
I don't have this hardware so it is not possible for me to test this. However, looking through the repository you linked to I would be tempted to do the following...
As you need to share the key events timings between functions I would put them into a class and have class variables for the key0up and key0down values.
I have also gone for different event handlers for the different keys to simplify the complex chain of if statements.
I was not sure if the keybow on decorator would do the right thing if used inside a class, so I have attached callbacks to keys without using a decorator.
import keybow
import time
class MyKeys:
key0Up = 0
key0Down = 0
def handle_key0(self, index, state):
if state:
self.key0Down = time.time()
print("down: ", self.key0Down)
elif not state:
self.key0Up = time.time()
downtime = self.key0Up - self.key0Down
print("down: ", self.key0Down)
print("up: ", self.key0Up)
print("downtime: ", downtime)
if downtime >= 1: # Greater than 1 second
print("shutdown!")
def handle_key3(self, index, state):
if not state:
print("Hello!")
def handle_key6(self, index, state):
if not state:
print("World!")
def main():
my_keys = MyKeys()
keybow.on(0, my_keys.handle_key0)
keybow.on(3, my_keys.handle_key3)
keybow.on(6, my_keys.handle_key6)
while True:
keybow.show()
time.sleep(1.0 / 60.0)
if __name__ == '__main__':
main()

Where to insert a loop/timer?

I need to insert a loop to ensure that the following runs and appends to the txt file every hour and I am stuck on where to properly put the loop.
thanks in advance.
from datetime import datetime
from threading import Timer
def log(self, LOG_TAG, LOG_MESSAGE):
print('{}: {}'.format(LOG_TAG, LOG_MESSAGE))
now = datetime.utcnow()
print(now)
year = now.year
day = now.day
month = now.month
print('year = {}, month = {}, day = {}'.format(year, month, day))
with open('log_{}_{}_{}.txt'.format(year, month, day), 'a+') as f:
f.write('{} \t {}: {} \n'.format(now, LOG_TAG, LOG_MESSAGE))
if __name__ == "__main__":
log = Spider_Log()
tag = 'SPIDERLOG'
log.log(tag, 'test2')
You can use a different thread to keep track of time. Once the set interval of time has lapsed, it would trigger an event. Another thread can wait for this event and do the part of printing to the log file. You can refer to the following code -
import threading, time
from _datetime import datetime
def thread_to_keep_time(event):
while True:
#Set it to 10 seconds for testing.
time.sleep(10)
event.set()
def thread_to_trigger(event):
print("Waiting for event")
while True:
if event.wait():
now = datetime.now()
print('Print log at ' , now)
timer_event.clear()
timer_event = threading.Event()
threading.Thread(target=thread_to_keep_time, args=[timer_event]).start()
threading.Thread(target=thread_to_trigger, args=[timer_event]).start()
# wait for all threads to exit
for t in threading.enumerate():
if t != threading.current_thread():
t.join()

Why isn't my alarm code printing the message at the end?

So I'm fairly new to Python and I am trying to write a code for a timer. My code is supposed to get the hour, minute, whether it's AM or PM, and a message that they want the program to print out when their timer is done. As of now, the program asks several questions and stores them in variables, but doesn't print out the message when it is done.
I have tried looking at each part of the code and the code is fairly simple so I don't understand why this is occurring.
# Set up variables
hour = int(input('What should the hour be? '))
minute = input('What should the minute be? ')
ampm = input('A.M. or P.M.? ')
if (ampm == 'A.M.'):
if (hour == 12):
hour = 0
else:
hour = hour
if (ampm == 'P.M.'):
if (hour == 12):
hour = hour
else:
hour = hour + 12
message = input('What should the message be? ')
import datetime
current_hour = datetime.datetime.today().strftime('%H')
current_minute = datetime.datetime.today().strftime('%M')
alarm = True
# Set up loop
while (alarm):
if (hour != datetime.datetime.today().strftime('%H')):
alarm = True
else:
if (minute == datetime.datetime.today().strftime('%M')):
print(message)
alarm = False
else:
alarm = True
It is supposed to print out the message that the user inputted. It's not doing that.
The variable of hour returns an int value and datetime.datetime.today().strftime('%H') returns string so your program get in the infinite loop.Change condition like
if (hour != int((datetime.datetime.today().strftime('%H')))):

Python 2.7 .datetime.datetimenow() and datetime.timedelta()

I have this following code and am stuck in the while loop
I know there is a problem with the while datetime.datetime.now() < (datetime.datetime.now() + datetime.timedelta(minutes=wait_time)): line.
Can anyone help please ?
nodes_with_scanner = []
wait_time = 60
while datetime.datetime.now() < (datetime.datetime.now() + datetime.timedelta(minutes=wait_time)):
nodes_with_scanner = get_nodes_with_scanner_in_dps(self.node_names, scanner_id, username=self.users[0].username)
log.logger.debug("Number of pre-defined {0} scanners detected in DPS: {1}/{2}".format(scanner_type, len(nodes_with_scanner), len(self.node_names)))
if state == "create":
if len(self.node_names) == len(nodes_with_scanner):
log.logger.debug("All {0} pre-defined scanners with id '{1}' have been successfully created in DPS for nodes '{2}'".format(scanner_type, scanner_id, ", ".join(self.node_names)))
return
elif state == "delete":
if len(nodes_with_scanner) < 1:
log.logger.debug("All {0} pre-defined scanners with id '{1}' have been successfully deleted in DPS for nodes '{2}'".format(scanner_type, scanner_id, ", ".join(self.node_names)))
return
log.logger.debug("Still waiting on some {0} pre-defined scanners to '{1}' in DPS; sleeping for 1 minute before next check".format(scanner_type, state))
time.sleep(60)
You are asking if the current time is smaller than the current time plus a delta. Of course that's going to be true each and every time, the future is always further away into the future.
Record a starting time once:
start = datetime.datetime.now()
while datetime.datetime.now() < start + datetime.timedelta(minutes=wait_time)):
If wait_time doesn't vary in the loop, store the end time (current time plus delta):
end = datetime.datetime.now() + datetime.timedelta(minutes=wait_time))
while datetime.datetime.now() < end:
It may be easier to just use time.time() here:
end = time.time() + 60 * wait_time
while time.time() < end:
You use datetime.datetime.now() in your while loop, what means each iteration you check if the time now is lower then the time now + delta.
That logically wrong, because it will be True forever as the time now will be always lower than the time now plus delta.
You should change it to this:
time_to_start = datetime.datetime.now()
while datetime.datetime.now() < (time_to_start + datetime.timedelta(minutes=wait_time)):
print "do something"

Stopping Stopwatches

I am trying to create a stopwatch that starts and stops through the user pressing the enter. Once to start and again to stop. The start works perfectly but the stopping section is not working. I've tried creating a variable called stop that is like so:
stop = input("stop?")
But it's still not working.
import time
def Watch():
a = 0
hours = 0
while a < 1:
for minutes in range(0, 60):
for seconds in range(0, 60):
time.sleep(1)
print(hours,":", minutes,":", seconds)
hours = hours + 1
def whiles():
if start == "":
Watch()
if start == "":
return Watch()
def whiltr():
while Watch == True:
stop = input("Stop?")
#Ask the user to start/stop stopwatch
print ("To calculate your speed, we must first find out the time that you have taken to drive from sensor a to sensor b, consequetively for six drivers.")
start = input("Start?")
start = input("Stop")
whiles()
Perhaps all you need is something simple like:
import time
input('Start')
start = time.time()
input('Stop')
end = time.time()
print('{} seconds elapsed'.format(end-start))
Should probably use the time function instead of
def Watch():

Categories