check_numberdealers/numberdealers/times.py

102 lines
2.3 KiB
Python
Raw Normal View History

#!/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()