#!/usr/bin/env python3 import sys import re from datetime import datetime from collections import defaultdict from typing import Mapping, Set if sys.stdin.isatty(): print("Hint: stdin is a terminal, you may want to do `./make_table.py < verifications.log` instead.", file=sys.stderr) # users[awardee][post_id][verifier]: score users: Mapping[str, Mapping[str, Mapping[str, int]]] = \ defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: 0))) for line_nr, line in enumerate(sys.stdin, start=1): line = line.rstrip() # {awardee} {post['id']} at {post_time}: {awarder} verified with score {score} m = re.fullmatch(r"([^ ]+) ([^ ]+) at ([^ ]+): ([^ ]+) verified with score ([^ ]+)", line) if m: awardee = m.group(1) post_id = m.group(2) post_time = datetime.fromisoformat(m.group(3)) verifier = m.group(4) score = int(m.group(5)) users[awardee][post_id][verifier] = score continue # {awardee} {post['id']} at {post_time}: {awarder} updated their verification's score from {prev_score} to {score} m = re.fullmatch(r"([^ ]+) ([^ ]+) at ([^ ]+): ([^ ]+) updated their verification's score from ([^ ]+) to ([^ ]+)", line) if m: awardee = m.group(1) post_id = m.group(2) post_time = datetime.fromisoformat(m.group(3)) verifier = m.group(4) prev_score = int(m.group(5)) score = int(m.group(6)) users[awardee][post_id][verifier] = score continue # {awardee} {post['id']} at {post_time}: {awarder} retracted their verification m = re.fullmatch(r"([^ ]+) ([^ ]+) at ([^ ]+): ([^ ]+) retracted their verification", line) if m: awardee = m.group(1) post_id = m.group(2) post_time = datetime.fromisoformat(m.group(3)) verifier = m.group(4) users[awardee][post_id][verifier] = 0 continue print(f"Couldn't parse line {line_nr}, looks like the file is corrupt: {line}", file=sys.stderr) for username, user_posts in users.items(): score = sum( max(post_verifications.values(), default=0) for post_verifications in user_posts.values() ) if score > 0: print(f"{username}: {score}")