-
Notifications
You must be signed in to change notification settings - Fork 1
/
scorePDGF.py
112 lines (101 loc) · 3.71 KB
/
scorePDGF.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
#!/usr/bin/python
"""A command line script for scoring games of paranoid debate.
A description of the game and the file format for running the scoring
algorithm can be found on the web.
http://wiki.lesswrong.com/wiki/Paranoid_debating
Released to the public domain I guess?
Authors:
Jennifer Rodriguez-Mueller
Steve Rayhawk
"""
import math
def main():
"""Handle job of "being a script" from command line."""
import sys
if len(sys.argv) != 2:
print "USAGE: scorePDGF.py FILE\n"
print "Exactly one arg required... but not provided."
sys.exit(-1)
if sys.argv[1] in ["--help","-h","/?"]:
print "USAGE: scorePDGF.py FILE\n"
print 'A "pdgf" file is file recording a game of Paranoind Debating'
print "in the relevant Game Format. By convention the file matches"
print "*.pdgf.txt and examples should be script.\n"
print "For background on the game itself, see:"
print "http://wiki.lesswrong.com/wiki/Paranoid_debating"
try:
f = open(sys.argv[1])
except:
print "USAGE: scorePDGF.py FILE\n"
print "Specified FILE couldn't be opened."
sys.exit(-1)
try:
scores = scoreParanoidDebatingGameFile(f)
except:
print "Game format violated. Double check references"
print "http://wiki.lesswrong.com/wiki/Paranoid_debating"
sys.exit(-1)
#Minimal output:
for person in scores:
print "The score of",person,"was",round(scores[person],3)
def scoreParanoidDebatingGameFile(inFileObj):
"""Score a game of paranoid debating in PDGF. Callable from IDLE :)"""
scores = {}
for rawline in inFileObj:
# Incremental file parsing...
line = rawline.strip()
if not line:
continue
if line[0] == "#":
continue
try:
oneRound = line.split("\t")
nums = []
for i in [0,1,2,3]:
nums.append(float(oneRound[i]))
people = oneRound[4].split("|")
speaker = people[0]
advisors = filter(len,people[1].split(","))
tricksys = filter(len,people[2].split(","))
except:
Exception("Bad format!")
for person in advisors+tricksys+[speaker]:
if person.lower() not in scores:
scores[person.lower()] = 0.0
if nums[0] < 0.0 or 1.0 < nums[0]:
Exception("Illegal confidence interval")
confidence = nums[0]
if nums[1] > nums[2]:
Exception("Probable confusion about bounds...")
logarithmic = True
if (logarithmic):
low = math.log(nums[1])
high = math.log(nums[2])
actual = math.log(nums[3])
else:
low = nums[1]
high = nums[2]
actual = nums[3]
center = (low+high)/2.0
## <Thank you Steve>
# Compute Cauchy inverse cdf of
# q = 1/2 + confidence/2
# (high quantile of centered confidence interval)
# as tan((q-1/2)*pi)
scale = math.tan(confidence/2.0*math.pi)*(high-low)/2.0
# Compute Cauchy pdf as 1/(1+x**2)/pi
density = 1.0/(1+((actual-center)/scale)**2)/math.pi/scale
# Calculate scores round by round...
speakerScore = math.log(density) * 2.0
advisorScore = math.log(density)
tricksyScore = math.log(density) * -1.0
## </You're welcome Jennifer>
# Update scores as you go...
scores[speaker.lower()] += speakerScore
for person in advisors:
scores[person.lower()] += advisorScore
for person in tricksys:
scores[person.lower()] += tricksyScore
return scores
if __name__ == '__main__':
main()