102 lines
2.3 KiB
Python
102 lines
2.3 KiB
Python
|
#!/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()
|