Reminder for a specific time in python - python

I need to write a python program that lets me set reminders for specific times, eg 'remember to take bins out at 2pm', but I can only work out setting a reminder for a certain length of time, not for a given time. I also need to be able to set multiple reminders for multiple times.
Any help would be much appreciated :)

This looks like a homework assignment, so you need to write the code yourself.
You know what time it is now. You know when 2pm is. How much time is there between now and 2pm? Sleep for that long.
Keep a list of all pending alarms. Find the earliest alarm. Remove it from the list. Sleep until that alarm happens. Repeat
You'll probably find Step 2 easier if you use an appropriate data structure like heapq or PriorityQueue. But if the number of alarms is small, a list should do just fine.

The following checks for any new reminders every seconds,
although, after reading Frank's answer, that would be a better solution,
and the best solution is to not use Python at all, and let the operating system manage this by creating a cron job or on Windows a scheduled task.
reminders = [
# Put all of your reminders here
('2021-11-16 02:44:00', 'Take out the garbage'),
('2021-11-17 04:22:00', 'Another reminder')
]
from datetime import datetime
import time
# For performance reasons it's best to perform whatever computations we can before we go into our infinite loop
# In this case let's calculate all of the timestamps
reminders2 = {datetime.fromisoformat(reminder[0]).timestamp(): reminder[1] for reminder in reminders}
while True:
now = time.time()
for timestamp, reminder_msg in reminders2.items():
if timestamp < now:
print(reminder_msg)
del reminders2[timestamp]
# we're not in any hurry, instead of worrying about the consequences of deleting something from the same dictionary we are iterating over
# we can just break and wait for the next go around of the while loop to finish checking the remaining reminders
break
time.sleep(1) # in seconds

Related

Python keep waiting for a variable input to change (from external file ) then run by itself

Am a beginner in Python. I have a set of functions that I want Python to execute whenever the input variable (from csv file) changes.
Simply, the program execute the functions, then keep waiting to detect if csv values change, (normally it changes every 2-3 hours), then once change happened, execute again and keep to wait for the next change, and so on.
I would appreciate it if there is a simple understandable way as am beginner in Python and programming.
You can check to see if the file has changed at a given interval like so:
First, store the original version:
f = open('filename','r')
some_var = f.read()
f.close()
Then, set up a loop that will compare it at a given interval (here, ten minutes). I used the sched module, as per this answer: What is the best way to repeatedly execute a function every x seconds?
import sched, time
s = sched.scheduler(time.time, time.sleep)
def checkChange(sc, original, current):
if original != current:
# call the function that does your operation here!
s.enter(600, 1, checkChange, (sc,))
s.enter(600, 1, checkChange, (s,))
s.run()
This code is entirely untested, and probably doesn't work as intended. I just wanted to give you a logical path toward solving your problem. Also, it's likely faster to compare the hashes of the two files' contents, rather than their actual contents. Hope this helped!

Python, doing task 3 times a day while other stuff is happening?

So I have a task that occurs three times a day at a certain time that needs to be executed.
I've set up code that does this using a package called Schedule
https://pypi.python.org/pypi/schedule
What I like about this is I can say, run at 3:00AM every day, or something similar.
However, the issue is, I want my other code to be running at the same time, and not be stuck in the same loop that the Schedule is running in
So right now, it looks something like:
def archerPull():
#insert code for calling archer pull here
with open("LogsForStuffPull.txt", "a") as myfile:
myfile.write("time: " + time.ctime(time.time()))
#this is code for scheduling job to do every day
def schedulingTasks(firstTime, secondTime, thirdTime, fourthTime, fivthTime):
schedule.every().day.at(firstTime).do(archerPull)
schedule.every().day.at(secondTime).do(archerPull)
schedule.every().day.at(thirdTime).do(archerPull)
schedule.every().day.at(fourthTime).do(archerPull)
schedule.every().day.at(fivthTime).do(archerPull)
schedulingTasks("13:46", "13:47", "13:48", "13:49", "13:50")
while True:
schedule.run_pending()
time.sleep(1)
So as you can see, the loop will be True forever, and therefore run the scheduler everyday. But if I want to integrate other stuff with it, will it also be looped forever?
I want the tasks to be indivitual occuring (is asynchronous the word for it)
Please help me out, thanks!
Yeah, I figured this out the same day I asked this question
I used ap-scheduler to do this, my webapp in flask is running well while the backgrounds tasks I needed work great

Python date rollover

