This commit is contained in:
Christian Lynggaard Jørgensen 2019-04-06 23:11:41 +02:00
commit c461a2352e
12 changed files with 95 additions and 51 deletions

View File

@ -10,7 +10,7 @@ from typing import List
import requests_cache
from flask import Flask, jsonify, logging, request
from .strategies import miloStrats, iss, cars_in_traffic, tide_strat, upstairs_neighbour, bing
from .strategies import miloStrats, iss, cars_in_traffic, tide_strat, upstairs_neighbour, bing, battery
from .util import Context
app = Flask(__name__)
@ -30,6 +30,7 @@ strategies = {
"tide": tide_strat.is_tide,
"upstairs_neighbour": upstairs_neighbour.check_games,
"bing": bing.clock,
"battery_level": battery.battery_level,
}
@ -78,14 +79,13 @@ def probabilities():
prediction["night"] = not prediction["night"]
# Calculate contributions of predictions
consensus_weight_sum = sum(p["weight"] for p in predictions if p["night"] == night)
weight_sum = sum(p["weight"] for p in predictions)
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
prediction["contribution"] = prediction["weight"] / weight_sum
# If this prediction disagrees with the consensus it contributed negatively
if prediction["night"] != night:
prediction["contribution"] *= -1
return jsonify({
"predictions": predictions,
"weighted_probabilities_mean": mean,

View File

@ -0,0 +1,21 @@
from ..util import Context, Prediction
def battery_level(context: Context) -> Prediction:
"""
If the battery is low, it's probably bedtime soon.
"""
p = Prediction()
if context.battery > 60:
p.reasons.append("Battery level's good, so it's probably still early in the day.")
elif context.battery > 30:
p.reasons.append("Battery level's getting low, so it's probably around dinnertime.")
elif context.battery > 10:
p.reasons.append("Your phone is dying, so it's bedtime soon?")
else:
p.reasons.append("Your phone's practically dead, so it's probably around four in the morning.")
p.probability = 1 - (context.battery / 100) # night is inverse proportional to battery level
return p

View File

@ -11,7 +11,7 @@ def clock(context: Context) -> Prediction:
It's nighttime if Bing says it's daytime.
"""
p = Prediction()
p.weight = 0.5
p.weight = 0.02
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'}
@ -22,12 +22,12 @@ def clock(context: Context) -> Prediction:
time = datetime.strptime(time_str, "%H:%M")
night = time.hour < 6 or time.hour >= 22
time_description = "" if night else "daytime"
time_description = "nighttime" if night else "daytime"
time_description_oppersite = "daytime" if night else "nighttime"
p.reasons.append(f"Bing says its {time_description}.")
p.reasons.append(f"We don't really trust it.")
p.reasons.append(f"Let's guess its {time_description_oppersite}.")
p.reasons.append(f"But we don't really trust it (who does?).")
p.reasons.append(f"Let's guess it's {time_description_oppersite}.")
p.probability = 1 - p.probability

View File

@ -27,13 +27,13 @@ def cars_in_traffic(context: Context) -> Prediction:
diff = day_avr - night_avr
if curr_avg >= day_avr:
p.reasons.append(f"Because {curr_avg} cars are driving around Aarhus right now and {day_avr} is the expected number for daytime")
p.reasons.append(f"Because {curr_avg:.1f} cars are driving around Aarhus right now and {day_avr:.1f} is the expected number for daytime")
p.probability = 0.0
elif curr_avg <= night_avr:
p.reasons.append(f"Because {curr_avg} cars are driving around Aarhus right now and {night_avr} is the expected number for nighttime")
p.reasons.append(f"Because {curr_avg:.1f} cars are driving around Aarhus right now and {night_avr:.1f} is the expected number for nighttime")
p.probability = 1.0
else:
p.reasons.append(f"Because average for daytime is {day_avr} and average for nighttime is {night_avr}, but the current average is {curr_avg}")
p.reasons.append(f"Because average for daytime is {day_avr:.1f} and average for nighttime is {night_avr:.1f}, but the current average is {curr_avg:.1f}")
res = 1 - curr_avg / diff
p.probability = res

View File

@ -1,5 +1,4 @@
import itertools
import logging
from datetime import datetime
from math import pi, sqrt, sin, cos, atan2
@ -14,7 +13,7 @@ tf = TimezoneFinder(in_memory=True)
def night_on_iss(context: Context) -> Prediction:
"""
It is night if it is night on the ISS and it is currently orbiting above us.
It is night if it is night on the ISS and it is currently orbiting above us. http://www.isstracker.com/
"""
p = Prediction()

View File

@ -17,7 +17,7 @@ def is_restaurant_open(name, open, close) -> Prediction:
soup = BeautifulSoup(r.content, features='html5lib')
listing_groups = soup.find_all('div', {'class': 'listing-group'})
p.reasons.append("Hopefully we are not banned from Just-eat ..")
#p.reasons.append("Hopefully we are not banned from Just-eat ..")
nice_group = None
for x in listing_groups:
@ -32,10 +32,12 @@ def is_restaurant_open(name, open, close) -> Prediction:
all_listings = nice_group.find_all('a', {'class': 'mediaElement'})
if any(name in x['href'] for x in all_listings):
p.reasons.append(f"{name} is currently open. We conclude from this, that there is {1 / 11}% chance of it being night outside!")
p.reasons.append(f"Our favorite pizza place, {name}, is currently open.")
p.reasons.append(f"We conclude from this, that there is {1 / 11}% chance of it being night outside")
p.probability = 1 / 11
else:
p.reasons.append(f"{name} is not open. We can conclude from this, that there is {1 - (1/11)}% chance of it currently being night outside! ")
p.reasons.append(f"Our favorite pizza place, {name}, is closed.")
p.reasons.append(f"We can conclude from this, that there is {1 - (1/11)}% chance of it currently being night outside!")
p.probability = 1 - (1 / 11)
return p

View File

@ -11,15 +11,18 @@ def camImgStrat(context : Context) -> Prediction:
The contents of the camera image
"""
img = context.image
average = img.mean()
average = float(img.mean())
p = Prediction()
p.weight = 0.7
if average < 100:
p.probability = 1.0
p.reasons.append('Image was dark')
p.weight = 1.0
p.probability = 1 - round((average/255),3)
if average < 128:
p.weight = round(1 - (average/255), 3)
p.reasons.append('Camera image was dark, so the sun has probably set.')
else:
p.reasons.append('Image was light')
p.probability = 0.0
p.weight = round(average / 255, 3)
p.reasons.append('Camera image was light, so the sun is still shining.')
return p
@ -34,10 +37,10 @@ def australiaStrat(context : Context) -> Prediction:
if hour > 22 or hour < 6:
p.probability = 0.0
p.reasons.append('It\'s night-time in Australia')
p.reasons.append('It\'s night-time in Australia, so it must be day-time here.')
else:
p.probability = 1.0
p.reasons.append('It\'s day-time in Australia')
p.reasons.append('It\'s day-time in Australia, so it must be night-time here.')
return p
@ -46,6 +49,7 @@ def tv2newsStrat(context : Context) -> Prediction:
The number of articles releases in the last few hours on TV2.dk
"""
r = requests.get('http://mpx.services.tv2.dk/api/latest')
data = r.json()
publish_dates = [(x['pubDate'])//1000 for x in data][:10]
delta_times = []

Binary file not shown.

View File

@ -6,10 +6,11 @@ import json
import numpy as np
from server.nightr.strategies.strat_utils import write_json
from .strat_utils import write_json
from ..util import Context, Prediction
def find_data(time):
def write_data(time):
write_json("https://portal.opendata.dk/api/3/action/datastore_search?resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c", "parking_aarhus", time)
def load_data():
@ -18,7 +19,7 @@ def load_data():
Y = []
for filename in glob.glob("parking_aarhus*"):
p_class = '2330' in filename
p_class = '2235' in filename
with open(filename) as file:
data = json.load(file)
@ -32,13 +33,26 @@ def load_data():
def train():
X, Y = load_data()
classifier = svm.SVC(C=10, gamma=0.01, probability=True)
classifier = svm.SVC(gamma=0.01, probability=True)
classifier.fit(X, Y)
joblib.dump(classifier, "nightness_classifier.pkl")
def predict(X):
classifier = joblib.load("nightness_classifier.pkl")
prob = classifier.predict_proba(X)
prob = classifier.predict_proba(np.array(X).reshape(1, -1))
return prob[0, 1]
train()
def perform_svm_pred(context: Context) -> Prediction:
p = Prediction()
data = requests.get('https://portal.opendata.dk/api/3/action/datastore_search?resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c')
records = data.json()['result']['records']
X = [house['vehicleCount'] / house['totalSpaces'] for house in records]
X = [min(x, 1) for x in X]
p.reasons.append("We only have two data points")
p.reasons.append("Our only two data points have 11 dimensions")
p.reasons.append("We are using a SVM")
p.probability = predict(X)
return p

View File

@ -19,10 +19,9 @@ def is_tide(context: Context) -> Prediction:
month, cur_year_total_cars, last_year_total_cars = determine_month()
month = int(month)
p.reasons.append(f"Because the month is f{calendar.month_name[month]}")
p.reasons.append(f"Because the number of cars having driven on the Storbæltsbro is f{cur_year_total_cars}")
p.reasons.append(f"And because the number of cars having driven over it in the last year is f{last_year_total_cars}")
p.reasons.append(f"The month is {calendar.month_name[month]}")
p.reasons.append(f"The number of cars having driven on the Storbæltsbro is {cur_year_total_cars}, in the current year")
p.reasons.append(f"The number of cars having driven over it in the last year is {last_year_total_cars}, thus the frequency is: {last_year_total_cars / cur_year_total_cars}")
tide_data = requests.get('https://www.dmi.dk/fileadmin/user_upload/Bruger_upload/Tidevand/2019/Aarhus.t.txt')
@ -47,27 +46,27 @@ def is_tide(context: Context) -> Prediction:
average_delta = timedelta(seconds=average_inc)
if last_match[1] < 0 and last_match[1] < current_water_level: # Increasing
if last_match[1] < 0 and last_match[1] <= current_water_level: # Increasing
time = last_match
while time[1] != current_water_level:
time[0] += average_delta
time[1] += 1
elif last_match[1] < 0 and last_match[1] > current_water_level:
elif last_match[1] < 0 and last_match[1] >= current_water_level:
time = last_match
while time[1] != current_water_level:
time[0] += average_delta
time[1] -= 1
elif last_match[1] > 0 and last_match[1] > current_water_level: # Decreasing
elif last_match[1] > 0 and last_match[1] >= current_water_level: # Decreasing
time = last_match
while time[1] != current_water_level:
time[0] += average_delta
time[1] -= 1
elif last_match[1] > 0 and last_match[1] < current_water_level:
elif last_match[1] > 0 and last_match[1] <= current_water_level:
time = last_match
while time[1] != current_water_level:
@ -78,9 +77,9 @@ def is_tide(context: Context) -> Prediction:
moments.append(time[0])
night = sum([1 for x in moments if 6 >= x.hour or x.hour >= 22])
p.reasons.append(f"The water level is currently at {current_water_level}")
p.reasons.append(f"The number of times the water is at the current level at nighttime is: {night}, compared to the total amount of times in {calendar.month_name[month]}, being {len(moments)}")
p.reasons.append(f"And because the number of times the water is at the current level at nighttime is: {night}, compared to the total amount of times in {calendar.month_name[month]}, being {len(moments)}")
p.probability = night / len(moments)
p.probability = 1 - (night / len(moments))
return p

View File

@ -1,12 +1,17 @@
import requests
from bs4 import BeautifulSoup
from datetime import datetime
from datetime import datetime, timedelta
from ..util import Prediction, Context
last_update = datetime.min
def update():
global last_update
now = datetime.utcnow()
if (now - timedelta(minutes=5)) > last_update:
requests.post('https://euw.op.gg/summoner/ajax/renew.json/', data={'summonerId': 34009256})
last_update = now
def check_games(context: Context) -> Prediction:
@ -29,12 +34,12 @@ def check_games(context: Context) -> Prediction:
last_game_in_hours = (((datetime.now() - last_played_game).seconds)/60/60)
if last_game_in_hours < 2:
p.reasons.append("Alexanders upstairs neighbour is currently playing league")
p.reasons.append("Alexander's upstairs neighbour is currently playing league")
p.probability = 0.8
else:
last_game_in_hours = min(24.0, last_game_in_hours)
p.reasons.append(f"Alexanders upstairs neighbour has not played league for {last_game_in_hours} hours!")
p.reasons.append(f"Alexanders upstairs neighbour has not played league for {last_game_in_hours:.2f} hours!")
p.probability = 1 - (last_game_in_hours / 24)
return p

View File

@ -9,8 +9,8 @@ import numpy as np
@dataclass
class Context:
battery: int = 100
position: Dict[str, float] = field(default_factory=lambda: {'latitude': 53.0, 'longitude': 9.0})
battery: int = 55
position: Dict[str, float] = field(default_factory=lambda: {'latitude': 53.0, 'longitude': 9.0}) # Denmark somewhere
image: np.ndarray = None
# App settings