Is it possible to have python 2.7 print something at a specific time of the day. For example if I ran the program at 15:06 and coded it to print "Do task now" at 15:07 it prints it. So no matter what time you ran the program once it hit 15:07 it would print "Do task now." In addition is it possible to have it print every week at this time?
I would suggest installing the library schedule, if you're able to.
Use pip install schedule
Your code would look like this if utilizing schedule:
import schedule
import time
def task():
print("Do task now")
schedule.every().day.at("15:07").do(task)
while True:
schedule.run_pending()
time.sleep(1)
You can adjust time.sleep(1) as necessary to sleep for longer if a 1s interval is too long. Here is the schedule library page.
If you're not using cron, then the general solution is to find the time remaining until you need the event to occur, have the program sleep for that duration, then continue execution.
The tricky part is to have the program find the next occurrence of a given time. There are some modules for this, but you could also do it with plain code for a well-defined case where it is only a fixed time of day.
import time
target_time = '15:07:00'
current_epoch = time.time()
# get string of full time and split it
time_parts = time.ctime().split(' ')
# replace the time component to your target
time_parts[3] = target_time
# convert to epoch
future_time = time.mktime(time.strptime(' '.join(time_parts)))
# if not in the future, add a day to make it tomorrow
diff = future_time - current_epoch
if diff < 0:
diff += 86400
time.sleep(diff)
print 'Done waiting, lets get to work'
While python is not ideal to schedule something; there are better tools out there. Yet, if this is desired to be done in python below is a way to implement it:
Prints at scheduled_time of 11AM:
import datetime as dt
scheduled_time = dt.time(11,00,00,0)
while 1==1:
if (scheduled_time < dt.datetime.now().time() and
scheduled_time > (dt.datetime.now()- dt.timedelta(seconds=59)).time() ):
print "Now is the time to print"
break
There are two if conditions with an intent to print within one minute; a shorter duration can be chosen. But the break immediately after print ensures that print is executed only once.
You would need to extrapolate this so that code is run across days.
Refer: datetime Documentation
Related
Im trying to make a countdown timer with the feature to reset/stop/pause/resume. I tried implementing an if/elif/else statement to check for user input letter within the while loop while it continues looping. However, the loop stops running when the conditional statement executes. How do I implement my intended functionality into the code?
code:
import time
import datetime
def timeinput():
# Inputs for hours, minutes, seconds on timer
h = input("Enter the time in hours: ")
m = input("Enter the time in minutes: ")
s = input("Enter the time in seconds: ")
countdown(int(h), int(m), int(s))
# Create class that acts as a countdown
def countdown(h, m, s):
# Print options for user to do
print("Press w to reset \nPress s to stop \nPress a to pause \nPress d to resume")
# Calculate the total number of seconds
total_seconds = h * 3600 + m * 60 + s
# While loop that checks if total_seconds reaches zero
# If not zero, decrement total time by one second
while total_seconds > 0:
# Timer represents time left on countdown
timer = datetime.timedelta(seconds = total_seconds)
# Prints the time left on the timer
print(timer, end="\r")
# Delays the program one second
time.sleep(1)
# Reduces total time by one second
total_seconds -= 1
user=input()
if user=="w":
total_seconds=0
print("Timer will now reset")
timeinput()
print("Bzzzt! The countdown is at zero seconds!")
timeinput()
result:
outcome of code
As shown in the provided image, the loop stops at 20 secs. My intended action here was for the countdown to continue until the user presses the W key, which shall then reset the countdown back to its original set time at initialization.
Soo, I'm also kinda new to programming and python so I don't exactly how to make a timer with that functionality. What is happening is that when you use the input() function the code stops and waits for the user input.
I know you can use some libraries, like pygame, in order to check for user input inside the loop without stopping it, but without one I'm not sure how to do it.
You can also use the module keyboard, that comes inside python, and I think is great for the problem you shared. Check this post How to detect key presses?
The command input() is blocking. It waits until it get something from the console. Maybe take a look at this post and try to implement a non blocking version of input. Non-blocking console input?
The problem is that input is blocking - that is, it will stop the execution until the user presses < enter> .
Antique running environments, on 8 bit computers, using Basic, could check "what the user is pressing right now", without waiting for a confirmation with "enter" using the inkey command.
In Python programs running on terminal, terminedia, a 3rdy party library, implements inkey() as it was - but it needs the terminal input to be reconfigured for which it provides a "keyboard" context manager.
You can then run almost the same code you have -just install terminedia in your Python environment with "pip install terminedia"
import terminedia as TM
...
def countdown(h, m, s):
...
while total_seconds > 0:
# Timer represents time left on countdown
timer = datetime.timedelta(seconds = total_seconds)
# Prints the time left on the timer
print(timer, end="\r")
with TM.keyboard:
# Delays the program one second
time.sleep(1)
# Reduces total time by one second
total_seconds -= 1
user=TM.inkey()
if user=="w":
total_seconds=0
print("Timer will now reset")
timeinput()
print("Bzzzt! The countdown is at zero seconds!")
timeinput()
(disclaimer: I am terminedia author)
Taking inputs from the answers received here and subsequent follow-up questions on stack overflow and Reddit, this question has been solved using pygame. I'll provide the link below for future reference to this question.
problem solution
i would like to generate random numbers for 5 minutes. after that, i would like to know the most common numbers.
my question is:
I am not sure about how much time I need. Can i MANUALLY terminate the script at 1 minute or 1 minute 19 seconds and get the result
my code is as follows:
import random
from collections import Counter
t_end = time.time() + 60*5
numbers = []
while time.time() < t_end:
number=''.join(map(str, [random.randint(0,9)for value in range(0,4)]))
numbers.append(number)
print(Counter(numbers))
There are a myriad number of options:
print an intermediate result every 5s or so and abort the script with ctrl+C
check if space or something else is pressed, if so, abort the loop (see here for how to)
listen to signals and handle accordingly (this could also gracefully terminate the script for option 1)
open a socket and listen to a socket if a stop signal comes in
create a gui with TKinter or what and add a stop button
...
The first one is the easiest but also the most quick&dirty one. For the second option, the following script should get you started (your script was working for me after adding whitespaces and linebreaks):
import keyboard
while True:
if keyboard.read_key() == "p":
print("You pressed p")
break
Assuming python3 and windows: Note that keyboard is not shipped with python on default. You need to install it with pip3 install keyboard. Pip3.exe might not be on your path. cd to where you installed python and look around. For me it was in the Scripts-folder (my installation is pretty messed up though).
import random
from collections import Counter
import time
t_end = time.time() + 60*5
numbers = []
while time.time() < t_end:
number=''.join(map(str, [random.randint(0,9)for value in range(0,4)]))
numbers.append(number)
if time.time()==(t_end-60*4): # break a 1 min
break
print(Counter(numbers))
As luigigi already mentioned in the comment, you could simply use the number of iterations as a limit, and use a for-loop:
number_of_iterations = 10000
for i in range(number_of_iterations):
place_your_function_here()
However, if you for some reason really want to use the time, here is how you can do it: Update the current time at the bottom of your while block, and in the continuing condition of the while loop, compare it to the finish time:
import datetime
delta_in_seconds = 60
finish = datetime.datetime.now() + datetime.timedelta(0, delta_in_seconds)
while time < finish:
place_your_function_here()
time = datetime.datetime.now()
I am writing a program that uses a while loop to check if it is a certain time, and if it is that certain time, it prints a statement. I have all the if-statements set up, but the time does not update once the program starts (if I start the program at 6 pm, it will always output 6 pm for local time). Is there a way to update the time within the while loop?
I tried to research some additional functions/methods to datetime, but from what I have seen, I have not been able to find any that updates the time while the program is running. Additionally, forums regarding datetime and locale time that I have found on stackoverflow are commonly ones that just explain how to obtain the locale time once (ex, Python datetime module current time in HR:MIN:SEC). Other forums regarding locale times that I have found also tended to be in different languages, particularly C# and PHP. Please correct me if there is another forum that answers my question!
from datetime import date
from datetime import time
from datetime import datetime
import time
import webbrowser
now = datetime.now()
sleep = False
today = date.today()
roundCheck = 0
print("Awaiting time check...")
while sleep != True:
print('Up here...')
if roundCheck != 0:
print('Stuck in time...')
time.sleep(60)
print('Time is done')
if str(now.strftime('%H')) == '20' and str(now.strftime('%M')) == '05':
print('Now the while loop will end')
sleep = True
roundCheck = 1
print('Another round has passed')
print('Outside while loop')
When the time is 20:05, sleep should be set to true and the print statement outside the while loop can be executed. However, when I start the program at an earlier time (20:00, for example), it only uses that time for checking now.strftime().
now never changes. You simply need to put now = datetime.now() in the while loop.
I would like to execute a portion of a script at 8 am each day. I have created a simplified test case that has no syntax error, but does not work properly. I think it may be because my if statement is using the time as a string, but it won't compile any other way. What am I doing wrong?
import datetime
while True:
if datetime.datetime.now().time() == "19:00:00.000000":
print "it's time!"
If you are on a system with cron, then it would be better to set up a cron job. However, your problem is fixable from within Python:
First, as you noted, datetime.datetime.now().time() returns a datetime.time object, not a string:
In [89]: datetime.datetime.now().time()
Out[89]: datetime.time(19, 36, 13, 388625)
Also, although datetime.datetime.now().time() == datetime.time(19, 0) would be
valid Python, the chance that you happen to execute time() at just the right
moment is very slim since datetime.datetime.now() has microsecond
resolution. So it would be better to test if the current time falls within some
range.
However, since you only want to run the function once per day, you could instead measure the total number of seconds between now and when you want to run the function and sleep that number of seconds:
import datetime as DT
import time
while True:
now = DT.datetime.now()
target = DT.datetime.combine(DT.date.today(), DT.time(hour=8))
if target < now:
target += DT.timedelta(days=1)
time.sleep((target-now).total_seconds())
# do something
If you want to keep your code simple, you can use the below code:
import datetime
import time
while True:
time.sleep(1)
if datetime.datetime.now().time().strftime("%H:%M:%S") == '19:00:00':
print ("it's time!")
Sleep is used to generate only 1 row per 1 second (without this you will print thousands of lines. Also it is worth to convert time to string.
# run infinitly
while(True):
done = False;
while(not done):
#Do Stuff
#Main Program
#stopping condition of inner while loop
if datetime.datetime.now().minute == 10:
done = True
if datetime.datetime.now().minute == 10:
time.sleep(60-datetime.datetime.now().second)
I can't figure out why this will not work for me. The entire script is supposed to run on an infinite loop, and then the inner loop is supposed to go through until the stopping condition is met every 10 minutes.
It was my understanding, and maybe I am wrong, that using datetime.datetime.now().minute like I did in an if loop like that would set done = True every 10 minutes, and would end the loop and proceed with the rest of the script...until it realizes that its in another infinite loop and then its supposed to start all over.
Am I getting confused with how this command works, or is there something wrong with my code? Or is there even a better way to do it? The script will run, but it does not end the inner loop with that stopping condtion.
There are various ways to do it, but keeping close to your original design, I'd code the inner loop as:
while(not done):
if datetime.datetime.now().minute % 10 == 0:
done = True
else:
time.sleep(60-datetime.datetime.now().second)
(I'm assuming what you were trying to do with that second if was sleep until the next minute when you weren't ready to exit the loop.)
It stops every tenth minute: 1:10, 2:10, 3:10, etc. In order to do that, use something like:
import time
# in outer loop
inner_loop_start = time.time()
# in inner loop
now = time.time()
if now - inner_loop_start > 60*10:
# done= True and all that jazz
Rather than thrashing around constantly checking if it's 10 past the top of the hour, just do some math and sleep appropriately. Time is generally deterministic.
import datetime
import time
def seconds_till_10past():
now = datetime.datetime.now()
delta = now.replace(minute=10, second=0) - now
return delta.seconds % 3600
while True:
time.sleep(seconds_till_10past())
print "Do something at 10 past the hour."
Also, don't parenthesize arguments to statements (e.g. while(True)), it's bad form.
This does not directly answer the question, but just in case all you want to achieve in the first place is to run some python code every (say) 10 minutes, you'd better implement this using cron.
I assume you so far have a script that is somehow started at boot time. It mainly consists of an infinite loop, a main procedure, and a wait-until-next-execution-time component. For example like the following:
""" my_first_daemon.py
does something everytime the datetime minute part is fully divisible by ten
"""
while True:
# do something at 00,10,20,30,40,50 (minutes) every hour
print "Hello World!"
# wait until the next execution time
wait_until_next_ten_minute_time()
If this is indeed the case I'd suggest to move the main section of your script to a separate script. For example like the following:
""" my_first_cronjob.py
is run by cron everytime the datetime minute part is fully divisible by ten
"""
# do something at 00,10,20,30,40,50 (minutes) every hour
print "Hello World!"
The you go ahead and add to your crontab (use the command crontab -e to add the entry to that user's crontab that shall run the script, also have a look at the manpage). For example like this:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed
# example entry:
# (divide minute-star by 10 to get it run every 10 minutes)
*/10 * * * * python /path/to/my_first_cronjob.py
After the edit you should notice a message like crontab: installing new crontab and then you're done. Just wait and have a look if it works.
Some things to note as well:
The script's output to stdout and stderr are sent to you by mail after termination. Have a look at tail -f /var/mail/moooeeeep (specify your username). You can also configure Thunderbird to fetch these mails, in order to inspect them easier.
The corresponding Wikipedia page is a very good source of information for further details.
If you need to keep state information between independent runs of the script, consider using a configuration file to store this state information, e.g., using pickle, shelve, sqlite, whatever.
Expanding from my comment above:
tic = datetime.datetime.now()
while True:
# do stuff
toc = datetime.datetime.now() - tic
if toc.minute > 10:
tic = datetime.datetime.now();
time.sleep(60-datetime.datetime.now().second)
I have removed the "done" variable, since it conveys a meaning of finished. By reading your code, though, it seems you are actually pausing an ever ongoing process, actually.
Hope this helps!