-
Notifications
You must be signed in to change notification settings - Fork 0
/
svt_old.py
235 lines (223 loc) · 8.34 KB
/
svt_old.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import pandas as pd
import os, json, copy
from shutil import copyfile
import dateutil.parser as dateparser
from colorama import Fore,Back,Style,init
from termcolor import colored
init()
std_fileloc = "./votes.csv"
filestd = None
while filestd != "y" and filestd != "n":
filestd = input("standard file location? (standard file location is ./votes.csv) y/n: ")
if filestd == "y":
fileloc = std_fileloc
elif filestd == "n":
fileloc = input("file location? \n")
if not os.path.exists(fileloc):
print("file not found")
filestd = None
else:
print("wrong input")
multivote_remove = None
while multivote_remove != "y" and multivote_remove != "n":
multivote_remove = input("remove multiple votes? (uses newest vote from voter) y/n: ")
if multivote_remove == "y":
multivote_remover = True
elif multivote_remove == "n":
multivote_remover = False
else:
print("wrong input")
threshold = -1
while(threshold < 0 or threshold > 100):
threshold = input("enter threshold in %: ")
try:
threshold = int(threshold)
except ValueError:
print("threshold is numbers only (0-100%)")
threshold = -1
continue
if threshold < 0 or threshold > 100:
print("threshold outside range (0-100%)")
print()
df = pd.read_csv(std_fileloc)
columns = df.columns
candidates = []
multivoters = []
for i in range(2, len(columns)):
candidates.append(columns[i])
def check_voters():
if os.path.exists("voterlist.txt"):
with open("voterlist.txt", "r") as file:
try:
voterlist = json.loads(file.read())
except ValueError:
print("error loading voter list. running without and recreating list")
copyfile("voterlist.txt", "bad_voterlist.txt")
os.remove("voterlist.txt")
else:
voterlist = []
voters = df.get(columns[1])
has_voted = []
for voter in voters:
if voter in has_voted:
if voter not in multivoters:
multivoters.append(voter)
else:
has_voted.append(str(voter))
past_voters = len(voterlist)
rec_voters = 0
new_voters = 0
for voter in voters:
if voter in voterlist and voter not in multivoters:
rec_voters = rec_voters + 1
elif voter not in multivoters:
new_voters = new_voters + 1
voterlist.append(str(voter))
for voter in multivoters:
if voter not in voterlist:
new_voters = new_voters + 1
voterlist.append(voter)
else:
rec_voters = rec_voters + 1
abstain_voters = past_voters - rec_voters
println = "total registered voters: %s \nregistered voters: %s \nnon-voting registered voters: %s \nnew voters : %s" % (past_voters, rec_voters, abstain_voters, new_voters)
print(println)
with open("voterlist.txt", "w") as file:
file.write(json.dumps(voterlist))
print()
print("following people voted multiple times:")
print(multivoters)
print()
remove = []
rounds = []
def print_result(votes, roundnr, total_votes):
header = "Results after round " +str(roundnr)+ ":"
high = 0
high_candidates = []
low_candidates = []
low = 1000000
dim = []
for candidate in candidates:
if votes[candidate][0] >= high:
if votes[candidate][0] == high:
high_candidates.append(candidate)
else:
high = votes[candidate][0]
high_candidates = [candidate]
if votes[candidate][0] <= low and votes[candidate][0] != 0:
if votes[candidate][0] == low:
low_candidates.append(candidate)
else:
low = votes[candidate][0]
low_candidates = [candidate]
if votes[candidate][0] == 0:
dim.append(candidate)
print("\033[4m"+Style.BRIGHT+header+Style.RESET_ALL)
for candidate in candidates:
candidate_out = str(candidate) + ": " + str(votes[candidate][0]) + " votes, " + str(round(votes[candidate][0] / total_votes * 100, 2)) + "%"
if candidate in high_candidates:
print("\033[1;92m"+candidate_out+Style.RESET_ALL)
elif candidate in low_candidates:
print("\033[1;91m"+candidate_out+Style.RESET_ALL)
elif candidate in dim:
print("\033[1;90m"+candidate_out+Style.RESET_ALL)
else:
print(Style.BRIGHT+candidate_out)
print()
votes = {}
total_votes = 0
removed_candidates = []
def count_individual(votes, roundnr, removed_candidates):
global total_votes
if roundnr == 1:
for i in df.index:
for j in range(2, len(candidates)+2):
if df.get(columns[j])[i] == roundnr and candidates[j-2] not in removed_candidates:
try:
new_votes = votes[candidates[j-2]][0] + 1
total_votes = total_votes+1
votes[candidates[j-2]] = [new_votes, new_votes/total_votes]
except KeyError:
total_votes = total_votes+1
votes[candidates[j-2]] = [1, 1/total_votes]
elif roundnr == len(candidates):
high = 0
high_candidates = []
for candidate in candidates:
if votes[candidate][0] >= high:
if votes[candidate][0] == high:
high_candidates.append(candidate)
else:
high = votes[candidate][0]
high_candidates = [candidate]
votes[candidate] = [0,0]
if len(high_candidates) > 1:
for candidate in high_candidates:
votes[candidate] = [int(total_votes/len(high_candidates)), 1/len(high_candidates)]
else:
votes[high_candidates[0]] = [total_votes,1]
else:
for candidate in candidates:
votes[candidate]=[0,0]
for i in df.index:
limit = len(candidates)
limit_candidate = None
for j in range(2, len(candidates)+2):
if df.get(columns[j])[i] < limit and candidates[j-2] not in removed_candidates:
limit = df.get(columns[j])[i]
limit_candidate = candidates[j-2]
try:
new_votes = votes[limit_candidate][0] + 1
votes[limit_candidate] = [new_votes, new_votes/total_votes]
except KeyError:
total_votes = total_votes+1
votes[limit_candidate] = [1, 1/total_votes]
for candidate in removed_candidates:
votes[candidate] = [0,0]
def threshold_test(votes, candidates):
for candidate in candidates:
try:
if float(votes[candidate][1]) >= float(threshold)/100:
return False
else:
return True
except KeyError:
return True
def count_votes():
multivote = {}
rounds.append(None)
for i in range(0,len(df.get(columns[1]))): #go through all votes
voter = df.get(columns[1])[i] #get current voter
date = dateparser.parse(df.get(columns[0])[i])
if voter in multivoters:
if voter in multivote.keys():
if date > multivote[voter][0]:
remove.append(multivote[voter][1])
multivote[voter] = [date, i]
else :
remove.append(i)
else:
multivote[voter] = [date, i]
if multivote_remover:
df.drop(remove, inplace=True)
roundnr = 1
while (threshold_test(votes, candidates)):
if roundnr > len(candidates):
break
if roundnr != 1:
low = 1000000
low_candidate = None
for candidate in candidates:
if votes[candidate][0] < low and candidate not in removed_candidates:
low = votes[candidate][0]
low_candidate = candidate
votes[low_candidate] = [0,0]
removed_candidates.append(low_candidate)
count_individual(votes, roundnr, removed_candidates)
for candidate in candidates:
if candidate not in votes.keys():
votes[candidate] = [0,0]
print_result(votes, roundnr, total_votes)
roundnr = roundnr+1
check_voters()
count_votes()