Python : Running a loop during a precise duration - python

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).

Related

Reminder for a specific time in 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

What's the most efficient way to pause during a loop in python?

I have a script which loops through the elements of a list. Each element is used to query an API. However, the API has a query limit (only 500 queries are permitted over a 24 hour period). I am currently managing this through a counter in a loop, which resets for each "chunk" of 500 elements and would pause the loop for a day. Is there a better way to do this?
counter = 0
for query in queries:
if counter < 500:
counter = counter + 1
api = ApiClient(api_key='secretkey')
data = api.get(q=query)
print(data)
safequery = ''.join(e for e in query if e.isalnum())
datafilename = "{} {}.txt".format(safequery,todaysdate)
with open(datafilename, 'w') as outfile:
json.dump(data, outfile)
else:
print('sleepy time')
time.sleep(86400)
counter = 0
time.sleep(86400) is asking for problems, and also makes your CPU work for nothing. If something happens during those 86400 seconds and the script crashes, nothing will restart it.
The much better option would be to save the current page/chunk somewhere (raw text file, json, DB, doesn't really matter), then load it before making the next requests.
Then you can put your script in an Operating System level/managed task scheduler (for example, cron for Unix or Task Scheduler for Windows) and run it daily.
time.sleep() is a good solution, but you can also make Python ask for input when you want to continue. That's primitive, I know.
if counter % 500 == 0: # make the counter start at 1
val = input("\nContinue? [y/n]: ")
if val == 'y':
pass # manually unpause the looping, whenever you want
elif val == 'n':
break # interrupt for loop
I would tackle this by creating a script that when ran will get the next 500 and then terminate. You might want to output a text file to store where you are up to in this sequence.
I would then schedule this script to run every 24 hours with windows task scheduler (on windows)
This means you are not having a process running doing nothing.
sleep()
should only be used for small time intervals.
I think you could make this code as a python script and execute in a batch file.
catch this batch file and schedule into a task manager to run every day at 2:00 pm for example...
usually i have a python script server that runs my robots and things that i need to do automatically.
An if else statement with a sleep is probably as simple as it gets; however it's not efficient since the process will still be alive and doing nothing for 86400 seconds.
You could look into creating a cron job to run your code one a day at the same time

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

Send a variable from outside the python console OR stop a script from outside

I wrote a Python script that executes an optimization and runs days to get a solution (due to the costly objective function). In all days work it will be sufficient to just stop the calculation at some point because the solution is good enough for me (but not for the optimization algorithm).
The problem is, I can always abort hitting Ctrl+C. But then there is no chance to nicely output the current best parameters, plot the data, save it etc. It would be great to stop the script in a controlled way after the next calculation of the objective function. So my thought was so question some variable (if user_stop=True) and programatically stop the optimization. But how to set such a variable? The python console is blocked during execution.
I thought about setting the content of a text file and reading it in each iteration but it's more than poor and hard to explain for other users of the script. Theoretically, I could also ask the user for an input but than the script won't run automatically (which it should until someone decides to stop).
Any ideas for my problem?
Basically that's it - stop the loop at some point but execute the print:
a = 0
while True:
a = a + 1
print(a)
If you poll your "variable" infrequently (say at most once every 20 seconds) then the overhead of testing for a file is negligible. Something like
import os
QUITFILE = "/home/myscript/quit_now.txt"
# and for convenience, delete any old QUITFILE that may exist at init time
... # days later
if os.path.isfile( QUITFILE)
# tidy up, delete QUITFILE, and exit
Then just echo please > home/myscript/quit_now.txt to tell your program to exit.
maybe you can use a do-while loop. holding your target in a varible
outside the loop and start looping the calculatio while <= your target calculation.
For Windows, I would use msvcrt.getch()
For example, this script will loop until a key is pressed, then, if it is q, prompt for the user to quit: (Note that the if statement uses 'short circuiting' to only evaluate the getch() - which is blocking - when we know that a key has been pressed.)
import msvcrt, time
while True: #This is your optimization loop
if msvcrt.kbhit() and msvcrt.getch() == 'q':
retval = raw_input('Quit? (Y/N) >')
if retval.lower() == 'y':
print 'Quitting'
break #Or set a flag...
else:
time.sleep(1)
print('Processing...')
If you place this if block at a point in the optimization loop where it will be frequently run, it will allow you to sop at a convenient point, or at least set a flag which you can check for at the end of each optimization run.
If you cannot place it somewhere where it will be frequently checked, then you can look at handling the KeyboardInterrupt raised by Ctrl-C
If you are running on Linux, or need cross-platform capability, have a look at this answer for getting the keypress.

continue takes you to top of your while loop in python. Is there something similar that will take interpreter to beginning of your code

Is there a way to make python jump back to the beginning of your code. Say for example I have a program that contains 3 while loops. I run the programs and get through all the while loops.
Is there a way I can then make the program jump back to line 1 of the code, and start all over again? I know the "continue" statement will take you to beginning of the while loop it is in. Was curious to know if there is another statement or something similar that can take you to beginning of your code from anywhere in your program?
Any help would be greatly appreciated. Spent time googling and searching stack overflow, but everytime I found an instance of this question, it was never really specifically answered, just better code was suggested.
I am a python beginner, so apologize if this is not so clear, or a dump question. Thank you in advance for your time, and any help you can give. =)
You could wrap what ever piece of functionality you have in a function or method, then simply call the function/method whenever you need it.
def print_ten():
n = 1
while n <= 10:
print n
n = n + 1
print_ten()
print_ten()
see Breaking out of nested loops
breaking out of all inner loops and evaluting all inner values in your outer while, should give the desired result.

Categories