From 53ec6fb4ac0d21920bfe34a7e29d2badb7cee5c0 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 6 Apr 2019 14:05:43 +0200 Subject: [PATCH 01/20] Added geolocation plugin --- client/Nightr/package-lock.json | 13 +++++++++++++ client/Nightr/package.json | 1 + 2 files changed, 14 insertions(+) diff --git a/client/Nightr/package-lock.json b/client/Nightr/package-lock.json index 447e2bf..04b5e41 100644 --- a/client/Nightr/package-lock.json +++ b/client/Nightr/package-lock.json @@ -3948,6 +3948,14 @@ } } }, + "nativescript-geolocation": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nativescript-geolocation/-/nativescript-geolocation-5.0.0.tgz", + "integrity": "sha512-olFTkG68Y0pkqtxyaPoHalZSHgXcg3iL9q+r9gcEY5c7QY8sCtfdO/T5FhHeQlDu0YrrZhx2Ke20dUczuePmUA==", + "requires": { + "nativescript-permissions": "~1.2.3" + } + }, "nativescript-hook": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/nativescript-hook/-/nativescript-hook-0.2.5.tgz", @@ -3978,6 +3986,11 @@ "resolved": "https://registry.npmjs.org/nativescript-intl/-/nativescript-intl-3.0.0.tgz", "integrity": "sha1-gu6b59N3Fys8QpVzRyMDdijhhqc=" }, + "nativescript-permissions": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/nativescript-permissions/-/nativescript-permissions-1.2.3.tgz", + "integrity": "sha1-4+ZVRfmP5IjdVXj3/5DrrjCI5wA=" + }, "nativescript-theme-core": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nativescript-theme-core/-/nativescript-theme-core-1.0.4.tgz", diff --git a/client/Nightr/package.json b/client/Nightr/package.json index 0bd444a..ddcc97a 100644 --- a/client/Nightr/package.json +++ b/client/Nightr/package.json @@ -22,6 +22,7 @@ "@angular/platform-browser-dynamic": "~7.2.0", "@angular/router": "~7.2.0", "nativescript-angular": "~7.2.0", + "nativescript-geolocation": "^5.0.0", "nativescript-theme-core": "~1.0.4", "reflect-metadata": "~0.1.12", "rxjs": "~6.3.0", From 366b2c3845af3654e939797198fdb2bee823e4d9 Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 14:10:26 +0200 Subject: [PATCH 02/20] More strats --- server/nightr/strategies/cars_in_traffic.py | 34 +++++++++ server/nightr/strategies/scrape.py | 83 ++------------------- server/nightr/strategies/strat_utils.py | 14 ++++ server/nightr/strategies/tide_strat.py | 69 +++++++++++++++++ 4 files changed, 125 insertions(+), 75 deletions(-) create mode 100644 server/nightr/strategies/cars_in_traffic.py create mode 100644 server/nightr/strategies/strat_utils.py create mode 100644 server/nightr/strategies/tide_strat.py diff --git a/server/nightr/strategies/cars_in_traffic.py b/server/nightr/strategies/cars_in_traffic.py new file mode 100644 index 0000000..00a740e --- /dev/null +++ b/server/nightr/strategies/cars_in_traffic.py @@ -0,0 +1,34 @@ +import requests + +from server.nightr.util import Prediction, Context + + +def scrape_traffic(context: Context) -> Prediction: + r = requests.get('https://portal.opendata.dk/api/3/action/datastore_search?resource_id=b3eeb0ff-c8a8-4824-99d6-e0a3747c8b0d') + night_avr = 3.38 + day_avr = 6.98 + + p = Prediction() + + data = r.json() + sum = 0 + len = 0 + for lel in data['result']['records']: + sum += lel['vehicleCount'] + len += 1 + curr_avg = len / sum + + 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.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.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}") + res = 1 - curr_avg / diff + p.probability = res + + return p diff --git a/server/nightr/strategies/scrape.py b/server/nightr/strategies/scrape.py index 9b800f0..5b9898e 100644 --- a/server/nightr/strategies/scrape.py +++ b/server/nightr/strategies/scrape.py @@ -4,60 +4,10 @@ import pandas as pd import urllib.request from datetime import datetime, timedelta import json - -def determine_month(): - ds = pd.read_excel(urllib.request.urlopen('https://sundogbaelt.dk/wp-content/uploads/2019/04/trafiktal-maaned.xls')) - - cur_year = 2019 - amount_of_cur_year = sum([x == cur_year for x in ds['År']]) - - cur_year_total = sum(ds['Total'][1:amount_of_cur_year+1]) - last_year_total = sum(ds['Total'][amount_of_cur_year+1:amount_of_cur_year+13]) - - return (12/(last_year_total//cur_year_total))+1 - -def is_tide(): - month = determine_month() - tide_data = requests.get('https://www.dmi.dk/fileadmin/user_upload/Bruger_upload/Tidevand/2019/Aarhus.t.txt') - lines = tide_data.text[570:].split('\n') - tuples = [x.split('\t') for x in lines] - lel = [[datetime.strptime(x[0], '%Y%m%d%H%M'), x[1]] for x in tuples[:-1]] - - matches = [[x[0], int(x[1])] for x in lel if x[0].month == month] - - all_the_data = requests.get('https://www.dmi.dk/NinJo2DmiDk/ninjo2dmidk?cmd=odj&stations=22331&datatype=obs') - current_water_level = json.loads(all_the_data.content)[0]['values'][-1]['value'] - - # Generate average of when the water is high - last_match = matches[0] - moments = [] - for idx, water_level in enumerate(matches[1:]): - #print(last_match[1], water_level[1]) - diff = abs(last_match[1]) + abs(water_level[1]) - time_diff = (water_level[0] - last_match[0]).seconds - - average_inc = time_diff/diff - average_delta = timedelta(seconds=average_inc) - - if last_match[1] < 0: # Increasing - time = last_match - while time[1] != current_water_level: - time[0] += average_delta - time[1] += 1 +from server.nightr.strategies.strat_utils import determine_month - elif last_match[1] > 0: # Decreasing - time = last_match - while time[1] != current_water_level: - time[0] += average_delta - time[1] -= 1 - last_match = water_level - moments.append(time[0]) - - night = sum([1 for x in moments if 6 >= x.hour or x.hour >= 22]) - - return night / len(moments) def tmp(): @@ -66,32 +16,13 @@ def tmp(): json.dump(r.json(), f) +def read_tmp(): + with open('traffic_data_13_23.json') as f: + data = json.load(f) + number = sum([cars['vehicleCount'] for cars in data['result']['records']]) + print(number / len(data['result']['records'])) -def scrape_traffic(): - r = requests.get('https://portal.opendata.dk/api/3/action/datastore_search?resource_id=b3eeb0ff-c8a8-4824-99d6-e0a3747c8b0d') - night_avr = 3.38 - day_avr = None - - data = r.json() - sum = 0 - len = 0 - for lel in data['result']['records']: - sum += lel['vehicleCount'] - len += 1 - curr_avg = len / sum - - diff= day_avr - night_avr - - if curr_avg >= day_avr: - return 0.0 - elif curr_avg <= night_avr: - return 1.0 - res = 1 - curr_avg / diff - - assert(res < 1 and res > 0) - - return res def scrape_weather(): @@ -112,3 +43,5 @@ def scrape_dmi_aarhus(): return 0.0 #adak_latest_time, adak_latest_temp_aarhus = max(adak_timeserie.items(), key= lambda x : x[0]) + +read_tmp() \ No newline at end of file diff --git a/server/nightr/strategies/strat_utils.py b/server/nightr/strategies/strat_utils.py new file mode 100644 index 0000000..97fc3ea --- /dev/null +++ b/server/nightr/strategies/strat_utils.py @@ -0,0 +1,14 @@ +import pandas as pd +import urllib.request + + +def determine_month(): + ds = pd.read_excel(urllib.request.urlopen('https://sundogbaelt.dk/wp-content/uploads/2019/04/trafiktal-maaned.xls')) + + cur_year = 2019 + amount_of_cur_year = sum([x == cur_year for x in ds['År']]) + + cur_year_total = sum(ds['Total'][1:amount_of_cur_year+1]) + last_year_total = sum(ds['Total'][amount_of_cur_year+1:amount_of_cur_year+13]) + + return ((12/(last_year_total//cur_year_total))+1), cur_year_total, last_year_total diff --git a/server/nightr/strategies/tide_strat.py b/server/nightr/strategies/tide_strat.py new file mode 100644 index 0000000..d57c77e --- /dev/null +++ b/server/nightr/strategies/tide_strat.py @@ -0,0 +1,69 @@ +import datetime +import json +import calendar +import requests + +from server.nightr.strategies.strat_utils import determine_month +from server.nightr.util import Context, Prediction + + +def is_tide(context: Context) -> Prediction: + """ + Determine whether or not it is night in Aarhus based no the current water level and which month we are in, based + on number of cars driving across The Storbæltsbro. + """ + + p = Prediction() + + month, cur_year_total_cars, last_year_total_cars = determine_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}") + + + + tide_data = requests.get('https://www.dmi.dk/fileadmin/user_upload/Bruger_upload/Tidevand/2019/Aarhus.t.txt') + lines = tide_data.text[570:].split('\n') + tuples = [x.split('\t') for x in lines] + lel = [[datetime.strptime(x[0], '%Y%m%d%H%M'), x[1]] for x in tuples[:-1]] + + matches = [[x[0], int(x[1])] for x in lel if x[0].month == month] + + all_the_data = requests.get('https://www.dmi.dk/NinJo2DmiDk/ninjo2dmidk?cmd=odj&stations=22331&datatype=obs') + current_water_level = json.loads(all_the_data.content)[0]['values'][-1]['value'] + + # Generate average of when the water is high + last_match = matches[0] + moments = [] + for idx, water_level in enumerate(matches[1:]): + #print(last_match[1], water_level[1]) + diff = abs(last_match[1]) + abs(water_level[1]) + time_diff = (water_level[0] - last_match[0]).seconds + + average_inc = time_diff/diff + average_delta = datetime.timedelta(seconds=average_inc) + + if last_match[1] < 0: # Increasing + time = last_match + while time[1] != current_water_level: + time[0] += average_delta + time[1] += 1 + + + elif last_match[1] > 0: # Decreasing + time = last_match + while time[1] != current_water_level: + time[0] += average_delta + time[1] -= 1 + + last_match = water_level + moments.append(time[0]) + + night = sum([1 for x in moments if 6 >= x.hour or x.hour >= 22]) + + 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) + + return p From 21fa94badec415698dc485e411a4cb93fb6f2af6 Mon Sep 17 00:00:00 2001 From: Milo Date: Sat, 6 Apr 2019 14:35:48 +0200 Subject: [PATCH 03/20] stuff --- server/activate.sh | 8 +++----- server/nightr/app.py | 6 ++++-- server/nightr/strategies/miloStrats.py | 6 ++++++ server/requirements.txt | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/server/activate.sh b/server/activate.sh index d9583b3..81ffbe1 100755 --- a/server/activate.sh +++ b/server/activate.sh @@ -4,15 +4,13 @@ FIRST_RUN=$? # Create and enter virtual environment if (( $FIRST_RUN )); then echo Creating virtual environment - python3 -m venv venv + python3.7 -m venv venv fi source venv/bin/activate # Install required python packages -if (( $FIRST_RUN )); then - echo Installing required Python packages - pip install -Ur requirements.txt -fi +echo Installing required Python packages +pip install -Ur requirements.txt function run() { python -m nightr diff --git a/server/nightr/app.py b/server/nightr/app.py index 1b4d4b5..18f58d5 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -7,8 +7,8 @@ from typing import List import requests_cache from flask import Flask, jsonify -from server.nightr.strategies import dmi, steam -from server.nightr.util import Context +from strategies import dmi, steam, miloStrats +import Context app = Flask(__name__) @@ -19,6 +19,8 @@ strategies = { # name: (weight, probability function) "dmi": (0.5, dmi.probability), "steam": (1.0, steam.probability), + "australia" : (0.5, miloStrats.australiaStrat), + "camera" : (0.5, miloStrats.camImgStrat), } diff --git a/server/nightr/strategies/miloStrats.py b/server/nightr/strategies/miloStrats.py index b53aa9a..6aee18d 100644 --- a/server/nightr/strategies/miloStrats.py +++ b/server/nightr/strategies/miloStrats.py @@ -5,6 +5,9 @@ from server.nightr.util import Context, Prediction def camImgStrat(context : Context) -> Prediction: + """ + The contents of the camera image + """ img = cv2.imread('night.jpg',0) average = img.mean(axis=0).mean(axis=0) print(average) @@ -18,6 +21,9 @@ def camImgStrat(context : Context) -> Prediction: return p def australiaStrat(context : Context) -> Prediction: + """ + Time in Australia + """ australia = timezone('Australia/Melbourne') t = datetime.now().astimezone(australia) hour = t.hour diff --git a/server/requirements.txt b/server/requirements.txt index 031c1c9..ac757ed 100644 --- a/server/requirements.txt +++ b/server/requirements.txt @@ -1,3 +1,4 @@ Flask==1.0.2 requests==2.21.0 requests-cache==0.4.13 +pytz \ No newline at end of file From 9bce7205d8b20273e555a15109fa44e7901bbd59 Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 14:40:49 +0200 Subject: [PATCH 04/20] Merge and stuff. --- server/activate.sh | 1 + server/nightr/app.py | 14 ++++++++++---- server/nightr/steamplayerhistory.py | 7 +++++-- server/nightr/strategies/miloStrats.py | 4 +++- server/nightr/util.py | 10 +++++++--- server/requirements.txt | 5 ++++- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/server/activate.sh b/server/activate.sh index 81ffbe1..cda886f 100755 --- a/server/activate.sh +++ b/server/activate.sh @@ -12,6 +12,7 @@ source venv/bin/activate echo Installing required Python packages pip install -Ur requirements.txt + function run() { python -m nightr } diff --git a/server/nightr/app.py b/server/nightr/app.py index 18f58d5..f06fd6a 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -7,8 +7,8 @@ from typing import List import requests_cache from flask import Flask, jsonify -from strategies import dmi, steam, miloStrats -import Context +from server.nightr.strategies import dmi, steam, miloStrats +from server.nightr.util import Context app = Flask(__name__) @@ -19,8 +19,8 @@ strategies = { # name: (weight, probability function) "dmi": (0.5, dmi.probability), "steam": (1.0, steam.probability), - "australia" : (0.5, miloStrats.australiaStrat), - "camera" : (0.5, miloStrats.camImgStrat), + "australia": (1.0, miloStrats.australiaStrat), + "camera": (1.0, miloStrats.camImgStrat), } @@ -49,6 +49,12 @@ def probabilities(): median = statistics.median(p["weighted_probability"] for p in predictions) night = mean > 0.5 + # Invert if we're in Australia + if context.in_australia: + night = not night + for prediction in predictions: + prediction["night"] = not prediction["night"] + # Calculate contributions of predictions consensus_weight_sum = sum(p["weight"] for p in predictions if p["night"] == night) for prediction in predictions: diff --git a/server/nightr/steamplayerhistory.py b/server/nightr/steamplayerhistory.py index 1fad799..6f49a70 100644 --- a/server/nightr/steamplayerhistory.py +++ b/server/nightr/steamplayerhistory.py @@ -1,6 +1,8 @@ -import requests -from datetime import datetime import time +from datetime import datetime + +import requests + def main(): filename = "dotaplayers " + str(datetime.now()) + ".csv" @@ -16,5 +18,6 @@ def main(): f.close() time.sleep(100) + if __name__ == '__main__': main() \ No newline at end of file diff --git a/server/nightr/strategies/miloStrats.py b/server/nightr/strategies/miloStrats.py index 6aee18d..c5b0633 100644 --- a/server/nightr/strategies/miloStrats.py +++ b/server/nightr/strategies/miloStrats.py @@ -1,6 +1,8 @@ +from datetime import datetime + import cv2 -from datetime import datetime, timedelta from pytz import timezone + from server.nightr.util import Context, Prediction diff --git a/server/nightr/util.py b/server/nightr/util.py index ad4585d..d2f37d8 100644 --- a/server/nightr/util.py +++ b/server/nightr/util.py @@ -1,11 +1,15 @@ from dataclasses import dataclass, field -from typing import List, Tuple +from typing import List, Dict @dataclass class Context: - battery: float = 1.0 - coordinates: Tuple[float, float] = (0.0, 0.0) + battery: float + position: Dict[str, float] # {'latitude': '23.2583', 'longitude': '154.0417'} + + # App settings + in_australia: bool = False + flat_earth: bool = False @dataclass diff --git a/server/requirements.txt b/server/requirements.txt index ac757ed..776c8a0 100644 --- a/server/requirements.txt +++ b/server/requirements.txt @@ -1,4 +1,7 @@ Flask==1.0.2 requests==2.21.0 requests-cache==0.4.13 -pytz \ No newline at end of file +pytz +beautifulsoup4 +pandas +opencv-python From 31f879118851d03307b351828dbf8f8d205203c9 Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 14:59:13 +0200 Subject: [PATCH 05/20] Svm strat and some parking data --- .../strategies/parking_aarhus_1430.json | 1 + server/nightr/strategies/strat_utils.py | 10 ++++- server/nightr/strategies/svm_strat.py | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 server/nightr/strategies/parking_aarhus_1430.json create mode 100644 server/nightr/strategies/svm_strat.py diff --git a/server/nightr/strategies/parking_aarhus_1430.json b/server/nightr/strategies/parking_aarhus_1430.json new file mode 100644 index 0000000..aab6620 --- /dev/null +++ b/server/nightr/strategies/parking_aarhus_1430.json @@ -0,0 +1 @@ +{"help": "https://portal.opendata.dk/api/3/action/help_show?name=datastore_search", "success": true, "result": {"include_total": true, "resource_id": "2a82a145-0195-4081-a13c-b0e587e9b89c", "fields": [{"type": "int", "id": "_id"}, {"type": "text", "id": "date"}, {"type": "text", "id": "garageCode"}, {"type": "int4", "id": "totalSpaces"}, {"type": "int4", "id": "vehicleCount"}], "records_format": "objects", "records": [{"_id": 1, "date": "2019/04/06 14:30:01", "garageCode": "NORREPORT", "totalSpaces": 80, "vehicleCount": 61}, {"_id": 2, "date": "2019/04/06 14:30:01", "garageCode": "SCANDCENTER", "totalSpaces": 1240, "vehicleCount": 1033}, {"_id": 6, "date": "2019/04/06 14:30:01", "garageCode": "SALLING", "totalSpaces": 700, "vehicleCount": 575}, {"_id": 7, "date": "2019/04/06 14:30:01", "garageCode": "DOKK1", "totalSpaces": 1000, "vehicleCount": 0}, {"_id": 8, "date": "2019/04/06 14:30:01", "garageCode": "Navitas", "totalSpaces": 449, "vehicleCount": 208}, {"_id": 9, "date": "2019/04/06 14:30:01", "garageCode": "NewBusgadehuset", "totalSpaces": 105, "vehicleCount": 101}, {"_id": 3, "date": "2019/04/06 14:30:01", "garageCode": "BRUUNS", "totalSpaces": 953, "vehicleCount": 598}, {"_id": 4, "date": "2019/04/06 14:30:01", "garageCode": "MAGASIN", "totalSpaces": 378, "vehicleCount": 361}, {"_id": 5, "date": "2019/04/06 14:30:01", "garageCode": "KALKVAERKSVEJ", "totalSpaces": 210, "vehicleCount": 278}, {"_id": 10, "date": "2019/04/06 14:30:01", "garageCode": "Urban Level 1", "totalSpaces": 319, "vehicleCount": 99}, {"_id": 11, "date": "2019/04/06 14:30:01", "garageCode": "Urban Level 2+3", "totalSpaces": 654, "vehicleCount": 170}], "_links": {"start": "/api/3/action/datastore_search?resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c", "next": "/api/3/action/datastore_search?offset=100&resource_id=2a82a145-0195-4081-a13c-b0e587e9b89c"}, "total": 11}} \ No newline at end of file diff --git a/server/nightr/strategies/strat_utils.py b/server/nightr/strategies/strat_utils.py index 97fc3ea..2e77640 100644 --- a/server/nightr/strategies/strat_utils.py +++ b/server/nightr/strategies/strat_utils.py @@ -1,6 +1,7 @@ import pandas as pd import urllib.request - +import json +import requests def determine_month(): ds = pd.read_excel(urllib.request.urlopen('https://sundogbaelt.dk/wp-content/uploads/2019/04/trafiktal-maaned.xls')) @@ -12,3 +13,10 @@ def determine_month(): last_year_total = sum(ds['Total'][amount_of_cur_year+1:amount_of_cur_year+13]) return ((12/(last_year_total//cur_year_total))+1), cur_year_total, last_year_total + + + +def write_json(url, data_name, time): + r = requests.get(url) + with open(f"{data_name}_{time}.json", 'w') as f: + json.dump(r.json(), f) diff --git a/server/nightr/strategies/svm_strat.py b/server/nightr/strategies/svm_strat.py new file mode 100644 index 0000000..78a760c --- /dev/null +++ b/server/nightr/strategies/svm_strat.py @@ -0,0 +1,44 @@ +from sklearn import svm +from sklearn.externals import joblib +import requests +import glob +import json +import numpy as np + + +from server.nightr.strategies.strat_utils import write_json + + +def find_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(): + + X = [] + Y = [] + + for filename in glob.glob("parking_aarhus*"): + p_class = '2330' in filename + + with open(filename) as file: + data = json.load(file) + + records = data['result']['records'] + frequencies = [house['vehicleCount'] / house['totalSpaces'] for house in records] + X.append(frequencies) + Y.append(int(p_class)) + + return np.array(X), np.array(Y) + +def train(): + X, Y = load_data() + classifier = svm.SVC(C=10, 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) + return prob[0, 1] + +train() From cabf12b29e3384edb44468f0caa1186768c7cc00 Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 15:37:35 +0200 Subject: [PATCH 06/20] Relative imports. --- server/nightr/app.py | 4 ++-- server/nightr/strategies/cars_in_traffic.py | 2 +- server/nightr/strategies/dmi.py | 2 +- server/nightr/strategies/miloStrats.py | 3 ++- server/nightr/strategies/scrape.py | 10 ++-------- server/nightr/strategies/steam.py | 2 +- server/nightr/strategies/tide_strat.py | 7 ++++--- server/nightr/util.py | 4 ++-- 8 files changed, 15 insertions(+), 19 deletions(-) diff --git a/server/nightr/app.py b/server/nightr/app.py index f06fd6a..a141134 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -7,8 +7,8 @@ from typing import List import requests_cache from flask import Flask, jsonify -from server.nightr.strategies import dmi, steam, miloStrats -from server.nightr.util import Context +from .strategies import dmi, steam, miloStrats +from .util import Context app = Flask(__name__) diff --git a/server/nightr/strategies/cars_in_traffic.py b/server/nightr/strategies/cars_in_traffic.py index 00a740e..65cf324 100644 --- a/server/nightr/strategies/cars_in_traffic.py +++ b/server/nightr/strategies/cars_in_traffic.py @@ -1,6 +1,6 @@ import requests -from server.nightr.util import Prediction, Context +from ..util import Prediction, Context def scrape_traffic(context: Context) -> Prediction: diff --git a/server/nightr/strategies/dmi.py b/server/nightr/strategies/dmi.py index c2a983b..7b2f431 100644 --- a/server/nightr/strategies/dmi.py +++ b/server/nightr/strategies/dmi.py @@ -1,4 +1,4 @@ -from server.nightr.util import Context, Prediction +from ..util import Context, Prediction def probability(context: Context) -> Prediction: diff --git a/server/nightr/strategies/miloStrats.py b/server/nightr/strategies/miloStrats.py index c5b0633..a571d08 100644 --- a/server/nightr/strategies/miloStrats.py +++ b/server/nightr/strategies/miloStrats.py @@ -3,7 +3,7 @@ from datetime import datetime import cv2 from pytz import timezone -from server.nightr.util import Context, Prediction +from ..util import Context, Prediction def camImgStrat(context : Context) -> Prediction: @@ -22,6 +22,7 @@ def camImgStrat(context : Context) -> Prediction: p.probability = 0.0 return p + def australiaStrat(context : Context) -> Prediction: """ Time in Australia diff --git a/server/nightr/strategies/scrape.py b/server/nightr/strategies/scrape.py index 5b9898e..ccb441b 100644 --- a/server/nightr/strategies/scrape.py +++ b/server/nightr/strategies/scrape.py @@ -1,13 +1,7 @@ +import json + import requests from bs4 import BeautifulSoup -import pandas as pd -import urllib.request -from datetime import datetime, timedelta -import json -from server.nightr.strategies.strat_utils import determine_month - - - def tmp(): diff --git a/server/nightr/strategies/steam.py b/server/nightr/strategies/steam.py index afd5753..814ae4f 100644 --- a/server/nightr/strategies/steam.py +++ b/server/nightr/strategies/steam.py @@ -1,4 +1,4 @@ -from server.nightr.util import Context, Prediction +from ..util import Context, Prediction def probability(context: Context) -> Prediction: diff --git a/server/nightr/strategies/tide_strat.py b/server/nightr/strategies/tide_strat.py index d57c77e..9b16399 100644 --- a/server/nightr/strategies/tide_strat.py +++ b/server/nightr/strategies/tide_strat.py @@ -1,10 +1,11 @@ +import calendar import datetime import json -import calendar + import requests -from server.nightr.strategies.strat_utils import determine_month -from server.nightr.util import Context, Prediction +from .strat_utils import determine_month +from ..util import Context, Prediction def is_tide(context: Context) -> Prediction: diff --git a/server/nightr/util.py b/server/nightr/util.py index d2f37d8..db52a0a 100644 --- a/server/nightr/util.py +++ b/server/nightr/util.py @@ -4,8 +4,8 @@ from typing import List, Dict @dataclass class Context: - battery: float - position: Dict[str, float] # {'latitude': '23.2583', 'longitude': '154.0417'} + battery: float = 1.0 + position: Dict[str, float] = field(default_factory=lambda: {'latitude': 53.0, 'longitude': 9.0}) # App settings in_australia: bool = False From 060a8eef36483d6856844e9e5bc3b98ee7d118cc Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 16:38:23 +0200 Subject: [PATCH 07/20] upstairs neighbour start --- .../nightr/strategies/upstairs_neighbour.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 server/nightr/strategies/upstairs_neighbour.py diff --git a/server/nightr/strategies/upstairs_neighbour.py b/server/nightr/strategies/upstairs_neighbour.py new file mode 100644 index 0000000..51ba11c --- /dev/null +++ b/server/nightr/strategies/upstairs_neighbour.py @@ -0,0 +1,35 @@ +import requests +from bs4 import BeautifulSoup +from datetime import datetime + +from ..util import Prediction, Context + + +def update(): + requests.post('https://euw.op.gg/summoner/ajax/renew.json/', data = {'summonerId': 34009256}) + + +def check_games(context: Context) -> Prediction: + update() + r = requests.get('https://euw.op.gg/summoner/userName=Im+Eating+Pros') + + #if not "is not in an active game" in str(r.content): + # return 1.0 + + p = Prediction() + + soup = BeautifulSoup(r.content, features='html5lib') + + timestamp = int(soup.find('div', {'class': 'GameItemList'}).find('div', {'class': 'GameItem'})['data-game-time']) + last_played_game = datetime.fromtimestamp(timestamp) + + 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.probability = 0.8 + else: + p.reasons.append(f"Alexanders upstairs neighbour has not played league for {last_game_in_hours} hours!") + p.probability = last_game_in_hours / 24 + + return p From 0fbf9ed9e48d0f0f7f646f78635a40023048bc97 Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 16:45:10 +0200 Subject: [PATCH 08/20] Added documentation --- server/nightr/strategies/cars_in_traffic.py | 5 ++++- server/nightr/strategies/upstairs_neighbour.py | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/server/nightr/strategies/cars_in_traffic.py b/server/nightr/strategies/cars_in_traffic.py index 65cf324..8cb4ea8 100644 --- a/server/nightr/strategies/cars_in_traffic.py +++ b/server/nightr/strategies/cars_in_traffic.py @@ -3,7 +3,10 @@ import requests from ..util import Prediction, Context -def scrape_traffic(context: Context) -> Prediction: +def cars_in_traffic(context: Context) -> Prediction: + """ + How many cars are currently driving around Aarhus? + """ r = requests.get('https://portal.opendata.dk/api/3/action/datastore_search?resource_id=b3eeb0ff-c8a8-4824-99d6-e0a3747c8b0d') night_avr = 3.38 day_avr = 6.98 diff --git a/server/nightr/strategies/upstairs_neighbour.py b/server/nightr/strategies/upstairs_neighbour.py index 51ba11c..b340c58 100644 --- a/server/nightr/strategies/upstairs_neighbour.py +++ b/server/nightr/strategies/upstairs_neighbour.py @@ -10,6 +10,9 @@ def update(): def check_games(context: Context) -> Prediction: + """ + Is Alexanders upstairs neighbour currently playing League of Legends? + """ update() r = requests.get('https://euw.op.gg/summoner/userName=Im+Eating+Pros') From c3be26fa5134cfa0439d920f0ad1e8f1de602776 Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 16:50:46 +0200 Subject: [PATCH 09/20] Fixed probs --- server/nightr/strategies/upstairs_neighbour.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/nightr/strategies/upstairs_neighbour.py b/server/nightr/strategies/upstairs_neighbour.py index b340c58..4b528b6 100644 --- a/server/nightr/strategies/upstairs_neighbour.py +++ b/server/nightr/strategies/upstairs_neighbour.py @@ -32,7 +32,9 @@ def check_games(context: Context) -> Prediction: p.reasons.append("Alexanders 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.probability = last_game_in_hours / 24 + p.probability = 1 - (last_game_in_hours / 24) return p From 840abb6dd87ba7f639846c34ee6e6a15c863835e Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 17:32:03 +0200 Subject: [PATCH 10/20] Integration. --- server/nightr/app.py | 27 ++++---- server/nightr/strategies/dmi.py | 12 ---- server/nightr/strategies/iss.py | 89 ++++++++++++++++++++++++++ server/nightr/strategies/miloStrats.py | 4 +- server/nightr/strategies/steam.py | 12 ---- server/nightr/util.py | 1 + server/requirements.txt | 10 ++- 7 files changed, 115 insertions(+), 40 deletions(-) delete mode 100644 server/nightr/strategies/dmi.py create mode 100644 server/nightr/strategies/iss.py delete mode 100644 server/nightr/strategies/steam.py diff --git a/server/nightr/app.py b/server/nightr/app.py index 6d65d1c..cf488fe 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -1,4 +1,5 @@ import inspect +import logging import statistics from dataclasses import asdict from datetime import timedelta @@ -7,21 +8,24 @@ from typing import List import requests_cache from flask import Flask, jsonify -from .strategies import dmi, steam, miloStrats +from .strategies import miloStrats, iss, cars_in_traffic, tide_strat, upstairs_neighbour from .util import Context +logger = logging.getLogger(__name__) app = Flask(__name__) -requests_cache.install_cache("requests_cache.sqlite", expire_after=timedelta(minutes=10)) +requests_cache.install_cache("requests_cache", expire_after=timedelta(minutes=10)) strategies = { # name: (weight, probability function) - "dmi": (0.5, dmi.probability), - "steam": (1.0, steam.probability), - "australia": (1.0, miloStrats.australiaStrat), - "camera": (1.0, miloStrats.camImgStrat), - "tv2news": (1.0, miloStrats.tv2newsStrat) + "tv2news": miloStrats.tv2newsStrat, + "australia": miloStrats.australiaStrat, + "camera": miloStrats.camImgStrat, + "iss": iss.night_on_iss, + "cars_in_traffic": cars_in_traffic.cars_in_traffic, + "tide": tide_strat.is_tide, + "upstairs_neighbour": upstairs_neighbour.check_games, } @@ -31,17 +35,18 @@ def probabilities(): context = Context(**phone_data) predictions: List[dict] = [] - for name, (weight, strategy) in strategies.items(): + for name, strategy in strategies.items(): try: prediction = strategy(context) except Exception as e: - print(f"Strategy {name} failed: {e}") + logger.warning("Strategy %s failed: %s", name, e) + logger.exception(e) continue predictions.append({ "name": name, "description": inspect.getdoc(strategy), - "weight": weight, - "weighted_probability": prediction.probability * weight, + "weight": prediction.weight, + "weighted_probability": prediction.probability * prediction.weight, "night": prediction.probability > 0.5, **asdict(prediction), }) diff --git a/server/nightr/strategies/dmi.py b/server/nightr/strategies/dmi.py deleted file mode 100644 index 7b2f431..0000000 --- a/server/nightr/strategies/dmi.py +++ /dev/null @@ -1,12 +0,0 @@ -from ..util import Context, Prediction - - -def probability(context: Context) -> Prediction: - """ - The data from DMI. - """ - p = Prediction() - p.probability = 0.7 - p.reasons.append("It is raining in Tønder") - - return p diff --git a/server/nightr/strategies/iss.py b/server/nightr/strategies/iss.py new file mode 100644 index 0000000..17ed941 --- /dev/null +++ b/server/nightr/strategies/iss.py @@ -0,0 +1,89 @@ +import itertools +import logging +from datetime import datetime +from math import pi, sqrt, sin, cos, atan2 + +import pytz +import requests +from timezonefinder import TimezoneFinder + +from ..util import Context, Prediction + +logger = logging.getLogger(__name__) +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. + """ + p = Prediction() + + if not context.flat_earth: + iss_position = requests.get("http://api.open-notify.org/iss-now.json").json()["iss_position"] + the_iss = "The ISS" + iss_position_description = "on board the ISS" + else: + p.reasons.append("The ISS is (obviously) located in Hollywood") + the_iss = "Hollywood" + iss_position = {'latitude': 34.092808, 'longitude': -118.328659} # Hollywood + iss_position_description = "in the Hollywood studio" + + phone_position = context.position + + # Calculate ratio: a number between 0 and 1 saying how close we are to the ISS + distance = haversine(iss_position, phone_position) + max_distance = 40075 / 2 # the furthest you can be from any position is half of the earth's circumference + ratio = distance / max_distance + + # We're in the same "timezone" as the ISS if we're on the same half of the earth + on_iss_time = ratio < 0.5 + + side = "same" if on_iss_time else "other" + p.reasons.append(f"{the_iss} is {int(distance)} km away, so we are on the {side} side of the earth.") + for i in itertools.count(1): + iss_tz = tf.closest_timezone_at(lng=float(iss_position["longitude"]), + lat=float(iss_position["latitude"]), + delta_degree=i) + if iss_tz is not None: + break + iss_time = datetime.now(pytz.timezone(iss_tz)) + + iss_night = 6 < iss_time.hour > 22 + + # iss_night on_iss_time night + # 0 0 1 + # 0 1 0 + # 1 0 0 + # 1 1 1 + night = iss_night == on_iss_time + + iss_time_description = "nighttime" if iss_night else "daytime" + time_description = "nighttime" if night else "daytime" + p.probability = float(night) + p.reasons.append(f"It is {iss_time_description} {iss_position_description}.") + p.reasons.append(f"Therefore, it must be {time_description} where we are.") + + return p + + +def haversine(pos1, pos2): + """ + Distance between two GPS coordinates. + https://stackoverflow.com/a/18144531 + """ + lat1 = float(pos1["latitude"]) + long1 = float(pos1["longitude"]) + lat2 = float(pos2["latitude"]) + long2 = float(pos2["longitude"]) + + degree_to_rad = float(pi / 180.0) + + d_lat = (lat2 - lat1) * degree_to_rad + d_long = (long2 - long1) * degree_to_rad + + a = pow(sin(d_lat / 2), 2) + cos(lat1 * degree_to_rad) * cos(lat2 * degree_to_rad) * pow(sin(d_long / 2), 2) + c = 2 * atan2(sqrt(a), sqrt(1 - a)) + km = 6367 * c + + return km diff --git a/server/nightr/strategies/miloStrats.py b/server/nightr/strategies/miloStrats.py index 49875e6..be105e5 100644 --- a/server/nightr/strategies/miloStrats.py +++ b/server/nightr/strategies/miloStrats.py @@ -1,18 +1,18 @@ from datetime import datetime +from pathlib import Path import requests import cv2 from pytz import timezone from ..util import Context, Prediction -#from server.nightr.util import Context, Prediction def camImgStrat(context : Context) -> Prediction: """ The contents of the camera image """ - img = cv2.imread('night.jpg',0) + img = cv2.imread(str(Path(__file__).parent.joinpath("night.jpg")), 0) average = img.mean(axis=0).mean(axis=0) print(average) p = Prediction() diff --git a/server/nightr/strategies/steam.py b/server/nightr/strategies/steam.py deleted file mode 100644 index 814ae4f..0000000 --- a/server/nightr/strategies/steam.py +++ /dev/null @@ -1,12 +0,0 @@ -from ..util import Context, Prediction - - -def probability(context: Context) -> Prediction: - """ - How many players are currently online on Steam. - """ - p = Prediction() - p.probability = 0.2 - p.reasons.append("CSGO has more than 10.000 online players") - - return p diff --git a/server/nightr/util.py b/server/nightr/util.py index db52a0a..5b2bc3c 100644 --- a/server/nightr/util.py +++ b/server/nightr/util.py @@ -15,4 +15,5 @@ class Context: @dataclass class Prediction: probability: float = 0.5 + weight: float = 1.0 reasons: List[str] = field(default_factory=list) diff --git a/server/requirements.txt b/server/requirements.txt index 776c8a0..a900813 100644 --- a/server/requirements.txt +++ b/server/requirements.txt @@ -1,7 +1,11 @@ -Flask==1.0.2 -requests==2.21.0 -requests-cache==0.4.13 +Flask +requests +requests-cache pytz beautifulsoup4 pandas opencv-python +timezonefinder +scikit-learn +html5lib +xlrd From 945b0c969f5db6153cfc203de9e512882c83611f Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 17:32:46 +0200 Subject: [PATCH 11/20] Update gitignore with requests_cache.sqlite --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index a6f12ec..6c1bb16 100644 --- a/.gitignore +++ b/.gitignore @@ -519,3 +519,7 @@ tags .history # End of https://www.gitignore.io/api/vim,emacs,android,pycharm+all,androidstudio,visualstudiocode,python,java,angular + + +# Custom +requests_cache.sqlite From 36c980d94f79ab65c08317410d8b47171cf8634e Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 17:38:19 +0200 Subject: [PATCH 12/20] Fixing bugs --- server/nightr/strategies/cars_in_traffic.py | 5 ++++- server/nightr/strategies/just_eat.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 server/nightr/strategies/just_eat.py diff --git a/server/nightr/strategies/cars_in_traffic.py b/server/nightr/strategies/cars_in_traffic.py index 8cb4ea8..f30e676 100644 --- a/server/nightr/strategies/cars_in_traffic.py +++ b/server/nightr/strategies/cars_in_traffic.py @@ -19,7 +19,10 @@ def cars_in_traffic(context: Context) -> Prediction: for lel in data['result']['records']: sum += lel['vehicleCount'] len += 1 - curr_avg = len / sum + if sum > 0: + curr_avg = len / sum + else: + curr_avg = 0 diff = day_avr - night_avr diff --git a/server/nightr/strategies/just_eat.py b/server/nightr/strategies/just_eat.py new file mode 100644 index 0000000..64ac646 --- /dev/null +++ b/server/nightr/strategies/just_eat.py @@ -0,0 +1,11 @@ +import requests +from bs4 import BeautifulSoup + + +def is_restaurant_open(name): + r = requests.get("https://www.just-eat.dk/area/8000-%C3%A5rhusc") + soup = BeautifulSoup(r.content, features='html5lib') + + print(soup.find('div', {'data-test-id': 'listingGroupOpen'})) + +is_restaurant_open("stop2shop") \ No newline at end of file From 9997aca958821ab83c281d99793973fbb71cd2db Mon Sep 17 00:00:00 2001 From: Milo Date: Sat, 6 Apr 2019 17:40:51 +0200 Subject: [PATCH 13/20] added weights for milo strats --- server/activate.sh | 1 - server/nightr/strategies/miloStrats.py | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/activate.sh b/server/activate.sh index cda886f..81ffbe1 100755 --- a/server/activate.sh +++ b/server/activate.sh @@ -12,7 +12,6 @@ source venv/bin/activate echo Installing required Python packages pip install -Ur requirements.txt - function run() { python -m nightr } diff --git a/server/nightr/strategies/miloStrats.py b/server/nightr/strategies/miloStrats.py index be105e5..3b08314 100644 --- a/server/nightr/strategies/miloStrats.py +++ b/server/nightr/strategies/miloStrats.py @@ -14,8 +14,9 @@ def camImgStrat(context : Context) -> Prediction: """ img = cv2.imread(str(Path(__file__).parent.joinpath("night.jpg")), 0) average = img.mean(axis=0).mean(axis=0) - print(average) p = Prediction() + p.weight = 0.7 + if average < 100: p.probability = 1.0 p.reasons.append('Image was dark') @@ -33,6 +34,7 @@ def australiaStrat(context : Context) -> Prediction: t = datetime.now().astimezone(australia) hour = t.hour p = Prediction() + if hour > 22 or hour < 6: p.probability = 0.0 p.reasons.append('It\'s night-time in Australia') @@ -55,9 +57,8 @@ def tv2newsStrat(context : Context) -> Prediction: avg_delta += d avg_timestamp = avg_delta // len(delta_times) // 60 p = Prediction() - print('average time between articles on tv2:', avg_timestamp, 'minutes') + p.weight = 0.7 p.probability = 1.0 if avg_timestamp > 50 else 0.0 p.reasons.append('There were ' + ('few' if avg_timestamp > 50 else 'many') + ' recent articles on TV2 News') - print(p.reasons[0]) return p From d51a81de49a557861d19713d130e56a969aac271 Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 17:45:03 +0200 Subject: [PATCH 14/20] Logging on server. --- server/nightr/app.py | 8 ++++---- server/nightr/strategies/iss.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/server/nightr/app.py b/server/nightr/app.py index cf488fe..63f9720 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -1,18 +1,17 @@ import inspect -import logging import statistics from dataclasses import asdict from datetime import timedelta from typing import List import requests_cache -from flask import Flask, jsonify +from flask import Flask, jsonify, logging from .strategies import miloStrats, iss, cars_in_traffic, tide_strat, upstairs_neighbour from .util import Context -logger = logging.getLogger(__name__) app = Flask(__name__) +logger = logging.create_logger(app) requests_cache.install_cache("requests_cache", expire_after=timedelta(minutes=10)) @@ -39,9 +38,10 @@ def probabilities(): try: prediction = strategy(context) except Exception as e: - logger.warning("Strategy %s failed: %s", name, e) + logger.warning("Strategy '%s' failed: %s:", name) logger.exception(e) continue + predictions.append({ "name": name, "description": inspect.getdoc(strategy), diff --git a/server/nightr/strategies/iss.py b/server/nightr/strategies/iss.py index 17ed941..e4ca5de 100644 --- a/server/nightr/strategies/iss.py +++ b/server/nightr/strategies/iss.py @@ -9,7 +9,6 @@ from timezonefinder import TimezoneFinder from ..util import Context, Prediction -logger = logging.getLogger(__name__) tf = TimezoneFinder(in_memory=True) From abe4d5186ffccda7b1c7567cd5d9debb0a15dfc9 Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 17:46:52 +0200 Subject: [PATCH 15/20] Im noob. --- server/nightr/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/nightr/app.py b/server/nightr/app.py index 63f9720..00c41ef 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -38,7 +38,7 @@ def probabilities(): try: prediction = strategy(context) except Exception as e: - logger.warning("Strategy '%s' failed: %s:", name) + logger.warning("Strategy '%s' failed:", name) logger.exception(e) continue From 670395c6725bd6937e3460ee42bfabdb66b64423 Mon Sep 17 00:00:00 2001 From: Milo Date: Sat, 6 Apr 2019 17:47:33 +0200 Subject: [PATCH 16/20] better weights --- server/nightr/strategies/miloStrats.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/nightr/strategies/miloStrats.py b/server/nightr/strategies/miloStrats.py index 3b08314..593c981 100644 --- a/server/nightr/strategies/miloStrats.py +++ b/server/nightr/strategies/miloStrats.py @@ -57,7 +57,10 @@ def tv2newsStrat(context : Context) -> Prediction: avg_delta += d avg_timestamp = avg_delta // len(delta_times) // 60 p = Prediction() - p.weight = 0.7 + if avg_timestamp < 0: + p.weight = 0.0 + else: + p.weight = 0.7 p.probability = 1.0 if avg_timestamp > 50 else 0.0 p.reasons.append('There were ' + ('few' if avg_timestamp > 50 else 'many') + ' recent articles on TV2 News') return p From 44c65183c0eb7228af79d009dd55bfb745ba95ec Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 17:49:39 +0200 Subject: [PATCH 17/20] Fixed looping bug --- server/nightr/strategies/tide_strat.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/server/nightr/strategies/tide_strat.py b/server/nightr/strategies/tide_strat.py index 9b16399..b6f1355 100644 --- a/server/nightr/strategies/tide_strat.py +++ b/server/nightr/strategies/tide_strat.py @@ -1,5 +1,6 @@ import calendar -import datetime +from datetime import datetime, timedelta + import json import requests @@ -17,7 +18,7 @@ def is_tide(context: Context) -> Prediction: p = 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}") @@ -43,21 +44,33 @@ def is_tide(context: Context) -> Prediction: time_diff = (water_level[0] - last_match[0]).seconds average_inc = time_diff/diff - average_delta = datetime.timedelta(seconds=average_inc) + average_delta = timedelta(seconds=average_inc) - if last_match[1] < 0: # 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: # Decreasing + 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 + 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: + time = last_match + while time[1] != current_water_level: + time[0] += average_delta + time[1] += 1 + last_match = water_level moments.append(time[0]) From e94199b7fd322da720f07299743d46b08cf70620 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 6 Apr 2019 17:52:50 +0200 Subject: [PATCH 18/20] Added button and location --- client/Nightr/src/app/app.component.html | 2 +- client/Nightr/src/app/app.component.ts | 1 + client/Nightr/src/app/app.module.ts | 4 +-- .../locationButton.component.css} | 0 .../locationButton.component.html | 4 +++ .../locationButton.component.ts | 25 +++++++++++++ .../app/my-button/my-button.component.html | 3 -- .../src/app/my-button/my-button.component.ts | 16 --------- .../app/services/my-geo-location.service.ts | 35 +++++++++++++++++++ client/Nightr/src/main.js | 2 +- 10 files changed, 69 insertions(+), 23 deletions(-) rename client/Nightr/src/app/{my-button/my-button.component.css => component/locationButton/locationButton.component.css} (100%) create mode 100644 client/Nightr/src/app/component/locationButton/locationButton.component.html create mode 100644 client/Nightr/src/app/component/locationButton/locationButton.component.ts delete mode 100644 client/Nightr/src/app/my-button/my-button.component.html delete mode 100644 client/Nightr/src/app/my-button/my-button.component.ts create mode 100644 client/Nightr/src/app/services/my-geo-location.service.ts diff --git a/client/Nightr/src/app/app.component.html b/client/Nightr/src/app/app.component.html index 6dea362..7bf993d 100644 --- a/client/Nightr/src/app/app.component.html +++ b/client/Nightr/src/app/app.component.html @@ -1,3 +1,3 @@ - + diff --git a/client/Nightr/src/app/app.component.ts b/client/Nightr/src/app/app.component.ts index d88b2fe..0bb10d0 100644 --- a/client/Nightr/src/app/app.component.ts +++ b/client/Nightr/src/app/app.component.ts @@ -1,4 +1,5 @@ import { Component } from "@angular/core"; +import { isEnabled, enableLocationRequest, getCurrentLocation, watchLocation, distance, clearWatch } from "nativescript-geolocation"; @Component({ selector: "ns-app", diff --git a/client/Nightr/src/app/app.module.ts b/client/Nightr/src/app/app.module.ts index d5d8d40..132e264 100644 --- a/client/Nightr/src/app/app.module.ts +++ b/client/Nightr/src/app/app.module.ts @@ -2,7 +2,7 @@ import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; import { NativeScriptModule } from "nativescript-angular/nativescript.module"; import { AppComponent } from "./app.component"; -import { MyButtonComponent } from './my-button/my-button.component'; +import { MyLocationButtonComponent } from './component/locationButton/locationButton.component'; // Uncomment and add to NgModule imports if you need to use two-way binding // import { NativeScriptFormsModule } from "nativescript-angular/forms"; @@ -19,7 +19,7 @@ import { MyButtonComponent } from './my-button/my-button.component'; ], declarations: [ AppComponent, - MyButtonComponent, + MyLocationButtonComponent, ], providers: [], schemas: [ diff --git a/client/Nightr/src/app/my-button/my-button.component.css b/client/Nightr/src/app/component/locationButton/locationButton.component.css similarity index 100% rename from client/Nightr/src/app/my-button/my-button.component.css rename to client/Nightr/src/app/component/locationButton/locationButton.component.css diff --git a/client/Nightr/src/app/component/locationButton/locationButton.component.html b/client/Nightr/src/app/component/locationButton/locationButton.component.html new file mode 100644 index 0000000..5088fab --- /dev/null +++ b/client/Nightr/src/app/component/locationButton/locationButton.component.html @@ -0,0 +1,4 @@ + + + + diff --git a/client/Nightr/src/app/component/locationButton/locationButton.component.ts b/client/Nightr/src/app/component/locationButton/locationButton.component.ts new file mode 100644 index 0000000..8495420 --- /dev/null +++ b/client/Nightr/src/app/component/locationButton/locationButton.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; +import { MyGeoLocationService} from '../../services/my-geo-location.service'; +@Component({ + selector: 'ns-locationButton', + templateUrl: './locationButton.component.html', + styleUrls: ['./locationButton.component.css'], + moduleId: module.id, +}) +export class MyLocationButtonComponent implements OnInit { + title = "Click to get location!"; + lat = "start"; + geoLocationService = new MyGeoLocationService(); + + constructor() { + } + ngOnInit() { + } + + onTap() { + this.geoLocationService.getLocation().then(location => { + this.lat = ""+location.latitude; + }).catch(error => { + }); + } +} diff --git a/client/Nightr/src/app/my-button/my-button.component.html b/client/Nightr/src/app/my-button/my-button.component.html deleted file mode 100644 index 59259f8..0000000 --- a/client/Nightr/src/app/my-button/my-button.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/client/Nightr/src/app/my-button/my-button.component.ts b/client/Nightr/src/app/my-button/my-button.component.ts deleted file mode 100644 index d18c116..0000000 --- a/client/Nightr/src/app/my-button/my-button.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'ns-my-button', - templateUrl: './my-button.component.html', - styleUrls: ['./my-button.component.css'], - moduleId: module.id, -}) -export class MyButtonComponent implements OnInit { - - constructor() { } - - ngOnInit() { - } - -} diff --git a/client/Nightr/src/app/services/my-geo-location.service.ts b/client/Nightr/src/app/services/my-geo-location.service.ts new file mode 100644 index 0000000..4de390a --- /dev/null +++ b/client/Nightr/src/app/services/my-geo-location.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@angular/core'; +import { isEnabled, enableLocationRequest, getCurrentLocation, watchLocation, distance, clearWatch, Location } from "nativescript-geolocation"; +import { stringify } from '@angular/core/src/render3/util'; + +@Injectable({ + providedIn: 'root' +}) +export class MyGeoLocationService { + loc: Location; + constructor() { + } + + getLocation(): Promise { + this.isLocationEnabled(); + var result = getCurrentLocation({ + desiredAccuracy: 3, + timeout: 5000 + }); + return result; + } + + private isLocationEnabled() { + isEnabled().then(function (isEnabled) { + if (!isEnabled) { + enableLocationRequest().then(function () { + }, function (e) { + alert("Error: " + (e.message || e)); + }); + } + }, function (e) { + alert("Error: " + (e.message || e)); + }); + + } +} diff --git a/client/Nightr/src/main.js b/client/Nightr/src/main.js index faf70ce..d07591d 100644 --- a/client/Nightr/src/main.js +++ b/client/Nightr/src/main.js @@ -11,4 +11,4 @@ var app_module_1 = require("./app/app.module"); // so we provide a wrapper platform object, platformNativeScriptDynamic, // that sets up a NativeScript application and can bootstrap the Angular framework. platform_1.platformNativeScriptDynamic().bootstrapModule(app_module_1.AppModule); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1haW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwR0FBMEc7QUFDMUcsMERBQTRFO0FBRTVFLCtDQUE2QztBQUU3QyxnRkFBZ0Y7QUFDaEYsMEVBQTBFO0FBQzFFLHNFQUFzRTtBQUN0RSx5REFBeUQ7QUFDekQseUVBQXlFO0FBQ3pFLHdFQUF3RTtBQUN4RSxtRkFBbUY7QUFDbkYsc0NBQTJCLEVBQUUsQ0FBQyxlQUFlLENBQUMsc0JBQVMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdGhpcyBpbXBvcnQgc2hvdWxkIGJlIGZpcnN0IGluIG9yZGVyIHRvIGxvYWQgc29tZSByZXF1aXJlZCBzZXR0aW5ncyAobGlrZSBnbG9iYWxzIGFuZCByZWZsZWN0LW1ldGFkYXRhKVxyXG5pbXBvcnQgeyBwbGF0Zm9ybU5hdGl2ZVNjcmlwdER5bmFtaWMgfSBmcm9tIFwibmF0aXZlc2NyaXB0LWFuZ3VsYXIvcGxhdGZvcm1cIjtcclxuXHJcbmltcG9ydCB7IEFwcE1vZHVsZSB9IGZyb20gXCIuL2FwcC9hcHAubW9kdWxlXCI7XHJcblxyXG4vLyBBIHRyYWRpdGlvbmFsIE5hdGl2ZVNjcmlwdCBhcHBsaWNhdGlvbiBzdGFydHMgYnkgaW5pdGlhbGl6aW5nIGdsb2JhbCBvYmplY3RzLFxyXG4vLyBzZXR0aW5nIHVwIGdsb2JhbCBDU1MgcnVsZXMsIGNyZWF0aW5nLCBhbmQgbmF2aWdhdGluZyB0byB0aGUgbWFpbiBwYWdlLlxyXG4vLyBBbmd1bGFyIGFwcGxpY2F0aW9ucyBuZWVkIHRvIHRha2UgY2FyZSBvZiB0aGVpciBvd24gaW5pdGlhbGl6YXRpb246XHJcbi8vIG1vZHVsZXMsIGNvbXBvbmVudHMsIGRpcmVjdGl2ZXMsIHJvdXRlcywgREkgcHJvdmlkZXJzLlxyXG4vLyBBIE5hdGl2ZVNjcmlwdCBBbmd1bGFyIGFwcCBuZWVkcyB0byBtYWtlIGJvdGggcGFyYWRpZ21zIHdvcmsgdG9nZXRoZXIsXHJcbi8vIHNvIHdlIHByb3ZpZGUgYSB3cmFwcGVyIHBsYXRmb3JtIG9iamVjdCwgcGxhdGZvcm1OYXRpdmVTY3JpcHREeW5hbWljLFxyXG4vLyB0aGF0IHNldHMgdXAgYSBOYXRpdmVTY3JpcHQgYXBwbGljYXRpb24gYW5kIGNhbiBib290c3RyYXAgdGhlIEFuZ3VsYXIgZnJhbWV3b3JrLlxyXG5wbGF0Zm9ybU5hdGl2ZVNjcmlwdER5bmFtaWMoKS5ib290c3RyYXBNb2R1bGUoQXBwTW9kdWxlKTtcclxuIl19 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1haW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwR0FBMEc7QUFDMUcsMERBQTRFO0FBRTVFLCtDQUE2QztBQUU3QyxnRkFBZ0Y7QUFDaEYsMEVBQTBFO0FBQzFFLHNFQUFzRTtBQUN0RSx5REFBeUQ7QUFDekQseUVBQXlFO0FBQ3pFLHdFQUF3RTtBQUN4RSxtRkFBbUY7QUFDbkYsc0NBQTJCLEVBQUUsQ0FBQyxlQUFlLENBQUMsc0JBQVMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdGhpcyBpbXBvcnQgc2hvdWxkIGJlIGZpcnN0IGluIG9yZGVyIHRvIGxvYWQgc29tZSByZXF1aXJlZCBzZXR0aW5ncyAobGlrZSBnbG9iYWxzIGFuZCByZWZsZWN0LW1ldGFkYXRhKVxuaW1wb3J0IHsgcGxhdGZvcm1OYXRpdmVTY3JpcHREeW5hbWljIH0gZnJvbSBcIm5hdGl2ZXNjcmlwdC1hbmd1bGFyL3BsYXRmb3JtXCI7XG5cbmltcG9ydCB7IEFwcE1vZHVsZSB9IGZyb20gXCIuL2FwcC9hcHAubW9kdWxlXCI7XG5cbi8vIEEgdHJhZGl0aW9uYWwgTmF0aXZlU2NyaXB0IGFwcGxpY2F0aW9uIHN0YXJ0cyBieSBpbml0aWFsaXppbmcgZ2xvYmFsIG9iamVjdHMsXG4vLyBzZXR0aW5nIHVwIGdsb2JhbCBDU1MgcnVsZXMsIGNyZWF0aW5nLCBhbmQgbmF2aWdhdGluZyB0byB0aGUgbWFpbiBwYWdlLlxuLy8gQW5ndWxhciBhcHBsaWNhdGlvbnMgbmVlZCB0byB0YWtlIGNhcmUgb2YgdGhlaXIgb3duIGluaXRpYWxpemF0aW9uOlxuLy8gbW9kdWxlcywgY29tcG9uZW50cywgZGlyZWN0aXZlcywgcm91dGVzLCBESSBwcm92aWRlcnMuXG4vLyBBIE5hdGl2ZVNjcmlwdCBBbmd1bGFyIGFwcCBuZWVkcyB0byBtYWtlIGJvdGggcGFyYWRpZ21zIHdvcmsgdG9nZXRoZXIsXG4vLyBzbyB3ZSBwcm92aWRlIGEgd3JhcHBlciBwbGF0Zm9ybSBvYmplY3QsIHBsYXRmb3JtTmF0aXZlU2NyaXB0RHluYW1pYyxcbi8vIHRoYXQgc2V0cyB1cCBhIE5hdGl2ZVNjcmlwdCBhcHBsaWNhdGlvbiBhbmQgY2FuIGJvb3RzdHJhcCB0aGUgQW5ndWxhciBmcmFtZXdvcmsuXG5wbGF0Zm9ybU5hdGl2ZVNjcmlwdER5bmFtaWMoKS5ib290c3RyYXBNb2R1bGUoQXBwTW9kdWxlKTtcbiJdfQ== \ No newline at end of file From d4bb45b84d0573fe231121d7dad4872240bdfa75 Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Sat, 6 Apr 2019 17:56:13 +0200 Subject: [PATCH 19/20] Log execution times. --- server/nightr/app.py | 8 +++++++- server/nightr/strategies/upstairs_neighbour.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/server/nightr/app.py b/server/nightr/app.py index 00c41ef..3f8b923 100644 --- a/server/nightr/app.py +++ b/server/nightr/app.py @@ -1,7 +1,9 @@ import inspect import statistics +import timeit from dataclasses import asdict from datetime import timedelta +from logging import DEBUG from typing import List import requests_cache @@ -12,6 +14,7 @@ from .util import Context app = Flask(__name__) logger = logging.create_logger(app) +logger.setLevel(DEBUG) requests_cache.install_cache("requests_cache", expire_after=timedelta(minutes=10)) @@ -36,7 +39,10 @@ def probabilities(): predictions: List[dict] = [] for name, strategy in strategies.items(): try: + start = timeit.default_timer() prediction = strategy(context) + stop = timeit.default_timer() + logger.debug("Execution time for %s: %ss", name, stop - start) except Exception as e: logger.warning("Strategy '%s' failed:", name) logger.exception(e) @@ -79,7 +85,7 @@ def probabilities(): def main(): - app.run(host='0.0.0.0') + app.run(host='0.0.0.0', debug=True) if __name__ == '__main__': diff --git a/server/nightr/strategies/upstairs_neighbour.py b/server/nightr/strategies/upstairs_neighbour.py index 4b528b6..63ff206 100644 --- a/server/nightr/strategies/upstairs_neighbour.py +++ b/server/nightr/strategies/upstairs_neighbour.py @@ -6,7 +6,7 @@ from ..util import Prediction, Context def update(): - requests.post('https://euw.op.gg/summoner/ajax/renew.json/', data = {'summonerId': 34009256}) + requests.post('https://euw.op.gg/summoner/ajax/renew.json/', data={'summonerId': 34009256}) def check_games(context: Context) -> Prediction: From daa6ec876cb9c5e5611b1b98ba4f148372ebb1e6 Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Sat, 6 Apr 2019 18:01:50 +0200 Subject: [PATCH 20/20] more bug fixing --- server/nightr/strategies/tide_strat.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/nightr/strategies/tide_strat.py b/server/nightr/strategies/tide_strat.py index b6f1355..2b48c4f 100644 --- a/server/nightr/strategies/tide_strat.py +++ b/server/nightr/strategies/tide_strat.py @@ -33,7 +33,7 @@ def is_tide(context: Context) -> Prediction: matches = [[x[0], int(x[1])] for x in lel if x[0].month == month] all_the_data = requests.get('https://www.dmi.dk/NinJo2DmiDk/ninjo2dmidk?cmd=odj&stations=22331&datatype=obs') - current_water_level = json.loads(all_the_data.content)[0]['values'][-1]['value'] + current_water_level = int(json.loads(all_the_data.content)[0]['values'][-1]['value']) # Generate average of when the water is high last_match = matches[0] @@ -50,6 +50,7 @@ def is_tide(context: Context) -> Prediction: 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 @@ -62,12 +63,14 @@ def is_tide(context: Context) -> Prediction: 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: time = last_match while time[1] != current_water_level: + time[0] += average_delta time[1] += 1