# -*- coding: utf-8 -*- import datetime import sys import time from typing import Optional # Only factor of 1000 SI_PREFIXES_LARGE = "kMGTPEZY" SI_PREFIXES_SMALL = "mµnpfazy" def humanize_number(data, unit: str = ""): counter = 0 while data >= 1000: data /= 1000 counter += 1 if counter >= len(SI_PREFIXES_LARGE): break while data < 1: data *= 1000 counter -= 1 if abs(counter) >= len(SI_PREFIXES_SMALL): break if not counter: prefix = "" elif counter > 0: prefix = SI_PREFIXES_LARGE[counter - 1] elif counter < 0: prefix = SI_PREFIXES_SMALL[abs(counter) - 1] return f"{data:.3g} {prefix}{unit}" def log(*message: object, **kwargs): print(datetime.datetime.utcnow().isoformat(" "), *message, **kwargs) sys.stdout.flush() class Periodical: prev: float interval: float def __init__(self, interval: float, start: Optional[float] = None): self.prev = time.time() - interval if start is None else start self.interval = interval def __call__(self, now: Optional[float] = None) -> bool: if now is None: now = time.time() if (now - self.prev) >= self.interval: skipped, overshoot = divmod(now - self.prev, self.interval) skipped -= 1 if skipped: log("Skipped:", skipped, overshoot, now - self.prev, self.interval) self.prev = now - overshoot return True return False