diff --git a/python/projet.py b/python/projet.py index daabe35..33d96a3 100644 --- a/python/projet.py +++ b/python/projet.py @@ -2,7 +2,8 @@ # Author: @saundersp from ViolaJones import train_viola_jones, classify_viola_jones -from toolbox import state_saver, picke_multi_loader, format_time_ns, benchmark_function, toolbox_unit_test, unit_test_argsort_2d +from toolbox import state_saver, picke_multi_loader, format_time_ns, benchmark_function, unit_test_argsort_2d +from toolbox_unit_test import format_time_ns_test from sklearn.metrics import accuracy_score, f1_score, confusion_matrix from sklearn.feature_selection import SelectPercentile, f_classif from common import load_datasets, unit_test diff --git a/python/toolbox.py b/python/toolbox.py index 3f202cf..be60e3f 100644 --- a/python/toolbox.py +++ b/python/toolbox.py @@ -1,13 +1,15 @@ -from typing import Any, Callable, List, Union +from typing import Any, Callable, List, Union, Final from time import perf_counter_ns from numba import njit import numpy as np import pickle import os from config import MODEL_DIR, OUT_DIR +from decorators import njit -formats = ["ns", "µs", "ms", "s", "m", "h", "j", "w", "M", "y"] -nb = np.array([1, 1000, 1000, 1000, 60, 60, 24, 7, 4, 12], dtype = np.uint16) +time_formats: Final = ["ns", "µs", "ms", "s", "m", "h", "j", "w", "M", "y", "c"] +time_numbers: Final = np.array([1, 1e3, 1e6, 1e9, 6e10, 36e11, 864e11, 6048e11, 26784e11, 31536e12, 31536e14], dtype = np.uint64) +@njit('str(uint64)') def format_time_ns(time: int) -> str: """Format the time in nanoseconds in human readable format. @@ -20,35 +22,17 @@ def format_time_ns(time: int) -> str: assert time >= 0, "Incorrect time stamp" if time == 0: return "0ns" - prod = nb.prod(dtype = np.uint64) s = "" - for i in range(nb.shape[0])[::-1]: - if time >= prod: - res = int(time // prod) - time = time % prod - s += f"{res}{formats[i]} " - prod = prod // nb[i] + for i in range(time_numbers.shape[0])[::-1]: + if time >= time_numbers[i]: + res = int(time // time_numbers[i]) + time = time % time_numbers[i] + s += f"{res}{time_formats[i]} " assert time == 0, "Leftover in formatting time !" return s.rstrip() -def toolbox_unit_test() -> None: - # FIXME Move unit test to different file - assert "0ns" == format_time_ns(0) - assert "1ns" == format_time_ns(1) - assert "1µs" == format_time_ns(int(1e3)) - assert "1ms" == format_time_ns(int(1e6)) - assert "1s" == format_time_ns(int(1e9)) - assert "1m" == format_time_ns(int(6e10)) - assert "1h" == format_time_ns(int(36e11)) - assert "1j" == format_time_ns(int(864e11)) - assert "1w" == format_time_ns(int(6048e11)) - assert "1M" == format_time_ns(int(24192e11)) - assert "1y" == format_time_ns(int(290304e11)) - # UINT64_MAX == 2^64 = 18446744073709551615 == -1 - assert "635y 5M 3j 23h 34m 33s 709ms 551µs 616ns" == format_time_ns(2**64) - def picke_multi_loader(filenames: List[str], save_dir: str = MODEL_DIR) -> List[Any]: """Load multiple pickle data files. diff --git a/python/toolbox_unit_test.py b/python/toolbox_unit_test.py new file mode 100644 index 0000000..a3bc883 --- /dev/null +++ b/python/toolbox_unit_test.py @@ -0,0 +1,67 @@ +from typing import Any +from toolbox import format_time_ns + +def Assert(name: str, expected: Any, result: Any): + if expected != result: + print(f"For test name {name} Expected '{expected}' but got '{result}' instead") + assert False + +def format_time_ns_test() -> None: + # https://en.wikipedia.org/wiki/Unit_of_time + Assert("format_time_ns null", "0ns", format_time_ns(0)); + Assert("format_time_ns nanosecond", "1ns", format_time_ns(1)); + Assert("format_time_ns shake", "10ns", format_time_ns(10)); + Assert("format_time_ns microsecond", "1µs", format_time_ns(int(1e3))); + Assert("format_time_ns millisecond", "1ms", format_time_ns(int(1e6))); + Assert("format_time_ns centisecond", "10ms", format_time_ns(int(1e7))); + Assert("format_time_ns decisecond", "100ms", format_time_ns(int(1e8))); + Assert("format_time_ns second", "1s", format_time_ns(int(1e9))); + Assert("format_time_ns decasecond", "10s", format_time_ns(int(1e10))); + Assert("format_time_ns minute", "1m", format_time_ns(int(6e10))); + Assert("format_time_ns milliday", "1m 26s 400ms", format_time_ns(int(864e8))); + Assert("format_time_ns hectosecond", "1m 40s", format_time_ns(int(1e11))); + Assert("format_time_ns kilosecond", "16m 40s", format_time_ns(int(1e12))); + Assert("format_time_ns hour", "1h", format_time_ns(int(36e11))); + Assert("format_time_ns day", "1j", format_time_ns(int(864e11))); + Assert("format_time_ns week/sennight", "1w", format_time_ns(int(6048e11))); + Assert("format_time_ns megasecond", "1w 4j 13h 46m 40s", format_time_ns(int(1e15))); + Assert("format_time_ns fortnight", "2w", format_time_ns(int(12096e11))); + Assert("format_time_ns lunar month (draconitic)", "3w 6j 5h 5m 35s 800ms", format_time_ns(int(23511358e8))); + Assert("format_time_ns lunar month (tropical)", "3w 6j 7h 43m 4s 700ms", format_time_ns(int(23605847e8))); + Assert("format_time_ns lunar month (sidereal)", "3w 6j 7h 43m 11s 600ms", format_time_ns(int(23605916e8))); + Assert("format_time_ns lunar month (anomalistic)", "3w 6j 13h 18m 33s 200ms", format_time_ns(int(23807132e8))); + Assert("format_time_ns lunar month (synodic)", "4w 1j 12h 44m 2s 900ms", format_time_ns(int(25514429e8))); + Assert("format_time_ns month", "1M", format_time_ns(int(26784e11))); + Assert("format_time_ns quarantine", "1M 1w 2j", format_time_ns(int(3456e12))); + Assert("format_time_ns semester", "4M 2j", format_time_ns(int(108864e11))); + Assert("format_time_ns lunar year", "11M 1w 6j 8h 52m 48s", format_time_ns(int(30617568e9))); + Assert("format_time_ns year", "1y", format_time_ns(int(31536e12))); + Assert("format_time_ns tropical year", "1y 5h 48m 45s 216ms", format_time_ns(int(31556925216e6))); + Assert("format_time_ns gregorian year", "1y 5h 49m 12s", format_time_ns(int(31556952e9))); + Assert("format_time_ns sidereal year", "1y 6h 9m 9s 763ms 545µs 600ns", format_time_ns(int(315581497635456e2))); + Assert("format_time_ns leap year", "1y 1j", format_time_ns(int(316224e11))); + Assert("format_time_ns olympiad", "4y", format_time_ns(int(126144e12))); + Assert("format_time_ns lusturm", "5y", format_time_ns(int(15768e13))); + Assert("format_time_ns decade", "10y", format_time_ns(int(31536e13))); + Assert("format_time_ns indiction", "15y", format_time_ns(int(47304e13))); + Assert("format_time_ns score", "20y", format_time_ns(int(63072e13))); + Assert("format_time_ns gigasecond", "31y 8M 1w 4j 1h 46m 40s", format_time_ns(int(1e18))); + Assert("format_time_ns jubilee", "50y", format_time_ns(int(15768e14))); + Assert("format_time_ns century", "1c", format_time_ns(int(31536e14))); + Assert("format_time_ns millennium", "10c", format_time_ns(int(31536e15))); + Assert("format_time_ns age", "257c 72y", format_time_ns(int(812745792e12))); + Assert("format_time_ns terasecond", "3170c 97y 10M 3w 4j 17h 46m 40s", format_time_ns(int(1e22))); + Assert("format_time_ns megaannum", "10000c", format_time_ns(int(31536e18))); + # Cannot use number bigger than currently supported ISO Python + #Assert("format_time_ns petasecond", "317097c 91y 11M 2w 4j 1h 46m 40s", format_time_ns(int(1e24))); + #Assert("format_time_ns galactic year", "2300000c", format_time_ns(int(725328e19))); + #Assert("format_time_ns eon", "10000000c", format_time_ns(int(31536e21))); + #Assert("format_time_ns kalpa", "43200000c", format_time_ns(int(13623552e19))); + #Assert("format_time_ns exasecond", "317097919c 83y 9M 1h 46m 40s", format_time_ns(int(1e27))); + #Assert("format_time_ns zettasecond", "", format_time_ns(int(1e30))); + #Assert("format_time_ns yottasecond", "", format_time_ns(int(1e33))); + #Assert("format_time_ns ronnasecond", "", format_time_ns(int(1e36))); + #Assert("format_time_ns quettasecond", "", format_time_ns(int(1e39))); + # uint64_t_MAX == 2**64 == 18446744073709551615I64u == -1 + Assert("format_time_ns max", "5c 84y 11M 2j 23h 34m 33s 709ms 551µs 615ns", format_time_ns(2**64 - 1)) +