Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@DomiDre
Last active November 20, 2019 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DomiDre/dd592df37add898491de85e329736e40 to your computer and use it in GitHub Desktop.
Save DomiDre/dd592df37add898491de85e329736e40 to your computer and use it in GitHub Desktop.
Determine from Whatsapp Logs, who has posted how many times 1337 at 13:37 throughout the years
from dataclasses import dataclass
import re, datetime
LEETTIME = "1337"
LEET_HOUR = "13"
LEET_MINUTE = "37"
datasrc = "./whatsapplog.txt"
scores = {}
class Score:
def __init__(self, name):
self.name = name
self.score = 0
self.posted_dates = {}
def add(self, date = None):
self.score += 1
if date:
self.posted_dates[date] = True
def subtract(self):
self.score -= 1
def __lt__(self, other):
return self.score < other.score
@dataclass
class MessageLine:
date: str
hour: int
minute: int
user_name: str
text: str
def read_message_line(line):
# extract date, time user and message from the line
matchObj = re.match(r'\s*(\d{2}\.\d{2}\.\d{2}),\s(\d{2}):(\d{2})\s-\s(\D+):\s(.*)', line)
# print(line)
# skip lines that are just multi line bla bla
if not matchObj:
return
date = matchObj.group(1)
hour = matchObj.group(2)
minute = matchObj.group(3)
user_name = matchObj.group(4)
text = matchObj.group(5)
return MessageLine(date, hour, minute, user_name, text)
def eval_current_day(day_scorers):
if len(day_scorers) == 0:
return
elif len(day_scorers) == 1:
scores[day_scorers[0]].add()
def is_leet(hour, minute):
return (hour == LEET_HOUR or hour == "14") and minute == LEET_MINUTE
def check_user_on_scoreboard(user_name):
if not user_name in scores:
scores[user_name] = Score(user_name)
with open(datasrc, 'r') as f:
current_day = 0
day_scorers = []
for line in f:
# only want lines that contain a date and time at the beginning. Search 1337 lines at 13:37
message = read_message_line(line)
if not message:
continue
day_ts = datetime.datetime.strptime(message.date, '%d.%m.%y').timestamp()
if day_ts > current_day:
eval_current_day(day_scorers)
day_scorers = []
current_day = day_ts
is_leet_time = is_leet(message.hour, message.minute)
if is_leet_time and message.text == LEETTIME:
# check if user is already within score board, otherwise initialize
check_user_on_scoreboard(message.user_name)
# if hasn't already scored today:
# add one point and note that has scored today
if not message.date in scores[message.user_name].posted_dates:
scores[message.user_name].add(message.date)
day_scorers.append(message.user_name)
if message.text == LEETTIME and not is_leet_time:
check_user_on_scoreboard(message.user_name)
scores[message.user_name].subtract()
# final day evaluation
eval_current_day(day_scorers)
for score in sorted(scores.values()):
print(f'{score.name}: {score.score}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment