|
Post by Pleonast on Jan 6, 2014 9:38:44 GMT -8
# -- VoteCount.py -- 6 Jan 2014
""" Copyright 2014 Pleonast on boards.straightdope.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. """
class Day_t: def __init__(Self,Name,Num,LastPost): Self._Name=Name Self._Num=Num Self._LastPost=LastPost
class Player_t: def __init__(Self,Name,Alias,Align=None): Self._Name=Name Self._Alias=Alias Self._Align=Align Self._VotesAsSource=[] Self._UnvotesAsSource=[] Self._NetVotesAsSource=[] Self._VotesAsTarget=[] Self._UnvotesAsTarget=[] Self._NetVotesAsTarget=[] Self._SortValue=(-float('inf'),) def AddVoteAsSource(Self,Vote): if Vote._Source!=Self._Alias: return # prevent voting if already have vote on target for v in Self._NetVotesAsSource: if v._Target==Vote._Target: return Self._VotesAsSource+=[Vote] Self._VotesAsSource.sort(key=lambda vote:(vote._Post,vote._Target)) Self._NetVotesAsSource+=[Vote] def AddVoteAsTarget(Self,Vote): if Vote._Target!=Self._Alias: return # prevent voting if already have vote from source for v in Self._NetVotesAsTarget: if v._Source==Vote._Source: return Self._VotesAsTarget+=[Vote] Self._VotesAsTarget.sort(key=lambda vote:(vote._Post,vote._Source)) Self._NetVotesAsTarget+=[Vote] def AddUnvoteAsSource(Self,Unvote): if Unvote._Source!=Self._Alias: return # only unvote if vote is present for v in Self._NetVotesAsSource[:]: if v._Target==Unvote._Target: Self._UnvotesAsSource+=[Unvote] Self._NetVotesAsSource.remove(v) return def AddUnvoteAsTarget(Self,Unvote): if Unvote._Target!=Self._Alias: return # only unvote if vote is present for v in Self._NetVotesAsTarget[:]: if v._Source==Unvote._Source: Self._UnvotesAsTarget+=[Unvote] Self._NetVotesAsTarget.remove(v) return def CheckAlign(Self,Aligns): if Self._Align and Self._Align not in Aligns: raise ValueError(Self._Name+' has unknown alignment '+Self._Align) def StrVotesAsSource(Self,Players,StrikeCode,Aligns): output='' if Self._Align: output+='[color='+Aligns[Self._Align]._Color+']' output+='[b]'+Self._Name+'[/b]' if Self._Align: output+='[/color]' output+=' has ' numVotes=len(Self._NetVotesAsSource) if len(Self._VotesAsSource)==0: output+='not voted.\n' return output output+='voted for' isFirst=True unvotes=Self._UnvotesAsSource[:] for vote in Self._VotesAsSource: unvote=None for u in unvotes: if u._Target==vote._Target: unvote=u unvotes.remove(u) break if isFirst: isFirst=False else: output+=',' output+=' ' if unvote: output+='['+StrikeCode+']' if Players[vote._Target]._Align: output+=('[color='+ Aligns[Players[vote._Target]._Align]._Color+']') output+=Players[vote._Target]._Name if Players[vote._Target]._Align: output+='[/color]' output+=' ('+str(vote._Post) if unvote: output+='-'+str(unvote._Post) output+=')' if unvote: output+='[/'+StrikeCode+']' if isFirst: output+=' not voted' output+='.\n' return output def StrVotesAsTarget(Self,Players,StrikeCode,Aligns): output='' if Self._Align: output+='[color='+Aligns[Self._Align]._Color+']' output+='[b]'+Self._Name+'[/b]' if Self._Align: output+='[/color]' output+=' has ' numVotes=len(Self._NetVotesAsTarget) if len(Self._VotesAsTarget)==0: output+='no votes.\n' return output output+=str(numVotes)+' vote' if numVotes!=1: output+='s' if Self._Alias=='ham' or Self._Alias=='fil': output+=' [of '+str((len(Players)-3+1)//2)+' needed]' output+=' from' isFirst=True unvotes=Self._UnvotesAsTarget[:] for vote in Self._VotesAsTarget: unvote=None for u in unvotes: if u._Source==vote._Source: unvote=u unvotes.remove(u) break if isFirst: isFirst=False else: output+=',' output+=' ' if unvote: output+='['+StrikeCode+']' if Players[vote._Source]._Align: output+=('[color='+ Aligns[Players[vote._Source]._Align]._Color+']') output+=Players[vote._Source]._Name if Players[vote._Source]._Align: output+='[/color]' output+=' ('+str(vote._Post) if unvote: output+='-'+str(unvote._Post) output+=')' if unvote: output+='[/'+StrikeCode+']' if isFirst: output+=' no votes' output+='.\n' return output
class Align_t: def __init__(Self,Name,Alias,Color): Self._Name=Name Self._Alias=Alias Self._Color=Color def StrLegend(Self): return '[color='+Self._Color+']'+Self._Name+'[/color]\n'
class Vote_t: def __init__(Self,Source,Target,Post): Self._Source=Source Self._Target=Target Self._Post=Post
def CheckAlias(Players,Alias): if not Alias in Players: raise ValueError('unknown alias '+Alias)
def ApplyVote(Players,Source,Target,Post): CheckAlias(Players,Source) CheckAlias(Players,Target) vote=Vote_t(Source,Target,Post) Players[Source].AddVoteAsSource(vote) Players[Target].AddVoteAsTarget(vote)
def ApplyUnvote(Players,Source,Target,Post): CheckAlias(Players,Source) CheckAlias(Players,Target) vote=Vote_t(Source,Target,Post) Players[Source].AddUnvoteAsSource(vote) Players[Target].AddUnvoteAsTarget(vote)
def ApplyUnvoteAll(Players,Source,Post): CheckAlias(Players,Source) for player in Players: ApplyUnvote(Players,Source,player,Post)
def GetDayNightStr(Day): dayInt=round(Day) dayDiff=Day-dayInt if abs(dayDiff)<0.1: return 'D'+str(dayInt) else: return 'N'+str(int(Day))
def GetLynchOrder(Players): lynchOrder=[] for alias in Players: if alias=='ham' or alias=='fil': continue if alias=='no': Players[alias]._SortValue=(-len(Players[alias]._NetVotesAsTarget), '~') else: Players[alias]._SortValue=(-len(Players[alias]._NetVotesAsTarget), Players[alias]._Name.lower()) lynchOrder+=[Players[alias]] lynchOrder.sort(key=lambda Player:Player._SortValue) return lynchOrder
def GetLynchPlayer(LynchOrder): # depends on No Lynch sorting after players with same number of votes player0=LynchOrder[0] votes0=len(player0._NetVotesAsTarget) player1=LynchOrder[1] votes1=len(player1._NetVotesAsTarget) if player0._Alias=='no': return 'no' elif player1._Alias=='no': return player0 elif votes0==votes1: return 'tie' else: return player0
def GetNameOrder(Players): nameOrder=[] for alias in Players: if alias=='ham' or alias=='fil' or alias=='no': continue nameOrder+=[Players[alias]] nameOrder.sort(key=lambda Player:Player._Name.lower()) return nameOrder
def Main(): # initialize day=None players={} players['no']=Player_t('No Lynch','no') players['ham']=Player_t('Hammer','ham') players['fil']=Player_t('Filibuster','fil') postMax=0 strikeCode='del' aligns={} # read input try: lineCount=0 while True: line=input() lineCount+=1 if not line: continue words=line.split(',') try: if words[0].startswith('d'): # d,DayName,DayNum,LastPost # add day info dayName=words[1] dayNum=int(words[2]) lastPost=int(words[3]) day=Day_t(dayName,dayNum,lastPost) elif words[0].startswith('p'): # p,Name,Alias[,Align] # add player to list, with align if known name=words[1] alias=words[2] if len(words)>=4: align=words[3] else: align=None players[alias]=Player_t(name,alias,align) elif words[0].startswith('v'): # v,Post,SourceAlias,TargetAlias(es),... # record vote post=int(words[1]) source=words[2] if len(words)<4: raise ValueError('Missing target') for idx in range(3,len(words)): target=words[idx] ApplyVote(players,source,target,post) if post>postMax: postMax=post elif words[0].startswith('u'): # u,Post,SourceAlias,TargetAlias(es),... # record unvote post=int(words[1]) source=words[2] if len(words)<4: raise ValueError('Missing target') for idx in range(3,len(words)): target=words[idx] if target=='all': ApplyUnvoteAll(players,source,post) else: ApplyUnvote(players,source,target,post) if post>postMax: postMax=post elif words[0].startswith('s'): # s,StrikethroughCode # set strike-through bb code, default is del strikeCode=words[1] elif words[0].startswith('a'): # a,Name,Alias,Color # set up alignment name=words[1] alias=words[2] color=words[3] aligns[alias]=Align_t(name,alias,color) else: raise ValueError('Unknown command '+words[0]) except (ValueError,IndexError): print('Error on line',lineCount,':',line) except EOFError: pass if not day: raise ValueError('Day not defined') if day._LastPost and postMax>day._LastPost: day._LastPost=postMax # check alignments are defined for player in players: players[player].CheckAlign(aligns) # do output output='' output+='[u]' if day._LastPost: output+='Current' else: output+='Final' output+=' Day '+day._Name+' Vote Count[/u]\n' # get lynch output+='\n' lynchOrder=GetLynchOrder(players) lynchPlayer=GetLynchPlayer(lynchOrder) if lynchPlayer=='no': lynchName='no one' elif lynchPlayer=='tie': lynchName='you don\'t know who' else: lynchName='[b]'+lynchPlayer._Name+'[/b]' if day._LastPost: if players['ham']._NetVotesAsTarget: output+=players['ham'].StrVotesAsTarget(players,strikeCode,aligns) if players['fil']._NetVotesAsTarget: output+=players['fil'].StrVotesAsTarget(players,strikeCode,aligns) if (players['ham']._NetVotesAsTarget or players['fil']._NetVotesAsTarget): output+='\n' output+=('Given these votes as of Post '+str(day._LastPost)+', ' +lynchName+' will be lynched.\n') else: output+='With these votes, '+lynchName+' was lynched.\n' # votes on players output+='\n' for player in lynchOrder: output+=player.StrVotesAsTarget(players,strikeCode,aligns) # votes by players output+='\n' nameOrder=GetNameOrder(players) for player in nameOrder: output+=player.StrVotesAsSource(players,strikeCode,aligns) # alignment legend output+='\n' for align in aligns: output+=aligns[align].StrLegend() print(output)
if __name__=='__main__': # multiprocessing.freeze_support() Main()
# -- VoteCount.py
|
|
|
Post by Pleonast on Jan 6, 2014 9:39:10 GMT -8
d,One,1,0
p,Scáthach,scat p,Idle Thoughts,idle p,Merestil Haye,haye p,SisterCoyote,sis p,Tinker,tink p,LightFoot,foot p,Suburban Plankton,sub p,Askthepizzaguy,pizza p,sinjin,sin p,Mahaloth,mah p,Heterometrus swammerdami,het p,BillMc,bill p,Packratter,pack p,EnderBoy,boy p,gnarlycharlie,gnarl p,Giraffe,raf p,Brewha,brew p,Silver Jan,jan p,Colby11,colb p,TexCat,tex p,Dizzymrslizzy,liz p,guiri,gui p,Archangel,arch
v,10,bill,no v,60,scat,idle v,62,het,no v,63,tex,idle,pizza,bill v,64,tex,het v,66,sis,tex v,69,raf,scat,tex v,71,mah,tex v,72,mah,scat u,73,bill,no v,73,bill,tex v,78,brew,no v,80,tink,pizza,arch,jan v,81,sin,idle v,82,raf,sin v,88,sin,raf v,110,pack,no v,114,idle,sin v,120,pizza,mah u,126,tink,pizza v,132,gnarl,tex,scat,sin,tink v,133,liz,no u,137,sin,all v,137,sin,no v,141,het,scat,tex u,141,het,no u,142,tex,all v,142,tex,idle,mah u,145,het,all v,145,het,no v,148,jan,tex,mah v,150,idle,tex u,154,tink,jan v,164,colb,sin,scat,mah u,166,colb,all v,166,colb,mah u,167,scat,idle v,168,scat,mah v,170,het,mah v,175,sub,mah,tink v,183,foot,tink u,201,sin,all v,201,sin,mah u,207,jan,mah u,208,het,mah u,250,pack,no v,250,pack,mah v,251,pack,sin v,255,gui,pack u,268,raf,scat,tex v,268,raf,pack v,279,sin,arch,boy,haye v,286,colb,pack v,287,tink,foot v,288,het,pizza,tex,colb,scat,sub,sin,pack u,290,brew,no v,290,brew,pack u,292,pack,all v,292,pack,gui v,294,tex,gui v,296,boy,sin u,298,sin,boy u,299,scat,mah v,299,scat,pack,gnarl v,302,gui,pizza v,303,haye,pack,het u,304,liz,no v,304,liz,het,sin v,306,pack,tex u,309,sub,mah u,310,raf,pack v,310,raf,tex u,311,gui,pack u,318,tex,all v,318,tex,no v,321,gui,tex
|
|
|
Post by Pleonast on Jan 17, 2014 7:27:46 GMT -8
d,Two,2,0
p,Scáthach,scat p,Idle Thoughts,idle p,Merestil Haye,haye p,SisterCoyote,sis p,Tinker,tink p,LightFoot,foot p,Suburban Plankton,sub p,Askthepizzaguy,pizza p,sinjin,sin p,Mahaloth,mah p,Heterometrus swammerdami,het p,BillMc,bill p,Packratter,pack p,EnderBoy,boy p,gnarlycharlie,gnarl p,Giraffe,raf p,Brewha,brew p,Silver Jan,jan p,Colby11,colb p,Dizzymrslizzy,liz p,guiri,gui p,Red Skeezix,red
v,33,idle,sin v,34,colb,raf v,45,raf,brew v,62,brew,sin v,64,brew,raf u,68,brew,sin,raf v,68,brew,sin,raf v,70,red,raf v,72,liz,raf u,73,red,raf v,88,jan,brew v,101,idle,gui v,102,idle,brew v,103,red,brew v,104,het,brew v,105,gui,sub,pizza u,108,het,brew v,108,het,sin v,112,tink,pack v,117,pizza,gui u,118,pizza,gui v,119,pizza,boy,haye,colb v,120,gnarl,pizza u,121,raf,brew v,121,raf,foot,haye,boy,bill v,139,scat,pack u,144,scat,pack u,150,pizza,colb v,150,pizza,bill u,151,pizza,boy v,151,pizza,red u,156,pizza,haye v,159,het,pizza v,175,haye,pizza v,180,scat,pizza v,198,raf,pack v,202,sub,raf u,203,brew,raf,sin v,207,bill,no v,214,mah,bill u,216,red,brew v,220,red,liz v,223,boy,brew v,225,gnarl,pack u,226,het,sin u,227,jan,brew v,227,jan,pack v,228,het,pack v,232,scat,pack u,234,liz,raf v,235,brew,pack v,239,liz,haye u,247,jan,pack v,247,jan,pizza u,254,het,pack u,262,brew,pack v,262,brew,no v,269,sin,pizza v,270,sis,no u,273,sis,no v,273,sis,sin v,276,sin,sis u,282,sin,pizza u,284,gui,pizza,sub v,284,gui,no u,286,jan,pizza u,288,het,pizza v,288,het,haye,no v,289,jan,tink v,292,colb,fil v,298,sin,fil u,300,sin,fil v,300,sin,fil u,301,jan,all v,301,jan,fil v,303,boy,fil v,305,sub,fil v,307,tink,fil v,308,raf,fil v,311,colb,haye u,312,raf,haye,bill u,314,sub,raf v,314,sub,no u,315,haye,pizza v,315,haye,no v,316,scat,fil u,317,scat,pizza v,318,het,fil v,319,gui,fil v,322,haye,fil v,324,foot,fil u,328,sub,no v,331,sub,colb u,334,sub,fil u,337,haye,fil,no u,338,het,no v,340,mah,sub u,344,colb,fil u,346,raf,fil v,347,raf,colb,liz,haye u,347,raf,pack u,360,sub,mah v,360,sub,pack u,361,red,liz u,366,sub,pack v,369,idle,haye u,370,idle,sin u,371,gui,all v,371,gui,foot v,374,jan,haye v,376,het,foot v,382,het,mah v,389,sub,foot u,391,sub,foot v,397,red,brew v,407,raf,brew v,409,scat,haye,brew v,411,pack,gui v,412,foot,brew,colb u,413,sin,fil v,413,sin,brew u,414,raf,haye u,429,brew,no v,429,brew,boy,scat,foot u,430,brew,sin u,436,boy,fil v,442,brew,haye
|
|
|
Post by Pleonast on Jan 28, 2014 12:27:27 GMT -8
d,Three,3,0
p,Scáthach,scat p,Idle Thoughts,idle p,Merestil Haye,haye p,SisterCoyote,sis p,Tinker,tink p,LightFoot,foot p,Suburban Plankton,sub p,Askthepizzaguy,pizza p,sinjin,sin p,Mahaloth,mah p,Heterometrus swammerdami,het p,BillMc,bill p,Packratter,pack p,EnderBoy,boy p,gnarlycharlie,gnarl p,Giraffe,raf p,Silver Jan,jan p,Colby11,colb p,Dizzymrslizzy,liz p,guiri,gui p,Red Skeezix,red
v,6,pizza,haye,het v,9,gui,haye v,11,raf,haye v,14,scat,haye v,15,liz,haye,ham v,20,sis,haye v,23,tink,haye v,34,mah,haye,ham v,44,colb,haye v,50,boy,haye,foot v,51,sin,haye v,54,foot,haye v,55,red,haye,ham v,58,het,haye,ham,fil v,63,idle,haye v,66,jan,haye,ham v,70,pack,haye,foot,raf v,71,colb,raf,ham v,73,liz,raf v,86,gnarl,haye v,88,foot,colb v,89,colb,foot v,101,sub,haye,raf v,121,raf,colb,pack v,122,haye,no
|
|
|
Post by Pleonast on Jan 31, 2014 14:02:02 GMT -8
d,Four,4,0
p,Scáthach,scat p,Idle Thoughts,idle p,Merestil Haye,haye p,SisterCoyote,sis p,Tinker,tink p,LightFoot,foot p,Suburban Plankton,sub p,Askthepizzaguy,pizza p,sinjin,sin p,Mahaloth,mah p,Heterometrus swammerdami,het p,BillMc,bill p,Packratter,pack p,EnderBoy,boy p,gnarlycharlie,gnarl p,Silver Jan,jan p,Colby11,colb p,Dizzymrslizzy,liz p,guiri,gui p,Red Skeezix,red
v,3,foot,haye v,5,boy,haye v,12,sis,haye v,14,mah,haye v,17,red,haye,het,ham v,18,idle,haye v,19,sin,haye v,23,sin,ham v,30,mah,ham v,31,colb,haye,het,boy,ham v,34,liz,haye,boy,het,ham v,37,het,haye v,39,boy,red,ham v,42,gui,haye,het,bill v,45,pizza,haye v,47,jan,haye,ham v,48,scat,haye v,53,tink,haye v,66,bill,haye v,67,sub,haye v,70,haye,no v,83,pack,haye v,91,gnarl,haye,het v,96,tink,het,bill v,99,gui,ham v,102,scat,ham v,106,het,ham
|
|
|
Post by Pleonast on Feb 7, 2014 12:34:35 GMT -8
d,Five,5,0
p,Scáthach,scat p,Idle Thoughts,idle p,SisterCoyote,sis p,Tinker,tink p,LightFoot,foot p,Suburban Plankton,sub p,Askthepizzaguy,pizza p,sinjin,sin p,Mahaloth,mah p,Heterometrus swammerdami,het p,BillMc,bill p,Packratter,pack p,EnderBoy,boy p,gnarlycharlie,gnarl p,Silver Jan,jan p,Colby11,colb p,Dizzymrslizzy,liz p,guiri,gui p,Red Skeezix,red
v,2,gui,fil v,8,red,het v,17,sin,bill v,19,het,mah v,23,pizza,het v,35,idle,het v,43,tink,het v,57,colb,boy v,58,colb,fil v,59,het,boy v,70,jan,het v,71,tink,fil v,72,scat,fil u,73,het,boy v,73,het,fil v,74,gui,no v,75,gnarl,no,fil v,78,boy,colb v,79,foot,colb
|
|