Created
December 17, 2015 15:29
-
-
Save TylerFisher/82de1ec90742d610c2de to your computer and use it in GitHub Desktop.
Sample agate-based script for tallying the results for the All Songs Considered listeners poll: http://www.npr.org/sections/allsongs/2015/12/16/459822811/poll-results-listeners-pick-their-favorite-albums-of-2015
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import agate | |
data = {} | |
output = {} | |
""" | |
Converts all entries to lowercase for easier matching. | |
""" | |
def process_csv(): | |
lowered_list = [] | |
with open('responses.csv', 'r') as f: | |
reader = agate.csv_py2.Reader(f) | |
for row in reader: | |
lowered_list.append([element.lower() for element in row]) | |
with open('build.csv', 'w') as f: | |
writer = agate.csv_py2.Writer(f) | |
for row in lowered_list: | |
writer.writerow(row) | |
""" | |
Load data into agate. | |
""" | |
def load_data(): | |
data['responses'] = agate.Table.from_csv('build.csv') | |
""" | |
Count votes in each column so we can combine them later. | |
""" | |
def count_votes(): | |
first = data['responses'].group_by('first') | |
data['first'] = first.aggregate([ | |
('votes', agate.Length()) | |
]) | |
second = data['responses'].group_by('second') | |
data['second'] = second.aggregate([ | |
('votes', agate.Length()) | |
]) | |
third = data['responses'].group_by('third') | |
data['third'] = third.aggregate([ | |
('votes', agate.Length()) | |
]) | |
fourth = data['responses'].group_by('fourth') | |
data['fourth'] = fourth.aggregate([ | |
('votes', agate.Length()) | |
]) | |
fifth = data['responses'].group_by('fifth') | |
data['fifth'] = fifth.aggregate([ | |
('votes', agate.Length()) | |
]) | |
""" | |
Pull tables out of agate so we can easily tabulate ranks and | |
put it into a new dataset. | |
""" | |
def rank_albums(): | |
for table in [ | |
(data['first'], 'first'), | |
(data['second'], 'second'), | |
(data['third'], 'third'), | |
(data['fourth'], 'fourth'), | |
(data['fifth'], 'fifth') | |
]: | |
for row in table[0].rows: | |
album = row[table[1]] | |
if album: | |
if album not in output: | |
output[album] = {} | |
output[album][table[1]] = row[1] | |
for album in output: | |
unweighted = 0 | |
weighted = 0 | |
object = output[album] | |
for key in [ | |
('first', 5), | |
('second', 4), | |
('third', 3), | |
('fourth', 2), | |
('fifth', 1) | |
]: | |
if key[0] in object: | |
unweighted += object[key[0]] | |
weighted += object[key[0]] * key[1] | |
object['unweighted'] = unweighted | |
object['weighted'] = weighted | |
""" | |
Load our new data into an agate table. | |
""" | |
def reload_data(): | |
column_names = [ | |
'album', | |
'unweighted', | |
'weighted', | |
'first', | |
'second', | |
'third', | |
'fourth', | |
'fifth' | |
] | |
column_types = [ | |
agate.Text(), | |
agate.Number(), | |
agate.Number(), | |
agate.Number(), | |
agate.Number(), | |
agate.Number(), | |
agate.Number(), | |
agate.Number() | |
] | |
rows = [] | |
for album in output: | |
rows.append((album, output[album]['unweighted'], output[album]['weighted'])) | |
data['ranks'] = agate.Table(rows, column_names, column_types) | |
""" | |
Print the data. | |
""" | |
def sort_ranks(): | |
unweighted_sorted = data['ranks']\ | |
.select(('album', 'unweighted'))\ | |
.order_by('unweighted', reverse=True) | |
unweighted_sorted.print_table(102) | |
weighted_sorted = data['ranks']\ | |
.select(('album', 'weighted'))\ | |
.order_by('weighted', reverse=True) | |
weighted_sorted.print_table(102) | |
if __name__ == '__main__': | |
process_csv() | |
load_data() | |
count_votes() | |
rank_albums() | |
reload_data() | |
sort_ranks() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment