2019-04-05 23:16:02 +00:00
|
|
|
import inspect
|
|
|
|
import statistics
|
2019-04-06 10:14:55 +00:00
|
|
|
from dataclasses import asdict
|
|
|
|
from datetime import timedelta
|
|
|
|
from typing import List
|
2019-04-05 23:16:02 +00:00
|
|
|
|
2019-04-06 10:14:55 +00:00
|
|
|
import requests_cache
|
2019-04-05 23:16:02 +00:00
|
|
|
from flask import Flask, jsonify
|
|
|
|
|
|
|
|
from server.nightr.strategies import dmi, steam
|
2019-04-06 10:14:55 +00:00
|
|
|
from server.nightr.util import Context
|
2019-04-05 23:16:02 +00:00
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
2019-04-06 10:14:55 +00:00
|
|
|
requests_cache.install_cache("requests_cache.sqlite", expire_after=timedelta(minutes=10))
|
|
|
|
|
2019-04-05 23:16:02 +00:00
|
|
|
|
|
|
|
strategies = {
|
|
|
|
# name: (weight, probability function)
|
2019-04-06 10:14:55 +00:00
|
|
|
"dmi": (0.5, dmi.probability),
|
|
|
|
"steam": (1.0, steam.probability),
|
2019-04-05 23:16:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/", methods=["GET", "POST"])
|
|
|
|
def probabilities():
|
2019-04-06 10:14:55 +00:00
|
|
|
phone_data = {} # TODO: get from POST request
|
|
|
|
context = Context(**phone_data)
|
2019-04-05 23:16:02 +00:00
|
|
|
|
2019-04-06 10:14:55 +00:00
|
|
|
predictions: List[dict] = []
|
2019-04-05 23:16:02 +00:00
|
|
|
for name, (weight, strategy) in strategies.items():
|
2019-04-05 23:31:45 +00:00
|
|
|
try:
|
2019-04-06 10:14:55 +00:00
|
|
|
prediction = strategy(context)
|
2019-04-05 23:31:45 +00:00
|
|
|
except Exception as e:
|
|
|
|
print(f"Strategy {name} failed: {e}")
|
|
|
|
continue
|
2019-04-06 10:14:55 +00:00
|
|
|
predictions.append({
|
2019-04-05 23:16:02 +00:00
|
|
|
"name": name,
|
2019-04-06 10:14:55 +00:00
|
|
|
"description": inspect.getdoc(strategy),
|
|
|
|
"weight": weight,
|
|
|
|
"weighted_probability": prediction.probability * weight,
|
|
|
|
"night": prediction.probability > 0.5,
|
|
|
|
**asdict(prediction),
|
2019-04-05 23:16:02 +00:00
|
|
|
})
|
|
|
|
|
2019-04-06 10:14:55 +00:00
|
|
|
mean = statistics.mean(p["weighted_probability"] for p in predictions)
|
|
|
|
median = statistics.median(p["weighted_probability"] for p in predictions)
|
|
|
|
night = mean > 0.5
|
|
|
|
|
|
|
|
# Calculate contributions of predictions
|
|
|
|
consensus_weight_sum = sum(p["weight"] for p in predictions if p["night"] == night)
|
|
|
|
for prediction in predictions:
|
|
|
|
# If this prediction agrees with the consensus it contributed
|
|
|
|
if prediction["night"] == night:
|
|
|
|
prediction["contribution"] = prediction["weight"] / consensus_weight_sum
|
|
|
|
else:
|
|
|
|
prediction["contribution"] = 0.0
|
|
|
|
|
2019-04-05 23:16:02 +00:00
|
|
|
return jsonify({
|
2019-04-06 10:14:55 +00:00
|
|
|
"predictions": predictions,
|
|
|
|
"weighted_probabilities_mean": mean,
|
|
|
|
"weighted_probabilities_median": median,
|
|
|
|
"night": night,
|
2019-04-05 23:16:02 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
app.run(host='0.0.0.0')
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|