Calling a function at datetime in Python - python

What is a good way to call a function at datetime in Python?
There 3 ways that I know of:
"Are we there yet?!" (check at if date has passed at interval (time.sleep(interval)))
This is obviously bad. It can only be precise if interval is low, which becomes inefficient.
Sleep off the difference (time.sleep(timedelta.seconds))
This is better, but I don't like the idea of putting a thread to sleep for an insanely long time, e.g. 6 months if such is the date.
Hybrid between the two above; sleep off the difference if difference is bellow interval. If above, sleep for an interval to prevent long sleeps.
I think this is the best out of all three when you think about long sleeps, but interval seems bad anyway.
Are there any more ways you can think of? Is there anything in standard library that can help me call a function at datetime behind the scene?
EDIT:
I'm asking this because I've actually developed my own Cron implementation in Python. The only problem is that I can't decide how my code should wait for next occurrence. One of the differences between my implementation and original Cron is support for seconds. So, simply sleeping for minimum possible interval (1 second in my case) is too inefficient.
I realize now that this question could perhaps be changed to "how does Cron do this?" i.e. "how does Cron check if any date has passed? Does it run constantly or is a process run each minute?". I believe the latter is the case, which, again, is inefficient if interval is 1 second.
Another difference is that my code reads crontab once and calculates the exact date (datetime object) of next occurrence from the pattern. While Cron, I assume, simply checks each minute if any pattern from crontab matches current time.
I'll stick to the "hybrid" way if there's no other way to do this.

If this is something that might be six months out like you said, a chron job is probably more suitable than keeping a python program running the whole time.

I use the gobject main loop, but any library with an event loop should have this ability.

It might be a good idea to use a cron job.
you can edit the cron table with : crontab -e
and add a line like this (called every 20 minutes)
*/20 * * * * /usr/bin/python /home/toto/my_script.py

Related

What is the correct way to run a pydrake simulation "online"?

In Drake/pydrake, all of the examples I have seen create an instance of Simulator and then advance the simulation by a set duration, e.g. sim.AdvanceTo(10) will step the simulation until it has simulated 10 seconds of activity.
How can I instead run a simulation indefinitely, where I don't have a specific duration to advance to, just have the simulation running in its own node and step at a fixed interval forever?
My intention is to just have the simulator running, and then send requests to update commands that will be sent to the robot. Is there a straightforward way to achieve this that won't break the simulation? I figured there would be a public Step function on Simulator, but have only encountered AdvanceTo. My first thought was to try to take the context from a call to AdvanceTo over a short interval, e.g. AdvanceTo(0.01) and then overwrite the context for the next call so that it's updating from the new context instead of the original, but I'm not sure it will work. Maybe there's a more official way to achieve this scheme?
You can do
simulator.AdvanceTo(std::numeric_limits<double>::infinity()); to keep the simulation running indefinitely.
https://github.com/RobotLocomotion/drake/tree/master/examples/kuka_iiwa_arm may be helpful as an example.
You can do the scheme you proposed. But AdvanceTo() takes a time rather than an interval. To avoid annoying accumulated roundoff you should use an integer step counter and then do AdvanceTo(step_number * dt) where dt is the length of step you would like to take between interruptions.
An alternative would be to use AdvanceTo(infinity) as Xuchen suggested but define some regular update Event that can modify the state when needed.

Run command on complex schedule in python

I know there are a lot of schedule and event libraries out there but I haven’t found one where I can make complex schedule. E.g
run python command every 500ms between 7.55 and 8.05 on Monday-Friday
Anyone who can easily crack that task in Python? I have considered using schedule but as far as I can tell then I can’t add something like every 500 ms. Although I do believe in a cron-like approach (except cron only allows down to every minute).
I’m thinking of calculating next “cron” time and then use sched to execute the command with the calculated delay. No idea how to calculate something like that though. I could someone already cracked this challenge though.
Turns out the apscheduler supports exactly what I'm looking for.

Millisecond precise python timer

