<commit_before>from time import time
from ggame.mathapp import MathApp, _MathDynamic

class Timer(_MathDynamic):
    """
    The Timer class instantiates an object whose basic function is to report
    the number of seconds since its creation by calling the object as a 
    function with an empty argument list.
    
    The Timer class accepts no arguments during creation.
    
    Example of use:
    
    .. literalinclude:: ../examples/mathtimer1.py
    
    """
    
    def __init__(self):
        super().__init__()
        self._once = []
        self._callbacks = {}
        self.time = 0
        """
        Attribute is always updated with the number of seconds since the 
        timer was created.
        """
        self._reset = time()
        MathApp._addDynamic(self)  # always dynamically defined
        
    def reset(self):
        """
        Set the reference time to the MathApp current time. If the timer is reset
        before the app initializes then do nothing.
        
        :returns: None
        """
        if self._reset:
            self._reset = time()

    def step(self):
        nexttimers = []
        calllist = []
        if not self._reset:
            self._reset = MathApp.time
        self.time = MathApp.time - self._reset
        while self._once and self._once[0][0] <= MathApp.time:
            tickinfo = self._once.pop(0)
            if tickinfo[1]:  # periodic?
                nexttimers.append((tickinfo[1], self._callbacks[tickinfo][0]))  # delay, callback
            calllist.append(self._callbacks[tickinfo].pop(0)) # remove callback and queue it
            if not self._callbacks[tickinfo]: # if the callback list is empty
                del self._callbacks[tickinfo] # remove the dictionary entry altogether
        for tickadd in nexttimers:
            self.callAfter(tickadd[0], tickadd[1], True)  # keep it going
        for call in calllist:
            call(self)

    def callAfter(self, delay, callback, periodic=False):
        """
        Set a callback to occur either once or periodically. The callback 
        function should accept a single parameter which will be a reference
        to the timer object that called it.
        
        :param float delay: The number of seconds to wait before executing
            the callback function
        :param function callback: The callback function to call on timer
            expiration
        :param boolean periodic: Set True if the callback function should
            be executed periodically
        :returns: None
        """
        key = (time() + delay, delay if periodic else 0)
        self._once.append(key)
        callbacklist = self._callbacks.get(key, [])
        callbacklist.append(callback)
        self._callbacks[key] = callbacklist
        self._once.sort()
        
    def callAt(self, time, callback):
        """
        Set a callback to occur at a specific time (seconds since
        the Timer object was created or since its 
        :func:`~ggame.timer.Timer.reset` method was called.
        
        :param float time: The time to wait since timer creation or reset 
            before calling the callback function.
        :param function callback: The callback function to call
        :returns: None
        """
        self.callAfter(time-self.time, callback)
        
    def callEvery(self, period, callback):
        """
        Set a callback to occur periodically. The callback 
        function should accept a single parameter which will be a reference
        to the timer object that called it.
        
        :param float period: The number of seconds to wait before each
            execution of the callback function
        :param function callback: The callback function to call on timer
            expiration
        :returns: None
        """
        self.callAfter(period, callback, True)

    def __call__(self):
        return self.time

<commit_msg>timer update - remove time attribute<commit_after>from time import time
from ggame.mathapp import MathApp, _MathDynamic

class Timer(_MathDynamic):
    """
    The Timer class instantiates an object whose basic function is to report
    the number of seconds since its creation by calling the object as a 
    function with an empty argument list.
    
    The Timer class accepts no arguments during creation.
    
    Example of use:
    
    .. literalinclude:: ../examples/mathtimer1.py
    
    """
    
    def __init__(self):
        super().__init__()
        self._once = []
        self._callbacks = {}
        self._time = 0
        self._reset = time()
        MathApp._addDynamic(self)  # always dynamically defined
        
    def reset(self):
        """
        Set the reference time to the MathApp current time. If the timer is reset
        before the app initializes then do nothing.
        
        :returns: None
        """
        if self._reset:
            self._reset = time()
            
    @property
    def time(self):
        """
        Attribute is always updated with the number of seconds since the 
        timer was created.
        """
        return self._time
        
    @time.setter
    def time(self, value):
        pass

    def step(self):
        nexttimers = []
        calllist = []
        if not self._reset:
            self._reset = MathApp.time
        self._time = MathApp.time - self._reset
        while self._once and self._once[0][0] <= MathApp.time:
            tickinfo = self._once.pop(0)
            if tickinfo[1]:  # periodic?
                nexttimers.append((tickinfo[1], self._callbacks[tickinfo][0]))  # delay, callback
            calllist.append(self._callbacks[tickinfo].pop(0)) # remove callback and queue it
            if not self._callbacks[tickinfo]: # if the callback list is empty
                del self._callbacks[tickinfo] # remove the dictionary entry altogether
        for tickadd in nexttimers:
            self.callAfter(tickadd[0], tickadd[1], True)  # keep it going
        for call in calllist:
            call(self)

    def callAfter(self, delay, callback, periodic=False):
        """
        Set a callback to occur either once or periodically. The callback 
        function should accept a single parameter which will be a reference
        to the timer object that called it.
        
        :param float delay: The number of seconds to wait before executing
            the callback function
        :param function callback: The callback function to call on timer
            expiration
        :param boolean periodic: Set True if the callback function should
            be executed periodically
        :returns: None
        """
        key = (time() + delay, delay if periodic else 0)
        self._once.append(key)
        callbacklist = self._callbacks.get(key, [])
        callbacklist.append(callback)
        self._callbacks[key] = callbacklist
        self._once.sort()
        
    def callAt(self, time, callback):
        """
        Set a callback to occur at a specific time (seconds since
        the Timer object was created or since its 
        :func:`~ggame.timer.Timer.reset` method was called.
        
        :param float time: The time to wait since timer creation or reset 
            before calling the callback function.
        :param function callback: The callback function to call
        :returns: None
        """
        self.callAfter(time-self._time, callback)
        
    def callEvery(self, period, callback):
        """
        Set a callback to occur periodically. The callback 
        function should accept a single parameter which will be a reference
        to the timer object that called it.
        
        :param float period: The number of seconds to wait before each
            execution of the callback function
        :param function callback: The callback function to call on timer
            expiration
        :returns: None
        """
        self.callAfter(period, callback, True)

    def __call__(self):
        return self._time


{'fraction_non_alphanumeric': 0.07103825136612021, 'fraction_numerical': 0.0029806259314456036, 'mean_word_length': 1.9947936035701004, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4636912', 'n_tokens_mistral': 2010, 'n_tokens_neox': 1958, 'n_words': 784}