Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: v2.0.5 #226

Merged
merged 2 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cereja/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
from . import scraping
from . import wcag

VERSION = "2.0.4.final.0"
VERSION = "2.0.5.final.0"

__version__ = get_version_pep440_compliant(VERSION)

Expand Down
86 changes: 85 additions & 1 deletion cereja/utils/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
SOFTWARE.
"""
import math
import random
import threading
import time
import time as _time
from typing import Callable, Union

__all__ = ["Timer", "set_interval", "time_format"]
__all__ = ["Timer", "set_interval", "time_format", "RandomTimer", "TimeEstimate", "IntervalScheduler"]


class Timer:
Expand Down Expand Up @@ -127,13 +128,68 @@ def time_overflow(self):

return max(self.elapsed - self.interval, 0) if self._interval > 0 else 0

def wait(self):
"""
Wait until the timer interval has passed.
"""
_time.sleep(self.remaining)

def __str__(self):
return time_format(self.elapsed)

def __repr__(self):
eta = "" if self._interval <= 0 else f", ETA={time_format(self.remaining)}"
return f"Timer(elapsed={self.__str__()}{eta})"

def iter_over(self, iterable):
"""
Iterate over an iterable and wait until the timer interval has passed.
@param iterable: An iterable object.
@return: An iterator object.
"""
for item in iterable:
self.start()
yield item
self.wait()


class RandomTimer(Timer):
def __init__(self, min_interval: float, max_interval: float, start=True, auto_reset=False):
"""
Initialize the RandomTimer.

Args:
min_interval (float): The minimum time interval in seconds.
max_interval (float): The maximum time interval in seconds.
start (bool): Whether to start the timer immediately. Default is True.
auto_reset (bool): Whether the timer should automatically reset after the interval has passed.
Default is False.
"""
assert isinstance(min_interval, (int, float)), TypeError(f"{min_interval} isn't valid. Send a number!")
assert isinstance(max_interval, (int, float)), TypeError(f"{max_interval} isn't valid. Send a number!")
assert min_interval >= 0, ValueError("min_interval must be greater than or equal to 0")
assert max_interval >= 0, ValueError("max_interval must be greater than or equal to 0")
assert min_interval < max_interval, ValueError("min_interval must be less than max_interval")
self._min_interval = min_interval
self._max_interval = max_interval
self._interval = self._random_interval()
super(RandomTimer, self).__init__(self._interval, start, auto_reset)

def _random_interval(self):
return random.uniform(self._min_interval, self._max_interval)

def reset(self):
self._interval = self._random_interval()
self.start()

def start(self):
self._interval = self._random_interval()
super(RandomTimer, self).start()

def __repr__(self):
eta = "" if self._interval <= 0 else f", ETA={time_format(self.remaining)}"
return f"RandomTimer(elapsed={self.__str__()}{eta})"


class TimeEstimate:
def __init__(self, size: int = None):
Expand All @@ -142,6 +198,14 @@ def __init__(self, size: int = None):
self._size = size or 0
self._total_times = 0

@property
def total_times(self):
return self._total_times

@property
def size(self):
return self._size

def set_time_it(self) -> float:
self._total_times += 1
return self._timer.elapsed
Expand Down Expand Up @@ -169,6 +233,12 @@ def eta_formated(self):
def per_sec(self):
return math.ceil(self._total_times / max(self._timer.elapsed, 1))

def __str__(self):
return f"TimeEstimate(duration={self.duration_formated}, eta={self.eta_formated}, per_sec={self.per_sec})"

def __repr__(self):
return self.__str__()


class IntervalScheduler:
"""
Expand Down Expand Up @@ -269,3 +339,17 @@ def time_format(seconds: float, format_="%H:%M:%S") -> Union[str, float]:
return f"-{time_}"
return time_
return seconds # Return NaN or any invalid input as it is


def set_timeout(func: Callable, sec: float, use_thread=False, *args, **kwargs):
"""
Call a function after sec seconds
@param func: function
@param sec: seconds
@param use_thread: If True, the function will be called in a new thread
"""
if use_thread:
threading.Timer(sec, func, args=args, kwargs=kwargs).start()
else:
time.sleep(sec)
func(*args, **kwargs)
Loading