I work on a python script designed to control multiple actuator at the same time. To simplify, let's say I need to control 2 electric motors.
With the multiprocessing module I create a process for each motors, and a process to save the data on a sheet.
This part of the script works fine, however I need to command my motors at precise times, every milliseconds, and the time.time() or the time.clock() functions seems to be unreliable (triggs between 0.05 and 30 millisecond!)
Is it "normal" for these functions to be so erratic, or is this caused by another part of my script?
EDIT: I used the datetime function (see below) to improve the precision, but I still have several discrete level of error. For example, if I want 1ms, I get also 1.25, 0.75,1.5...
So IMO this is due to computer hardware(as Serge Ballesta said).
As I "only" need a relative time (1ms between each command), do you
know a way to do that precisely?
The best you can hope for is datetime.datetime.now(), which will give you microsecond resolution:
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2014, 7, 15, 14, 31, 1, 521368)
>>> i = datetime.datetime.now()
>>> q = datetime.datetime.now()
>>> (i-q).seconds
86389
>>> (i-q).microseconds
648299
>>> i.microsecond
513160
IMHO the problem is not in your script but more probably in your machine. I assume you are using a standard computer under Linux or Windows. And even if the computer is able to do many things in one single milliseconds, it constantly does with :
network
mouse or keyboard events
screen (including screen savers ...)
antivirus software (mainly on Windows)
system or daemon processes (and there are plenty of them)
multi-task management
You cannot reliably hope to have a one millisecond accuracy without a dedicated hardware equipement or you must use a real time system.
Edit:
As a complement, here is a quote from an answer from Ulrich Eckhardt to this other post Inconsistent Python Performance on Windows :
You have code that performs serial IO, which will block your process and possibly invoke the scheduler. If that happens, it will first give control to a different process and only when that one yield or exceeds its timeslice it will re-schedule your process.
The question for you is: What is the size of the scheduler timeslice of the systems you are running? I believe that this will give you an insight into what is happening.
I can't give You a comment yet (reputation), so a give you an anwser:
It's just a clue:
Try to use cProfile module.
https://docs.python.org/2/library/profile.html
It lets you check how long your script is executed, and every function in the script. Function .run() in the cProfile module returns precise statistics about your script.
Maybe it can help you..

Best way to code a reminder / stopwatch program in python?

I want to code a reminder program in python. I don't really have much experience, but I was thinking of a few ideas. My main way of doing this would be with a timer from the thread module that ran every second, and have it look through all reminders and stopwatch see if the time matches any of these reminders, but this would probably consume a lot of resources, especially if one has lots of reminders. So has anyone worked wih this before? What would be the best way to make this work in such a manner that it consumes as less resources as possible? Should I load the list of reminders into memory once, then look through them every second? Or should I look through them every 10 seconds and get the conditions to match for >= times?
If anyone has any experience on this, I'd appreciate the help. Thanks.
If you keep your reminders sorted, you only really need to check the next one in the list every second.
Also, you don't have to check every second - you can take longer naps, when you know nothing is going to happen for a few hours - just be sure to wake up, when a new reminder is set ;)
You could simply have the alarm thread sleep until the next event. This will necessitate waking that thread when a new event is inserted earlier than the current earliest event.

How to periodically check for the current date from within a program?

I would like to write a tiny calendar-like application for someone as a birthday present (to be run on Ubuntu). All it should do is display a separate picture each day, so whenever it's invoked it should check the date and select the appropriate picture from the collection I would provide, but also, in case it just keeps running, it should switch to the next picture when the next day begins.
The date-checking on invocation isn't the problem; my question pertains to the second case: how can I have the program notice the beginning of the next day? My clumsy approach would be to make it check the current date at regular intervals and let it change the displayed picture once there was a change in date, but that strikes me as very roundabout and not particularly elegant.
In case any of you have got some idea of how I could accomplish this, please don't hesitate to reply. I would aim to write the application in either Perl or Python, so suggestions concerning those two languages would be most welcome, but any other suggestions would be appreciated as well.
Thanks a lot for your time!
The answer to this could be very system dependant. Controlling the time at which your program is executed is likely to be system dependant. On all *nix type systems, I would use cron. Assuming for a moment that you are using a *nix system, the answer then depends on what the program actually does.
If it only needs to select an image, then I would suggest that it not be run continuously, but terminates itself after selecting it, and is then run again the next day (there are a lot of tutorials on how to setup cron).
If, however, it has some form of UI and it is likely (read possible) to keep running for several days, then you can follow two approaches:
Create your program as it is, to poll periodically for the current time, and do a date delta comparison. Python timedelta objects could help here. This is pretty much your inelegant approach.
The other solution would be to send it a signal from cron when you do wish it to update. This process would mean that you would have to make it signal aware, and respond to something like USR1. The Python docs talk to this, but you can find many tutorials on the web. This approach also works quite nicely for daemonised apps.
I'm sure there are many other approaches too, but those are the ones that come to mind for a quickish and nastyish app.
Did you think about scheduling the invoke of your script?
For me, the best approach is this:
1.Have two options to run the script:
run_script
run_script --update
2.Schedule the update run in some task scheduler (for example Cron) to be executed daily.
3.When you would want to check the image for current day, simply run the script without update option.
If you would like me to extend any part of these, simply ask about it.

Categories

Resources