-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnewsim.py
More file actions
213 lines (176 loc) · 6.9 KB
/
Copy pathnewsim.py
File metadata and controls
213 lines (176 loc) · 6.9 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
import json
import math
import statistics
import numpy as np
import random
import matplotlib.pyplot as plt
# constants
CITIES = ['Albuquerque', 'El Paso', 'Flagstaff', 'Phoenix', 'Tucson']
MONTHS = ['June', 'July', 'August', 'September']
METHODS = ['a', 'b', 'c', 'd', 'e', 'f']
GUESSNUM = 1000
def main():
actuRain = getActuRain()
histRain = getHistRain()
guessDict = getGuesses(histRain)
pointDict = calcPoints(actuRain, histRain, guessDict)
exportData(pointDict)
def getActuRain():
'''
getActuRain() - reads in rain data from input.js
'''
f = open('input.json',)
data = json.load(f)
# rain totals for each month
total = {}
for city in CITIES:
actRain = {}
actRain['June'] = float(data[city]['June'])
actRain['July'] = float(data[city]['July'])
actRain['August'] = float(data[city]['August'])
actRain['September'] = float(data[city]['September'])
total[city] = actRain
f.close()
return total
def getHistRain():
'''
histRain() - read in historical rain data to be used later
'''
rainData = {}
for city in CITIES:
# arrays to hold rain logs
juneRain = []
julyRain = []
augRain = []
sepRain = []
f = open('HistoricalCleaned.json',)
data = json.load(f)
for year, info in data.items():
# populate arrays
juneRain.append(float(info[city]["June"]))
julyRain.append(float(info[city]["July"]))
augRain.append(float(info[city]["August"]))
sepRain.append(float(info[city]["September"]))
f.close()
# get standard deviation, decile ranges, and mean rain (all are need
# to get point values)
rainData[city] = {}
rainData[city]["JuneRain"] = statistics.stdev(juneRain)
rainData[city]["JuneDeciles"] = np.percentile(
np.array(juneRain), np.arange(0, 100, 10))
rainData[city]["JuneMean"] = statistics.mean(juneRain)
rainData[city]["JulyRain"] = statistics.stdev(julyRain)
rainData[city]["JulyDeciles"] = np.percentile(
np.array(julyRain), np.arange(0, 100, 10))
rainData[city]["JulyMean"] = statistics.mean(julyRain)
rainData[city]["AugustRain"] = statistics.stdev(augRain)
rainData[city]["AugustDeciles"] = np.percentile(
np.array(augRain), np.arange(0, 100, 10))
rainData[city]["AugustMean"] = statistics.mean(augRain)
rainData[city]["SeptemberRain"] = statistics.stdev(sepRain)
rainData[city]["SeptemberDeciles"] = np.percentile(
np.array(sepRain), np.arange(0, 100, 10))
rainData[city]["SeptemberMean"] = statistics.mean(sepRain)
return rainData
def getGuesses(histRain):
'''
getGuesses(histRain) - simulate a season's worth of guesses for each guess,
guesses are made based of random deciles
'''
guesses = {}
for i in range(GUESSNUM): # for each guess
guesses[i] = {}
for month in MONTHS: # guess for each month
guesses[i][month] = {}
for city in CITIES: # guess for each city each month
guesses[i][month][city] = histRain[city][month +
'Deciles'][int(random.randint(0, 9))]
return guesses
def calcPoints(actuRain, histRain, guessDict):
'''
calcPoints(actuRain, histRain, guessDict) - calculates appropriate points
based of of each guess
'''
# inner function to yield points
def getPoints(stdDev, mean, guess, actual, scoreFunc):
'''
getPoints(stdDev, mean, guess, actual, scoreFunc) - calculates the max
points based off of user's choice, then returns the points rewarded
'''
# using dharma's original (a, b, c) and skewed (d, e, f) functions
if (scoreFunc == 'a'):
maxPoints = -4 * \
math.exp((-(actual - mean)**2) / (2*(stdDev**2))) + 8
elif (scoreFunc == 'b'):
maxPoints = -2 * \
math.exp((-(actual - mean)**2) / (2*(stdDev**2))) + 6
elif (scoreFunc == 'c'):
maxPoints = -1 * \
math.exp((-(actual - mean)**2) / (2*(stdDev**2))) + 5
# due to the nature of the log function, 0 is passed in it will error
# out, so 0 rain point value is set manually
elif (scoreFunc == 'd'):
maxPoints = 8 if actual == 0 else -4 * \
math.exp(-((math.log(actual / mean))**2) /
(2 * (stdDev / 2)**2)) + 8
elif (scoreFunc == 'e'):
maxPoints = 6 if actual == 0 else -2 * \
math.exp(-((math.log(actual / mean))**2) /
(2 * (stdDev / 2)**2)) + 6
elif (scoreFunc == 'f'):
maxPoints = 5 if actual == 0 else -1 * \
math.exp(-((math.log(actual / mean))**2) /
(2 * (stdDev / 2)**2)) + 5
# calc actual points recieved
if (guess < actual - stdDev or guess > actual + stdDev):
return 0
elif (guess < actual - stdDev*0.75 or guess > actual + stdDev*0.75):
return round(maxPoints*0.25)
elif (guess < actual - stdDev*0.5 or guess > actual + stdDev*0.5):
return round(maxPoints*0.5)
elif (guess < actual - stdDev*0.25 or guess > actual + stdDev*0.25):
return round(maxPoints*0.75)
else:
return round(maxPoints)
pointDict = {}
for method in METHODS:
pointArr = []
for num, info in guessDict.items():
totalPoints = 0
for month, guesses in info.items():
for city, guess in guesses.items():
temp = getPoints(histRain[city][month + 'Rain'], histRain[city]
[month + 'Mean'], guess, actuRain[city][month], method)
totalPoints = totalPoints + temp
pointArr.append(totalPoints)
pointArr.sort()
pointDict[method] = pointArr
return pointDict
def exportData(pointDict):
'''
exportData(pointDict) - converts the data to a nice dictionary to be used
by d3, writes it to output.js
'''
test = {}
for method, points in pointDict.items():
temp = {}
for point in points:
if str(point) not in temp:
# point dict (object for js)
temp[str(point)] = {
'x': point,
'y': 1
}
else:
temp[str(point)]['y'] = temp[str(point)]['y'] + 1
test[method] = temp
# get only the array of point objects
exportDict = {}
for method, v in test.items():
exportDict[method] = []
for items in v.values():
exportDict[method].append(items)
with open('output.js', 'w') as outfile:
outfile.write('let data = ')
json.dump(exportDict, outfile)
main()