How to use Schedule module with a conditional while loop in Python - python

I'm trying to use the Schedule module to run a task during specific days of the week and specific hours, basically business hours. The while loop will work when the condition is true but once it's false it will not run again to see if the time frame still applies. I would have to restart the script for it to work.
I'm pretty new to Python and self taught. This is my first time posting here so please correct me if I've formatted this badly or haven't included enough information. I've tried scouring the forums to get around this particular issue I'm having but haven't found an answer; I'm probably searching wrong. It may be a simple issue but I've been wracking my brain for a few days. This is a small test portion of code that I'm trying to use for another script. Other people have recommended Cron but since this is going into a larger script, I only need a section of it to run on a task and not the whole thing.
from datetime import datetime as dt
import schedule
import time
def weekdayJob(x, i=None):
week = dt.today().weekday()
if i is not None and week < 5 and dt.now().hour in range(9,17):
schedule.every(i).minutes.do(x)
def printJob():
timestamp = time.strftime("%Y%m%d-%H%M")
print(f"test {timestamp}\n")
weekdayJob(printJob, 5)
while True:
schedule.run_pending()
time.sleep(5)
I've also tried
from datetime import datetime as dt
import schedule
import time
def weekdayJob(x, i=None):
week = dt.today().weekday()
if i is not None and week < 5 and dt.now().hour in range(9,17):
schedule.every(i).minutes.do(x)
def printJob():
timestamp = time.strftime("%Y%m%d-%H%M")
print(f"test {timestamp}\n")
x = 1
while x == 1:
weekdayJob(printJob, 1)
time.sleep(5)
while True:
schedule.run_pending()
time.sleep(5)
I figured that putting the scheduled job in the while loop would make it constantly check to see if the conditional statement was true but that doesn't seem the case. How would I make it so this script is constantly checking if weekdayJob is within the desired time frame so I don't have to restart the script.

Move the conditional statement into the printjob function, and do not use nested while loop (code here switches between business hours and non business hours). schedule tasks run continuously, but your function if-statement only runs during your defined business hours. Here running at 1minute interval (testing odd vs even minutes), you can spec your own business hours:
import datetime as dt
import schedule, time
from datetime import datetime
def printJob():
week = dt.datetime.today().weekday()
timestamp = time.strftime("%Y%m%d-%H%M")
if week < 5 and datetime.now().minute % 2 ==0: # in range(9,17):
print(f"business hours test...EVEN minutes... {timestamp}\n")
# your business hours function here...
else:
print(f'go home...test... ODD minutes... {timestamp}\n')
schedule.every(1).minute.do(printJob)
while True:
schedule.run_pending()

Related

Python - Schedule: Run function every hour + "on the hour"

I'm trying to use the schedule module to do some basic scheduling in a continuously updating script.
Is there a way to set a schedule to run every "x" hours, 'on the hour'?
For example, I'd like to have a function that runs at: [1:02pm, 2:02pm, 3:02pm, 4:02pm] regardless of when I run the script in the first place. In other words, simply doing "schedule.every(1).hours.' doesn't work because I can't guarantee what time the script is run in the first place.
Thanks!
Here you can find examples for case you trying to achieve.
schedule.every().hour.at(":02").do(job)
Here is a simple script:
from datetime import datetime
import time
# scheduled hours in 24-hour format
hours = ["13:2", "14:2", "15:2", "16:2"]
# your function
def foo():
pass
while True:
now = datetime.now() # gets current datetime
hour = str(now.hour) # gets current hour
minute = str(now.minute) # gets current minute
current_time = f"{hour}:{minute}" # combines current hour and minute
# checks if current time is in the hours list
if current_time in hours:
foo()
time.sleep(60) # waits a minute until it repeats
Please note that it will check every minute at the same time when you ran it, and not when the new minute starts. (For instance, if you run it in the middle of the minute, it will check again in the middle of the next minute)

How can I say to Python to do an instruction at a given time?

