Created
January 6, 2013 03:56
-
-
Save robinkraft/4465108 to your computer and use it in GitHub Desktop.
simple ordering implementation in Python for foursquare hackathon dish ranking app - messy messy messy!
This file contains hidden or 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 json | |
| TESTSTRING = '[{ "_id" : "HZXXY3", "venues" : { "A" : [ "B" ], "B" : [ "C" ], "C" : [ ] } }, { "_id" : "HZXXY4", "venues" : { "A" : [ "B" ], "B" : [ "C" ], "C" : [ ] } }, { "_id" : "HZXXY5", "venues" : { "A" : [ "B", "C"], "B" : [ "A", "C" ], "C" : ["A"] } }]' | |
| # initialize ballot dict | |
| # loop through records | |
| # loop through venues | |
| # add or increment "for" ballot for venue | |
| # loop through beaten venues | |
| # add or increment "against" ballot for venue | |
| def increment_venue_ballot(v, k, ballot): | |
| """Given a venue id, 'for' or 'against' key, and the ballot | |
| dictionary, increment the appropriate ballot field. | |
| Ex.: | |
| increment_venue_ballot('a', 'for', {}) | |
| => {'a': {'against': 0, 'for': 1}}""" | |
| if not v in ballot: | |
| ballot[v] = {"for": 0, "against": 0} | |
| ballot[v][k] += 1 | |
| return ballot | |
| def parse_venue(rec, ballot): | |
| """Given record and ballot dictionaries, determine winner and loser.""" | |
| for winner in rec["venues"].keys(): | |
| if len(rec["venues"][winner]) > 0: | |
| ballot = increment_venue_ballot(winner, "for", ballot) | |
| for loser in rec["venues"][winner]: | |
| ballot = increment_venue_ballot(loser, "against", ballot) | |
| return ballot | |
| def parse_records(recs): | |
| """Parse venues from user records, returning ballot""" | |
| ballot = dict() | |
| for rec in recs: | |
| ballot = parse_venue(rec, ballot) | |
| return ballot | |
| def get_margin(votes): | |
| """Calculate voting margin (for - against).""" | |
| return votes["for"] - votes["against"] | |
| def get_venue_tallies(ballot): | |
| """Tally up ballot for ranking.""" | |
| tally = list() | |
| for venue in ballot.keys(): | |
| tally.append({"venue":venue, | |
| "margin":get_margin(ballot[venue]), | |
| "against":ballot[venue]["against"]}) | |
| return tally | |
| def rank_venues(tallies): | |
| """Rank venues based on vote margin and number of votes against | |
| (tiebreaker).""" | |
| sorted_tallies = sorted(tallies, | |
| key=lambda k: (-k['margin'], k['against'])) | |
| return sorted_tallies | |
| def main(s): | |
| records = json.loads(s) | |
| ballot = parse_records(records) | |
| tallies = get_venue_tallies(ballot) | |
| ranks = rank_venues(tallies) | |
| for rec in ranks: | |
| print rec["venue"], rec["margin"], rec["against"] | |
| return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment