diff --git a/src/data_types/frequency.py b/src/data_types/frequency.py index ef87a80..966a07c 100644 --- a/src/data_types/frequency.py +++ b/src/data_types/frequency.py @@ -1,5 +1,6 @@ from typing import List from datetime import timedelta +import calendar from utils import str_date, str_datetime, from_now @@ -9,16 +10,35 @@ class Frequency: self.dates = [] self.longest_break = timedelta(seconds=0) self.longest_break_start = None + self.week = {i: 0 for i in range(7)} + self.day = {i: 0 for i in range(24)} + self.busiest_day = None + self.busiest_day_count = 0 + self.busiest_hour = None + self.busiest_hour_count = 0 def to_string(self) -> List[str]: + delta = self.dates[-1] - self.dates[0] + total_msg = len(self.dates) + busiest_weekday = sorted(self.week.keys(), key=lambda k: self.week[k])[-1] + busiest_hour = sorted(self.day.keys(), key=lambda k: self.day[k])[-1] + n_weekdays = delta.days // 7 + if ( + self.dates[0].weekday() <= busiest_weekday + and self.dates[-1].weekday() >= busiest_weekday + ): + n_weekdays += 1 + n_hours = delta.days + if self.dates[0].hour <= busiest_hour and self.dates[-1].hour >= busiest_hour: + n_hours += 1 return [ - f"**earliest message:** {str_datetime(self.dates[0])} ({from_now(self.dates[0])})", - f"**latest message:** {str_datetime(self.dates[-1])} ({from_now(self.dates[-1])})", - # "**msg/day:** n", - # "**busiest day of week:** dd (avg. n msg)", - # "**busiest day ever:** jj/mm/yyyy (n days ago) (n msg)", - # "**msg/hour:** n", - # "**busiest hour of day:** hh (avg. n msg)", - # "**busiest hour ever:** hh jj/mm/yyyy (n days ago) (n msg)", - f"**longest break:** {int(self.longest_break.total_seconds() / 3600):,} hours ({int(self.longest_break.days):,} days) from {str_datetime(self.longest_break_start)} ({from_now(self.longest_break_start)})", + f"- **earliest message**: {str_datetime(self.dates[0])} ({from_now(self.dates[0])})", + f"- **latest message**: {str_datetime(self.dates[-1])} ({from_now(self.dates[-1])})", + f"- **messages/day**: {total_msg/delta.days:,.2f}", + f"- **busiest day of week**: {calendar.day_name[busiest_weekday]} (~{self.week[busiest_weekday]/n_weekdays:,.2f} msg) ({round(100*self.week[busiest_weekday]/total_msg)}%)", + f"- **busiest day ever**: {str_date(self.busiest_day)} ({from_now(self.busiest_day)}) ({self.busiest_day_count} msg)", + f"- **messages/hour**: {total_msg*3600/delta.total_seconds():,.2f}", + f"- **busiest hour of day**: {busiest_hour:0>2}:00 (~{self.day[busiest_hour]/n_hours:,.2f} msg) ({round(100*self.day[busiest_hour]/total_msg)}%)", + f"- **busiest hour ever**: {str_datetime(self.busiest_hour)} ({from_now(self.busiest_hour)}) ({self.busiest_hour_count} msg)", + f"- **longest break**: {self.longest_break.total_seconds()//3600:,.0f} hours ({self.longest_break.days:,} days) from {str_datetime(self.longest_break_start)} ({from_now(self.longest_break_start)})", ] diff --git a/src/scanners/frequency_scanner.py b/src/scanners/frequency_scanner.py index 6e6b0d1..a011933 100644 --- a/src/scanners/frequency_scanner.py +++ b/src/scanners/frequency_scanner.py @@ -55,9 +55,38 @@ class FrequencyScanner(Scanner): def compute_results(freq: Frequency): freq.dates.sort() latest = freq.dates[0] + current_day = 0 + current_day_date = freq.dates[0] + current_day_count = 0 + current_hour_buffer = [] for date in freq.dates: + # calculate longest break delay = date - latest if delay > freq.longest_break: freq.longest_break = delay freq.longest_break_start = latest latest = date + # calculate busiest weekday / hours + freq.week[date.weekday()] += 1 + freq.day[date.hour] += 1 + # calculate busiest day ever + start_delta = date - freq.dates[0] + if start_delta.days > current_day: + if current_day_count > freq.busiest_day_count: + freq.busiest_day_count = current_day_count + freq.busiest_day = current_day_date + current_day = start_delta.days + current_day_date = date + current_day_count = 0 + else: + current_day_count += 1 + # calculate busiest hour ever + while ( + len(current_hour_buffer) > 0 + and (date - current_hour_buffer[0]).total_seconds() > 3600 + ): + current_hour_buffer.pop(0) + current_hour_buffer += [date] + if len(current_hour_buffer) > freq.busiest_hour_count: + freq.busiest_hour = current_hour_buffer[0] + freq.busiest_hour_count = len(current_hour_buffer)