-
Notifications
You must be signed in to change notification settings - Fork 1
/
stats.py
142 lines (111 loc) · 3.92 KB
/
stats.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
'''
Stats module
'''
###########
# IMPORTS #
###########
from dataclasses import dataclass
from typing import Dict, Generator, List, Tuple
import argparse
from message import Message
from file_utils import messages_generator_from_file
################
# Number Class #
################
@dataclass(order=True)
class Number():
mobile: str
copypastas: int = 0
spam: int = 0
@property
def ratio(self) -> float:
'''returns the ratio of spam to copypastas'''
return self.copypastas / self.spam
@property
def ratio_str(self) -> str:
'''returns a string with the raw ratio'''
return f"{self.mobile} with a ratio of {self.ratio} copypastas to regular messages\n"
def copypasta_str(self, pasta: bool = True) -> str:
'''returns a string with the raw copypasta count'''
return f"{self.mobile} has {self.copypastas} copypastas\n" if pasta else \
f"{self.mobile} has {self.spam} spam messages\n"
########
# ARGS #
########
def parse_args() -> argparse.Namespace:
'''parses the args'''
parser = argparse.ArgumentParser(
description='stats module',
usage='python stats.py INPUT [-d]'
)
parser.add_argument(
"src",
metavar="INPUT",
help="the exported file from whatsapp"
)
parser.add_argument(
"-d",
"--debug",
required=False,
action='store_true',
help="DEBUG mode, Enables prints"
)
return parser.parse_args()
#############
# FUNCTIONS #
#############
def add_to_stats(stat_dict: Dict[str, Number],
message: Message) -> None:
'''
adds a message to the stats dict
'''
if message.sender not in stat_dict:
stat_dict[message.sender] = Number(message.sender)
if message.is_copypasta:
stat_dict[message.sender].copypastas += 1
else:
stat_dict[message.sender].spam += 1
def sorted_stats(stat_list: List[Number]) -> \
Generator[Tuple[int, Number], None, None]:
'''sorts and returns the stats in a enumerated list'''
yield from enumerate(sorted(stat_list, reverse=True, key=lambda number: number.ratio))
def write_all_stats(stat_dict: Dict[str, Number],
leaderboard_file: str = "leaderboard.txt",
most_cp_file: str = "most_copypastas.txt",
most_spam_file: str = "most_non_copypastas.txt"
) -> None:
'''
writes all the stats to the a file
'''
with open(leaderboard_file, "w", encoding="utf-8") as out:
number_list = list(stat_dict.values())
for place, number in enumerate(sorted(number_list, reverse=True,
key=lambda number: number.ratio), 1):
out.write(f"{place=} : {number.ratio_str}")
with open(most_cp_file, "w", encoding="utf-8") as out:
for place, number in enumerate(sorted(number_list, reverse=True,
key=lambda number: number.copypastas), 1):
out.write(f"{place=} : {number.copypasta_str()}")
with open(most_spam_file, "w", encoding="utf-8") as out:
for place, number in enumerate(sorted(number_list, reverse=True,
key=lambda number: number.spam), 1):
out.write(f"{place=} : {number.copypasta_str(pasta=False)}")
def main() -> None:
'''main function'''
args: argparse.Namespace = parse_args()
lost: int = 0
pastas: int = 0
stat_dict: Dict[str, Number] = {}
for message in messages_generator_from_file(args.src, args.debug):
if message.is_readable:
add_to_stats(stat_dict, message)
if message.is_copypasta:
pastas += 1
else:
lost += 1
if args.debug:
print(
f"we didn't read {lost} of the messages and {pastas} of them were copypastas")
write_all_stats(stat_dict)
if __name__ == "__main__":
main()