This commit is contained in:
Viktor Søndergaard 2019-04-07 05:01:56 +02:00
parent dd13101bcb
commit 6ee03105f5
6 changed files with 73 additions and 5 deletions

BIN
dota2players.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -3,3 +3,30 @@ cd server/
source activate.sh
run
```
## Inspiration
We were tasked with the troubling assignment of coming up with a project to built throughout this weekend. We had a base at the bar, sitting inside all confused and slightly drunk, as we did in fact not know if it was dark outside. This bewilderment inspired us to try and figure out how we could efficiently determine if it was nighttime, to try and fight our confusion.
## What it does
The application taps into all the open data that Denmark has to offer. We use the number of cars on the roads, the free parking spaces, the level of the water in the bay, the number of cars having driven across the great belt bridge and whether your favorite pizza place is currently open. We also realise that everything has to utilise Machine Learning, so naturally the application has a support vector machine using all of two data points in an attempt to determine if it's nighttime based on free parking spaces. This is not all though, we also look at where the ISS space station is and much more, we do, however, make sure to not trust the clock.. Or Bing. Furthermore, the application allows for you to live in Australia, thus inverting everything, or perhaps you're a flat-earther and do not recognize space as a thing, thus special effort has to be taken.
## How we built it
Through the power of drunken ideas and mediocre at best skills at Python.
We have a backend server which is written in Python. This server is easily extendable with strategies for determining whether or not it is nighttime. Whenever a request is received, the context of the person asking the question is sent to each strategy, who then has to determine if they think it is nighttime. Each answer is pooled together and we determine a weighted average from this. How each strategy determines this, is heavily dependent on its focus area. Some strategies use advanced machine learning, some use open data which has to be scraped or some just figure out if Alexanders upstairs neighbour is playing League of Legends.
On the frontend side of things, we have built a cross-platform application in nativescript. This application is built using their frameworks in Javascript and is tested on an android phone.
## Challenges we ran into
We had to figure out how nativescript worked. We also had to find all the required data and do a bunch of odd calculations, such that the strategies could fulfill their purpose. The most difficult part was definitely building the app to work on an android phone, as none of us had really used this framework before. We had a slight grasp on machine learning prior to this, so the primary struggle of this, was building the dataset.
## Accomplishments that we're proud of
We have scraped thousands of lines of open data, scoured through it to find what could be correlated to whether or not it is nighttime. We have built an android phone from the bottom up, capable of displaying our results and talking to our backend server. We have had to look at and decipher what internal calls different websites perform, as they did not actually give an open API. All of this results in an app which can give an accurate guess on whether or not it is nighttime.
## What we learned
How to use nativescript.
How to scrape data using various python frameworks.
A strange amount of information in regards to the flat earth society.
How many factors ACTUALLY have a direct correlation with whether or not it is nighttime.
## What's next for Nightr
We're actively looking for investors for our series A funding. BlackRock, get in touch!

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, svm_strat, battery, just_eat
from .strategies import miloStrats, iss, cars_in_traffic, tide_strat, upstairs_neighbour, bing, svm_strat, battery, just_eat, steam
from .util import Context
app = Flask(__name__)
@ -33,6 +33,7 @@ strategies = {
"ML Parking": svm_strat.perform_svm_pred,
"Phone Battery Level": battery.battery_level,
"Pizza Availability": just_eat.do_just_eat_strat,
"Steam Players Online": steam.dota2_players,
}

View File

@ -33,7 +33,7 @@ def is_restaurant_open(name, open, close) -> Prediction:
p.probability = 1 / 11
else:
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.reasons.append(f"We can conclude from this, that there is {1 - (1/11):.1f}% chance of it currently being night outside!")
p.probability = round(1 - (1 / 11), 2)
return p

View File

@ -0,0 +1,40 @@
from datetime import datetime
from pathlib import Path
import requests
from ..util import Context, Prediction
def dota2_players(context: Context) -> Prediction:
"""
How many players are playing Dota 2?
"""
p = Prediction()
# Find the historic data closest matching the current number of players. Lol yolo
current_players = get_dota2_players()
with Path(__file__).parent.joinpath("dotaplayers 2019-04-06 13:43:33.074496.csv").open() as csv:
best_players, best_dt = min(csv, key=lambda l: abs(int(l.rstrip().split(", ")[0]) - current_players)).rstrip().split(", ")
best_match_players = int(best_players)
best_match_datetime = datetime.strptime(best_dt, "%Y-%m-%d %H:%M:%S.%f")
night = best_match_datetime.hour < 6 or best_match_datetime.hour >= 22
night_description = "night" if night else "day"
p.reasons.append(f"{current_players} people are currently playing Dota 2.")
p.reasons.append(f"On the {night_description} of {best_match_datetime.strftime('%B %d')}, {best_match_players} were playing Dota 2.")
p.reasons.append(f"Therefore, it must currently be {night_description}time.")
p.probability = float(night) # TODO: actual float lol gg
return p
def get_dota2_players():
header = {"Client-ID": "F07D7ED5C43A695B3EBB01C28B6A18E5"}
appId = 570
game_players_url = 'https://api.steampowered.com/ISteamUserStats/GetNumberOfCurrentPlayers/v1/?format=json&appid=' + str(appId)
game_players = requests.get(game_players_url, headers=header)
players_str = str(game_players.json()['response']['player_count'])
return int(players_str)

View File

@ -19,9 +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"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}")
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:.2f}")
p.reasons.append(f"The month is therefore {calendar.month_name[month]}")
tide_data = requests.get('https://www.dmi.dk/fileadmin/user_upload/Bruger_upload/Tidevand/2019/Aarhus.t.txt')
@ -77,7 +77,7 @@ 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 water level is currently at {current_water_level} in the Aarhus Bay")
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.probability = 1 - (night / len(moments))