101 lines
2.3 KiB
Python
Executable file
101 lines
2.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
||
|
||
from dataclasses import dataclass
|
||
from typing import Iterable
|
||
import json
|
||
import numpy
|
||
from . import parse_numberdealers
|
||
|
||
|
||
@dataclass
|
||
class TimeAnalysis:
|
||
avg: float
|
||
stdev: float
|
||
min: float
|
||
perc5 : float
|
||
med: float
|
||
perc95: float
|
||
max: float
|
||
midrange: float
|
||
|
||
|
||
def analyze_times(numbers: Iterable[parse_numberdealers.Message]) -> TimeAnalysis:
|
||
times = []
|
||
prev_time = None
|
||
|
||
for msg in numbers:
|
||
if prev_time is not None:
|
||
times.append((msg.create_at - prev_time) / 1000)
|
||
prev_time = msg.create_at
|
||
|
||
times.sort()
|
||
|
||
min_ = min(times)
|
||
max_ = max(times)
|
||
return TimeAnalysis(
|
||
avg=numpy.mean(times),
|
||
stdev=numpy.std(times),
|
||
min=min_,
|
||
perc5 =numpy.percentile(times, 5),
|
||
med=numpy.median(times),
|
||
perc95=numpy.percentile(times, 95),
|
||
max=max_,
|
||
midrange=(min_ + max_) / 2
|
||
)
|
||
|
||
|
||
def format_time(total_seconds: float):
|
||
if total_seconds < 1:
|
||
return f"{total_seconds:.3f} s"
|
||
if total_seconds < 10:
|
||
return f"{total_seconds:.2f} s"
|
||
if total_seconds < 60:
|
||
return f"{total_seconds:.1f} s"
|
||
|
||
formatted = None
|
||
seconds_str = f"{total_seconds:.0f} s"
|
||
|
||
total_minutes, seconds = divmod(total_seconds, 60)
|
||
total_hours, minutes, = divmod(total_minutes, 60)
|
||
total_days, hours, = divmod(total_hours, 24)
|
||
total_years, days, = divmod(total_days, 365)
|
||
if total_minutes < 60:
|
||
formatted = f"{total_minutes:.0f} min {seconds:.0f} sec"
|
||
elif total_hours < 24:
|
||
formatted = f"{total_hours:.0f} hr {minutes:.0f} min"
|
||
elif total_days < 365:
|
||
formatted = f"{total_days:.0f} days {hours:.0f} hr"
|
||
else:
|
||
formatted = f"{total_years:.0f} yr {days:.0f} days"
|
||
|
||
assert formatted
|
||
return f"{seconds_str} ({formatted})"
|
||
|
||
|
||
def report_times(numbers):
|
||
a = analyze_times(numbers)
|
||
print(f""" μ = {format_time(a.avg)}
|
||
σ = {format_time(a.stdev)}
|
||
|
||
min = {format_time(a.min)}
|
||
P5 = {format_time(a.perc5)}
|
||
median = {format_time(a.med)}
|
||
P95 = {format_time(a.perc95)}
|
||
max = {format_time(a.max)}""")
|
||
|
||
|
||
def main():
|
||
import sys
|
||
numbers, errors = parse_numberdealers.parse(sys.stdin)
|
||
|
||
if numbers == [] and errors == []:
|
||
print("No input data")
|
||
else:
|
||
if numbers == []:
|
||
print("No valid number messages!")
|
||
else:
|
||
print(f"Checked from {numbers[0].recognized_number} up to {numbers[-1].recognized_number}")
|
||
report_times(numbers)
|
||
|
||
if __name__ == '__main__':
|
||
main()
|