Skip to content

Commit

Permalink
'Refactored by Sourcery'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sourcery AI committed Jan 19, 2023
1 parent edf1735 commit 9b91c1e
Show file tree
Hide file tree
Showing 13 changed files with 266 additions and 279 deletions.
14 changes: 6 additions & 8 deletions .ipynb_checkpoints/vse2-checkpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ def __init__(self, model, methodsAndStrats,
fgs.extend([(paramStrat(m.diehardBallot, intensity=i), targetFunc) for i in m.diehardLevels]
+ [(paramStrat(m.compBallot, intensity=i), targetFunc) for i in m.compLevels])
fgs.append((swapPolls(m.lowInfoBallot), targetFunc))
for bg in [m.honBallot, m.lowInfoBallot]:
ms.append((m, bg, fgs))
ms.extend((m, bg, fgs) for bg in [m.honBallot, m.lowInfoBallot])
else:
ms.append(m)
for i in range(niter):
Expand All @@ -55,12 +54,11 @@ def saveFile(self, baseName="SimResults"):
i = 1
while os.path.isfile(baseName + str(i) + ".csv"):
i += 1
myFile = open(baseName + str(i) + ".csv", "w")
dw = csv.DictWriter(myFile, self.rows[0].keys(), restval="NA")
dw.writeheader()
for r in self.rows:
dw.writerow(r)
myFile.close()
with open(baseName + str(i) + ".csv", "w") as myFile:
dw = csv.DictWriter(myFile, self.rows[0].keys(), restval="NA")
dw.writeheader()
for r in self.rows:
dw.writerow(r)


def compareStrats(method, model, backgroundStrat, nvot, ncand, niter): pass
2 changes: 1 addition & 1 deletion ballotEval.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def stratStats(model, strat, nvot, ncand, niter, stratArgs={}, numWinners=1, pol
usePolls=True, pickiness=0.7, pollFilter=None):
bulletCount, totalScore = 0, 0
scoreCounts = collections.Counter()
for i in range(niter):
for _ in range(niter):
electorate = model(nvot, ncand)
if usePolls:
pollBallots = [Approval.zeroInfoBallot(v, pickiness=pickiness) for v in electorate]
Expand Down
56 changes: 34 additions & 22 deletions cid.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,15 @@ def influentialBlocs(voters, method, numWinners=1, utilChange=0.1, numBuckets=5,
pollingMethod = method
pollingStrat = method.honBallot
basePollBallots = [pollingStrat(v, numWinners=numWinners, **pollingStratArgs) for v in voters]
pollErrors = [random.gauss(0, pollingError/2) for i in range(numCands)]
pollErrors = [random.gauss(0, pollingError/2) for _ in range(numCands)]
polls = [min(1, max(0, r + e)) for r, e in zip(pollingMethod.results(basePollBallots), pollErrors)]
#polls = media(pollingMethod.results(pollBallots), pollingError) #method.results can't depend on numWinners; this may need to be changed
baseBallots = [strat(v, polls=polls, electabilities=polls, numWinners=numWinners, **stratArgs) for v in voters]
if isinstance(sorter, type):
sorter = sorter(voters)
baseWinners = method.winnerSet(baseBallots, numWinners)
baseResults = method.results(baseBallots)
isIncentive = [[] for i in range(numCands)]
isIncentive = [[] for _ in range(numCands)]
#isIncentive[c][b] is 1 if candidate c is incentivized to appeal to the bth bucket of voters, 0 otherwise
for cand in range(numCands):
utilShifts = [0]*numCands
Expand Down Expand Up @@ -205,7 +205,7 @@ def __init__(self, model, methodsAndStrats, nvot, ncand, niter, nwinners=1,
elif len(m) == 2:
ms.append((m[0], m[1], {}))
else: ms.append(m)
self.mNames = [m[0].__name__ + ':' + m[1].__name__ + str(m[2]) for m in ms]
self.mNames = [f'{m[0].__name__}:{m[1].__name__}{str(m[2])}' for m in ms]
self.rows = []
args = (model, nvot, ncand, ms, nwinners, utilChange, numBuckets, sorter, pollingMethod, pollingError, pollAfterPert)
with multiprocessing.Pool(processes=7) as pool:
Expand Down Expand Up @@ -233,7 +233,10 @@ def chart(self, methodOnly=True):
fig, ax = plt.subplots()
incentFracts = self.summarize()[0]
if methodOnly:
incentFracts = {re.match(".*(?=:)", name).group(0): data for name, data in incentFracts.items()}
incentFracts = {
re.match(".*(?=:)", name)[0]: data
for name, data in incentFracts.items()
}
for name, data in incentFracts.items():
ax.plot([i/self.numBuckets for i in range(1, self.numBuckets+1)], data, label=name)
#ax.set_xlim(1, self.numBuckets)
Expand All @@ -258,16 +261,17 @@ def saveFile(self, baseName="cidResults", newFile=True):
fields = ['name', 'baseResult'] + list(range(self.numBuckets)) + list(universalInfo.keys())
resultTypeIndices = {'all': 1, 'loss': 2, 'win': 3}

myFile = open(baseName + (str(i) if newFile else "") + ".csv", "w")
dw = csv.DictWriter(myFile, fields, restval="data missing")
dw.writeheader()
for outcome, index in resultTypeIndices.items():
for name, results in self.summarize()[index].items():
row = {'name': name, 'baseResult': outcome}
row.update({i: result for i, result in enumerate(results)})
row.update(universalInfo)
dw.writerow(row)
myFile.close()
with open(baseName + (str(i) if newFile else "") + ".csv", "w") as myFile:
dw = csv.DictWriter(myFile, fields, restval="data missing")
dw.writeheader()
for outcome, index in resultTypeIndices.items():
for name, results in self.summarize()[index].items():
row = (
{'name': name, 'baseResult': outcome}
| enumerate(results)
| universalInfo
)
dw.writerow(row)

def simOneElectorate(model, nvot, ncand, ms, nwinners, utilChange, numBuckets, sorter,
pollingMethod, pollingError, pollAfterPert, baseSeed=None, i = 0):
Expand All @@ -280,9 +284,17 @@ def simOneElectorate(model, nvot, ncand, ms, nwinners, utilChange, numBuckets, s
for method, strat, stratArgs in ms:
allIncentives, baseWinners, baseResults = influentialBlocs(electorate, method, nwinners, utilChange, numBuckets,
sorter, strat, stratArgs, pollingMethod, pollAfterPert=pollAfterPert, pollingError=pollingError)
for i, candIncentives in enumerate(allIncentives):
results.append(dict(incentives=candIncentives, isWinner=i in baseWinners,
method=method.__name__, strat=strat.__name__, stratArgs=stratArgs, voterModel=str(model)))
results.extend(
dict(
incentives=candIncentives,
isWinner=i in baseWinners,
method=method.__name__,
strat=strat.__name__,
stratArgs=stratArgs,
voterModel=str(model),
)
for i, candIncentives in enumerate(allIncentives)
)
return results

def showChart(fileName, norm=1, methodOnly=True, forResult='all', percentages=True, wholeOnly=True):
Expand All @@ -298,7 +310,7 @@ def showChart(fileName, norm=1, methodOnly=True, forResult='all', percentages=Tr
elif norm == 'max':
normFactor = max(rawData)
data = [d/normFactor for d in rawData]
name = re.match(".*(?=:)", row['name']).group(0) if methodOnly else row['name']
name = re.match(".*(?=:)", row['name'])[0] if methodOnly else row['name']
ax.plot([(i+.5)*100/buckets for i in range(buckets)], data, label=name)
ax.set_xlabel("Voter's support for candidate")
ax.set_ylabel("Candidate's incentive to appeal to voter")
Expand All @@ -308,9 +320,9 @@ def yFormatFunc(value, position):
if value == 1: return "Average"
if value == 0: return "0"
if wholeOnly:
if value % 1 != 0: return ""
return f'{int(value)}x Avg'
return "" if value % 1 != 0 else f'{int(value)}x Avg'
return f'{value:1.1f}x Avg'

ax.yaxis.set_major_formatter(mtick.FuncFormatter(yFormatFunc))
ax.grid(True)
ax.legend()
Expand All @@ -327,11 +339,11 @@ def showDFUandCS(fileName, positions=(0.25,0.5), methodOnly=True, forResult='all
buckets = int(row['numBuckets'])
rawData = [float(row[str(i)]) for i in range(buckets)]
total = sum(rawData)
name = re.match(".*(?=:)", row['name']).group(0) if methodOnly else row['name']
name = re.match(".*(?=:)", row['name'])[0] if methodOnly else row['name']
DFU = sum(entry/total - 1/buckets for entry in rawData if entry/total > 1/buckets)
CSs = [sum(entry/total for i, entry in enumerate(rawData) if i < buckets*pos) for pos in positions]
csString = "\t".join(f"{cs:1.2f}" for cs in CSs)
print(f"{name}: {DFU:1.2f}\t"+csString)
print(f"{name}: {DFU:1.2f}\t{csString}")

if __name__ == "__main__":
import doctest
Expand Down
73 changes: 36 additions & 37 deletions dataClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def winnerSet(cls, ballots, numWinners=1):
def honBallot(cls, utils, **kw):
"""Takes utilities and returns an honest ballot
"""
raise NotImplementedError("{} needs honBallot".format(cls))
raise NotImplementedError(f"{cls} needs honBallot")

@classmethod
def vaBallot(cls, utils, electabilities, **kw):
Expand Down Expand Up @@ -100,10 +100,9 @@ def realisticBullets(cls, utils, electabilities, baseBullets=0.3, slope=0.35, ot
r = random.Random(utils.id).random()
if r < baseBullets + slope*margin:
return cls.bulletBallot(utils)
else:
if otherStrat is None:
otherStrat = cls.honBallot
return otherStrat(utils, electabilities=electabilities)
if otherStrat is None:
otherStrat = cls.honBallot
return otherStrat(utils, electabilities=electabilities)

@classmethod
def diehardBallot(cls, utils, intensity, candToHelp, candToHurt, electabilities=None, polls=None):
Expand Down Expand Up @@ -152,7 +151,7 @@ def winner(results):
>>> 2 < Method().winner([1,2,1,3,3,3,2,1,2]) < 6
True
"""
winScore = max([result for result in results if isnum(result)])
winScore = max(result for result in results if isnum(result))
winners = [cand for (cand, score) in enumerate(results) if score==winScore]
#return random.choice(winners)
return winners[0] #made it deterministic to prevent nondeterministic behaviors in useful functions
Expand All @@ -176,7 +175,7 @@ def stratThresholdSearch(cls, targetWinner, foundAt, bgBallots, fgBallots, fgBas
midpoint = int(floor((maxThreshold + minThreshold)/2))
midpointBallots = bgBallots + fgBallots[:midpoint] + fgBaselineBallots[midpoint:]
midpointWinner = cls.winner(cls.results(midpointBallots))
if not any(midpointWinner == w for w, _ in winnersFound):
if all(midpointWinner != w for w, _ in winnersFound):
winnersFound.append((midpointWinner, midpoint))
if midpointWinner == targetWinner:
maxThreshold = midpoint
Expand All @@ -189,15 +188,15 @@ def resultsFor(cls, voters):
"""Create (honest/naive) ballots and get results.
Again, test on subclasses.
"""
return cls.results(list(cls.honBallot(v) for v in voters))
return cls.results([cls.honBallot(v) for v in voters])
@staticmethod
def stratTarget2(places):
((frontId,frontResult), (targId, targResult)) = places[0:2]
((frontId,frontResult), (targId, targResult)) = places[:2]
return (frontId, frontResult, targId, targResult)

@staticmethod
def stratTarget3(places):
((frontId,frontResult), (targId, targResult)) = places[0:3:2]
((frontId,frontResult), (targId, targResult)) = places[:3:2]
return (frontId, frontResult, targId, targResult)

stratTargetFor = stratTarget2
Expand Down Expand Up @@ -247,8 +246,9 @@ def rememberBallot(fun):
"""
def getAndRemember(cls, voter, tally=None):
ballot = fun(cls, voter)
setattr(voter, cls.__name__ + "_" + fun.__name__[:-6], ballot) #leave off the "...Ballot"
setattr(voter, f"{cls.__name__}_{fun.__name__[:-6]}", ballot)
return ballot

getAndRemember.__name__ = fun.__name__
getAndRemember.allTallyKeys = lambda:[]
return getAndRemember
Expand All @@ -263,9 +263,10 @@ def getAndRemember(cls, voter, tally=None):
ballots = fun(cls, voter)
for bType, ballot in ballots.items():

setattr(voter, cls.__name__ + "_" + bType, ballot)
setattr(voter, f"{cls.__name__}_{bType}", ballot)

return ballots[fun.__name__[:-6]] #leave off the "...Ballot"

getAndRemember.__name__ = fun.__name__
getAndRemember.allTallyKeys = lambda:[]
return getAndRemember
Expand Down Expand Up @@ -302,9 +303,10 @@ def paramStrat(strategy, **kw):
def strat(voter, polls=None, electabilities=None, candToHelp=None, candToHurt=None):
return strategy(voter, polls=polls, electabilities=electabilities,
candToHelp=candToHelp, candToHurt=candToHurt, **kw)

strat.__name__ = strategy.__name__
for key, value in kw.items():
strat.__name__ += "_"+str(key)[:4]+str(value)[:4]
strat.__name__ += f"_{str(key)[:4]}{str(value)[:4]}"
return strat

def wantToHelp(voter, candToHelp, candToHurt, **kw):
Expand All @@ -313,7 +315,8 @@ def wantToHelp(voter, candToHelp, candToHurt, **kw):
def selectAB(candA, candB): #candA and candB are candidate IDs
def fgSelect(voter, **kw):
return max(voter[candA] - voter[candB], 0)
fgSelect.__name__ = "select"+str(candA)+str(candB)

fgSelect.__name__ = f"select{str(candA)}{str(candB)}"
return fgSelect

def selectRand(polls, **kw):
Expand Down Expand Up @@ -353,16 +356,25 @@ def selectV(v, **kw):
"pivotalUtilDiff", "deciderUtilDiffSum", "deciderMargUtilDiffs", "numWinnersFound",
"factionSize", "factionFraction"]
for prefix in ["", "min", "t1", "o"]:
for columnName in ["fgUtil", "fgUtilDiff", "fgSize",
"fgNumHelped", "fgHelpedUtil", "fgHelpedUtilDiff",
"fgNumHarmed", "fgHarmedUtil", "fgHarmedUtilDiff",
"helpCandElected", "hurtCandElectedR1"]:
resultColumns.append(prefix + columnName)
resultColumns.extend(
prefix + columnName
for columnName in [
"fgUtil",
"fgUtilDiff",
"fgSize",
"fgNumHelped",
"fgHelpedUtil",
"fgHelpedUtilDiff",
"fgNumHarmed",
"fgHarmedUtil",
"fgHarmedUtilDiff",
"helpCandElected",
"hurtCandElectedR1",
]
)

def makeResults(**kw):
results = {c: kw.get(c, None) for c in resultColumns}
results.update(kw)
return results
return {c: kw.get(c, None) for c in resultColumns} | kw

def makePartialResults(fgVoters, winner, r1Winner, prefix, candToHelp, candToHurt):
fgHelped = []
Expand Down Expand Up @@ -527,10 +539,7 @@ def tieFor2Estimate(probs):


def adaptiveTieFor2(polls, uncertainty=.15):
if False and len(polls) < 6:
return tieFor2Probs(polls, uncertainty)
else:
return tieFor2Estimate(tuple(pollsToProbs(polls, uncertainty)))
return tieFor2Estimate(tuple(pollsToProbs(polls, uncertainty)))

def appendResults(filename, resultsList, globalComment = dict()):
"""append list of results created by makeResults to a csv file.
Expand All @@ -548,17 +557,7 @@ def appendResults(filename, resultsList, globalComment = dict()):

with open(baseName + str(i) + ".csv", "a") as myFile:
if needsHeader:
print("# " + str(globalComment),
#dict(
#media=self.media.__name__,
# version=self.repo_version,
# seed=self.seed,
## model=self.model,
# methods=self.methods,
# nvot=self.nvot,
# ncand=self.ncand,
# niter=self.niter)),
file=myFile)
print(f"# {str(globalComment)}", file=myFile)
dw = csv.DictWriter(myFile, keys, restval="NA")
dw.writeheader()
for r in resultsList:
Expand Down
Loading

0 comments on commit 9b91c1e

Please sign in to comment.