I'm trying to send a file after a loop completes while inside an endless loop. Everything works except the trigger for sending the file. How can I check if midnight passed when I was in the loop?
from datetime import date
while(True):
stamp = date.today()
for site in siteList:
# Long series of url requests and data processing
check = date.today()
if stamp != check: # <--- This doesn't work I don't know why
# Send today's file
As far as I can see, your code should work. Perhaps the problem lies elsewhere.
Have you tried printing stamp and check so you can see what values are being used?
Is your timezone set properly?
This is fragile and is going to cause you problems. The only way this will ever fire is if your processing actually spans midnight. This is because you update your check date every loop as well as your original date.
If you are committed to this, set the value of stamp outside the loop, and then update it inside your if block so that your send file function will always fire once per day.
However, starting a script on a machine and leaving it running for a long period of time with no supervision is just going to lead to heartache. You need some kind of job processor- I either have my webapp's work queue fire the periodic task, or if it is really external I have my Jenkins server run it- in either case I can look somewhere and see when things ran last and get notified if something goes wrong.
How can I check if midnight passed when I was in the loop?
Your code already does it if you mean the internal loop: date.today() returns only the date i.e., unless the day ends during the inner loop; stamp and check are always equal.
If you meant the outer loop then move stamp = date.today() outside of the outer loop and update stamp only on if the trigger is executed i.e., if stamp != check. btw, you should use a better names such as last_date and today. You could set last_date = None initially, to trigger the execution on the first pass.
I want it to do something once a day after the inner loop finishes
from datetime import date
last_date = None
while True: # outer loop
for site in siteList: # inner loop
"hours long computations here"
today = date.today()
if last_date is None or last_date < today:
last_date = today # jobs are executed on different days
"send today's file here"
In general, it is more flexible to separate the code that schedules a task from the code that defines the task itself e.g., you could create a cron job, to run something once a day. You could use locks, to wait for the inner loop to finish and to avoid running multiple jobs in parallel (cron doesn't protect against it). Two jobs may happen on the same day if the previous job took more than a day.

Why do my threads stop?

I have a list consisting of ID's, about 50k per day.
and i have to make 50k request per day to the server { the server is at the same city } , and fetch the information and store it into database ... i've done that using loop and Threads
and i've notice that after unknown period of time it's stop fetching and storing ...
take a look of my code fragment
import re,urllib,urllib2
import mysql.connector as sql
import threading
from time import sleep
import idvalid
conn = sql.connect(user="example",password="example",host="127.0.0.1",database="students",collation="cp1256_general_ci")
cmds = conn.cursor()
ids=[] #here is going to be stored the ID's
def fetch():
while len(ids)>0:#it will loop until the list of ID's is finish
try:
idnumber = ids.pop()
content = urllib2.urlopen("http://www.example.com/fetch.php?id="+idnumber,timeout=120).read()
if content.find('<font color="red">') != -1:
pass
else:
name=content[-20:]
cmds.execute("INSERT INTO `students`.`basic` (`id` ,`name`)VALUES ('%s', '%s');"%(idnumber,name))
except Exception,r:
print r,"==>",idnumber
sleep(0.5)#i think sleep will help in threading ? i'm not sure
pass
print len(ids)#print how many ID's left
for i in range(0,50):#i've set 50 threads
threading.Thread(target=fetch).start()
output:it will continue printing how many ID's left and at unknown moment it stops printing and fetching & storing
Both networking and threading are non-trivial... most probably the cause is a networking event that results in a hanging thread. I'd be interested to hear whether people have solutions for this, because I have suffered the same problem of threads that stop responding.
But there are some things I would definitely change in your code:
I would never catch "Exception". Just catch those exceptions that you know how to deal with. If a network error occurs in one of your threads, you could retry rather than giving up on the id.
There is a race condition in your code: you first check whether there is remaining content, and then you take it out. At the second point in time, the remaining work may have disappeared, resulting in an exception. If you find this difficult to fix, there is a brilliant python object that is meant to pass objects between threads without race conditions and deadlocks: the Queue object. Check it out.
The "sleep(0.5)" is not helping threading in general. It should not be necessary. It may reduce the chance of hitting race conditions, but it is better to program race conditions totally out. On the other hand, having 50 threads at full spead banging the web server may not be a very friendly thing to do. Make sure to stay within the limits of what the service can offer.

Python : Running a loop during a precise duration

I need to run a loop during a precise duration. For example, the code I'm trying to make would look like that :
initialize and lauch timer
while timer<10000sec:
do things
Do you know how to do this ?
Thank you :)
stop = time.time()+10000
while time.time() < stop:
do things
This requires that each run through the loop is sufficiently short so that you read the current time often enough (for the preciseness that you want to achieve).

Categories