#!/usr/bin/env python """Miscellaneous class and functions used in utils script.""" __author__ = "Théo de la Hogue" __credits__ = [] __copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" __license__ = "BSD" from typing import Tuple import time import types def printProgressBar (iteration:int, total:int, prefix:str = '', suffix:str = '', decimals:int = 1, length:int = 100, fill:str = '█', printEnd:str = "\r"): """ Print iterations progress. Call in a loop to create terminal progress bar. Parameters: iteration: current iteration total: total iterations prefix: string to print before progress bar suffix: string to print after progress bar decimals: positive number of decimals in percent complete length: character length of bar fill: bar fill character printEnd: end character (e.g. \\r, \\r\\n) """ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) filledLength = int(length * iteration // total) bar = fill * filledLength + '-' * (length - filledLength) print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd) # Print New Line on Complete if iteration == total: print() def importFromTestPackage(module: str) -> types.ModuleType: """ Import module from ArGaze test package. Parameters: module: module name into ArGaze package Returns: module named Test """ import argaze import importlib.util import sys import os source_directory = os.path.dirname(os.path.dirname(os.path.abspath(argaze.__file__))) module_directory = os.path.join(source_directory, 'argaze.test', f'{module}.py') spec = importlib.util.spec_from_file_location(f'{module}Test', module_directory) TestModule = importlib.util.module_from_spec(spec) sys.modules[f'{module}Test'] = TestModule spec.loader.exec_module(TestModule) return TestModule class ExitSignalHandler(): """ Handle exit event """ def __init__(self): import signal import threading global __exit_event global __on_exit_signal __exit_event = threading.Event() def __on_exit_signal(signo, _frame): __exit_event.set() for sig in ('TERM', 'HUP', 'INT'): signal.signal(getattr(signal, 'SIG'+sig), __on_exit_signal) def status(self) -> bool: """ Get exit status. Returns: exit status """ return __exit_event.is_set() class TimeProbe(): """ Assess temporal performance. """ def __init__(self): self.start() def start(self): """ Start chronometer. """ self.__last_time = time.perf_counter() self.__lap_counter = 0 self.__elapsed_time = 0 def lap(self) -> Tuple[float, int, float]: """ Get lap info. Returns: last lap time (millisecond) number of laps total elapsed time (millisecond) """ lap_time = time.perf_counter() - self.__last_time self.__last_time = time.perf_counter() self.__lap_counter += 1 self.__elapsed_time += lap_time return lap_time * 1e3, self.__lap_counter, self.__elapsed_time * 1e3 def end(self) -> float: """ Stop chronometer Returns: elapsed time (millisecond) """ self.__elapsed_time += time.perf_counter() - self.__last_time return self.__elapsed_time * 1e3, self.__lap_counter def restart(self): """ Restart chronometer. """ self.start()