I want that a specific time of the day (for example 10:00:00), one of my if condition activates.
For example:
if time is 10:00:00:
print("Hello world")
Imortant: I already read this: Python script to do something at the same time every day
But I don't want to use a function!
If you do not one to use a function but need to run a simple script at certain times, you may use crons/job schedulers for this.
Windows and Linux both supports cron operations.
If you want to do this programmatically instead of relying on operating system tools you need to write a service or a long running process for it.
You could easy use datetime to help you with that.
import datetime
from time import sleep
timing = [10, 0, 0] # Hour, minute, second, in 24 hour time
while True: # Repeat forever
now = datetime.datetime.now()
data = [now.hour, now.minute, now.second]
if data == timing:
# Code to be executed
print("Hello World")
#######
sleep(1) # To ensure the command is not repeated again
# break # Uncomment this if you want to execute the command only once
Make sure that I indented it properly, because one space can tick python off :).
The way that it works:
import datetime and from time import sleep import the necessary modules and functions that you will need.
Modules needed:
datetime
time.sleep
Now we're set.
timing = [10,0,0] sets the time that you want to use (you'll see why later)
while True repeats the loop... on and on and on.
now = datetime.datetime.now() creates a shortcut for such a long piece of text.
data == timing makes sure the time matches the timing you asked.
Note that the timing is in UTC
Go to Getting the correct timezone offset in Python using local timezone to know how to find your offset.
An offset of UTC-0200 (Or -7200 seconds) means that you need to ADD 2 hours to your time to get UTC. Or, if your time zone is UTC+0200, SUBSTRACT 2 hours from your time.

How do I activate a python program at exact whole hours? (12:00:00pm, 04:00:00am)

I want to write a program that keeps running in the background and performs a certain task at each hour of the day. How do I achieve this?
for production i would add cron or schedule
# Schedule Library imported
import schedule
import time
# Functions setup
def sudo_placement():
print("Get ready for Sudo Placement at Geeksforgeeks")
def good_luck():
print("Good Luck for Test")
def work():
print("Study and work hard")
def bedtime():
print("It is bed time go rest")
def geeks():
print("Shaurya says Geeksforgeeks")
# Task scheduling
# After every 10mins geeks() is called.
schedule.every(10).minutes.do(geeks)
# After every hour geeks() is called.
schedule.every().hour.do(geeks)
# Every day at 12am or 00:00 time bedtime() is called.
schedule.every().day.at("00:00").do(bedtime)
# After every 5 to 10mins in between run work()
schedule.every(5).to(10).minutes.do(work)
# Every monday good_luck() is called
schedule.every().monday.do(good_luck)
# Every tuesday at 18:00 sudo_placement() is called
schedule.every().tuesday.at("18:00").do(sudo_placement)
# Loop so that the scheduling task
# keeps on running all time.
while True:
# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
time.sleep(1)
You can write a if condition in a infinite while loop to check if current time is equals to your time say (12:00:00pm, 04:00:00am) or you can make use of the sleep method, it stops the exexution of your code for the specified amount of time, you must find that by calculating the difference between your time and the current time and this method does not consume much memory and cpu cycles like the previous method.
I'd advise setting up a cron job to run your python program at specific time
Try this:
from datetime import datetime # Import datetime
def schedule(time, function): # Syntax:
cur_time = datetime.strftime("%T") # time: 24 hour time hh:mm:ss (09:00:00 or 21:00:00)
if cur_time == time: # function: lampda: to_execute()
function()
def scheduled_function():
print("TEST")
while True:
schedule("15:00:00", lampda:scheduled_function()) # Schedule scheduled_function() to execute at 3:00 pm

Run python script every 5 minutes on the clock

I'm busy with an python script on a raspberry pi for a rain gauge.
The script need to count the tips of the bucket and write the total rain amount every 5 minutes to a csv file. The script does the writing now every 299.9 seconds but I want it to write every exact 5 minutes, for example: 14:00, 14:05, 14:10 and so on.
Is there anyone who could help me out?
Thanks in advance!
Use a cronjob, for raspberry pi go with crontab
https://www.raspberrypi.org/documentation/linux/usage/cron.md
You will find lots of helpful functions in the datetime module:
from datetime import datetime, timedelta
# Bootstrap by getting the most recent time that had minutes as a multiple of 5
time_now = datetime.utcnow() # Or .now() for local time
prev_minute = time_now.minute - (time_now.minute % 5)
time_rounded = time_now.replace(minute=prev_minute, second=0, microsecond=0)
while True:
# Wait until next 5 minute time
time_rounded += timedelta(minutes=5)
time_to_wait = (time_rounded - datetime.utcnow()).total_seconds()
time.sleep(time_to_wait)
# Now do whatever you want
do_my_thing()
Note that when do_my_thing() is called it will actually be fractionally after the exact time in time_to_round, because obviously computers can't do work in precisely zero time. It's guaranteed not to wake up before that time though. If you want to refer to the "current time" in do_my_thing(), pass in the time_rounded variable so that you get neat timestamps in your log file.
In the code above I've deliberately recomputed time_to_wait each time, rather than just setting it to 5 minutes after the first time. That's so that the slight delay I just mentioned don't gradually snowball after you've been running the script for a long time.

most efficient way to check for a specific time

So what I am trying to do is have a bit of code check the time and at a a given time do something, the current part I am working on is small but I want it to run as efficiently as possible because the program will be running for long amounts of time when its finished. I've noticed on on task manager when I run a file with only the bit of code I will show soon my cpu usage is over 15% with an i7 7700 cpu, is there any way to make this code more efficient?
import datetime
import webbrowser
#loop to run until desired time
while True:
#checks current time to see if it is the desired time
if str(datetime.datetime.now().time()) == "11:00:00":
#opens a link when its the desired time
webbrowser.open('https://www.youtube.com/watch?v=q05NxtGgNp4')
break
If your program can remain idle until calling the browser, you can use sleep, for the time difference between now and 11:00:00:
import datetime
import webbrowser
# loop to run until desired time
def find_time_between_now__and_11():
"""returns the time in ms between now and 11"""
return datetime.datetime.now().time() - 11 # pseudocode, you need to figure out how to do that
lag = find_time_between_now__and_11()
time.sleep(lag)
# opens a link when its the desired time
webbrowser.open('https://www.youtube.com/watch?v=q05NxtGgNp4')
15% imho means you have one core filled 100%, because you're continuously looping. You can sleep() for 1+ seconds so the CPU is not busy looping and you need to add a fuzzy comparison for:
str(datetime.datetime.now().time()) == "11:00:00"
I'd go for something like:
def run_task(alarm):
last_run = None
while True:
now = datetime.datetime.now()
if now > alarm && last_run != now:
last_run = now
# Do whatever you need
webbrowser.open('https://www.youtube.com/watch?v=q05NxtGgNp4')
time.sleep(10) # Sleep 10 seconds
It's a bit convoluted bout you can extend to support multiple alarm times and change the if logic to suit your needs.

Categories

Resources