Python Forum
ticktock generator and command - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: General (https://python-forum.io/forum-1.html)
+--- Forum: Code sharing (https://python-forum.io/forum-5.html)
+--- Thread: ticktock generator and command (/thread-28224.html)



ticktock generator and command - Skaperen - Jul-10-2020

this code can be imported for the generator or just run to be a command (some people may want to add a #! at the start). the generator simply returns the amount of time it did sleep when it does return. the cycle period is arg 2 and the offset is arg 1. the default is ticktock(0,60) which returns every minute at 0 seconds after the minute.

this generator can be useful to make timed repeating event scripts without accumulating timing errors like using a plain sleep would do.

import time
_mt = dict(s=1,m=60,h=60*60,d=60*60*24,w=60*60*24*7)
def ticktock(offset=0,cycle=60): # default is top of every minute
    """Generator to sleep to each time stop in a time sequence without acculated errors."""
    # example: wake up every 5 minutes at 1 minute in: ticktock(60,300)
    while True:
        n=time.time()
        s = (offset-time.time())%cycle
        time.sleep(s)
        yield s
def _tc(s):
    try:
        return float(s)
    except ValueError:
        return float(s[:-1])*_mt[s[-1]]
if __name__ == '__main__':
    import sys
    g=ticktock(*[_tc(x)for x in sys.argv[1:]])
    try:
        while True:
            next(g)
            print('tick',flush=True)
            next(g)
            print('tock',flush=True)
    except KeyboardInterrupt:
        exit('')
    except Exception:
        exit()
if you prefer to get it from a URL: http://ipal.net/python-forum/ticktock.py


RE: ticktock generator and command - Skaperen - Jul-10-2020

yes, line 7 was totally useless. it looks to me like leftover from an edit that quietly didn't break anything. i have removed it, now.

ticktock.py:
import time
_mt=dict(s=1,m=60,h=60*60,d=60*60*24,w=60*60*24*7)
def ticktock(offset=0,cycle=60): # default is top of every minute
    """Generator to sleep to each time stop in a time sequence without acculated errors."""
    # example: wake up every 5 minutes at 1 minute in: ticktock(60,300)
    while True:
        s=(offset-time.time())%cycle
        time.sleep(s)
        yield s
def _tc(s):
    try:
        return float(s)
    except ValueError:
        return float(s[:-1])*_mt[s[-1]]
if __name__=='__main__':
    import sys
    g=ticktock(*[_tc(x)for x in sys.argv[1:]])
    try:
        while True:
            next(g)
            print('tick',flush=True)
            next(g)
            print('tock',flush=True)
    except KeyboardInterrupt:
        exit('')
    except Exception:
        exit()
this doesn't really need to be a generator. but it's a nice example and a starting point for making other things.