From 6747c731c613c15bbed70cc5fd58308251cd5ff8 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 10 Jul 2025 23:53:16 +0000 Subject: [PATCH] Adding moon and sun phases --- Pipfile | 1 + Pipfile.lock | 108 ++++++++++++++++++++++++++++++++++++- data/build_weather.py | 21 ++++++++ data/sql/build_db.sql | 1 - data/sql/prefill_parks.sql | 3 +- data/stats_importer.py | 25 ++++++--- main.py | 24 +++++---- 7 files changed, 161 insertions(+), 22 deletions(-) diff --git a/Pipfile b/Pipfile index b86d932..16094ce 100644 --- a/Pipfile +++ b/Pipfile @@ -4,6 +4,7 @@ verify_ssl = true name = "pypi" [packages] +ephem = "*" geopy = "*" matplotlib = "*" numpy = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 88e0dc9..ea0b32e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "126729a6f98a1153aadb9df0008587107239cbb495b6d44f658c16a275f11a0a" + "sha256": "a3658f8ae490d77c34cccced0d4f5c75c0c32084ef390cd6abe8fbd885a09bba" }, "pipfile-spec": 6, "requires": { @@ -193,6 +193,112 @@ "markers": "python_version >= '3.8'", "version": "==0.12.1" }, + "ephem": { + "hashes": [ + "sha256:02189a7e9eaf70aa887a1e9cd38db1297c52cd6febd7226811d01c304d563ebf", + "sha256:0277e0022d7a9efd740e4014a66ac56fe79f35972f79d70e2d828b17cec3805f", + "sha256:0e0c517d9e586d9cdb6bd63d3b3ca3ef1b82809fa64f70c8f659856096e0d403", + "sha256:0fbf26f0c99d7ba100df584cd4899044e582af57bbe313aecfecefd6ab389753", + "sha256:10f561e488787b6fc9a689f1f926f51bb225bb91af18ed0b38e1c93ffa179d2e", + "sha256:129fda6db42abb6baf4e55e953969ad923995dcaadacfc7d652e5ad6103d7ebe", + "sha256:13349edb5263e81a38c07157a558b712948e0456e9dd02fc33d7bb2ebdb54bdb", + "sha256:1a99357c6e1a2394231718434ec77b0a09daaaf8308e852eb887c0f830e5eab4", + "sha256:1e9b3b809ccf6addf01e852b1bb0a0c872b92144a38efda13caef1c3de451808", + "sha256:1f924be0002e943e5a73b226aecdf43c94d3e557f85674c153e712b92f6df9b3", + "sha256:20c9545f19660fcc8a6546f944304749932da354d2e5bb268df324c8051b6e9b", + "sha256:245accecb7050f3f0e495dbd49f58b38e63d70d1af2a034ba40038daa968925f", + "sha256:2c9763d4c108de400226697e7256e496ef37f60490591c043038b8fbce7bde94", + "sha256:303a476a6242174231233bcfebb8c05ad46bcc07000ef90e7c84c0b5174c50d0", + "sha256:3069578b3dfe0de4182d95ba58843f2efc26145171ca2afb233ba70a6b4b8e9d", + "sha256:308bbf9cd4449661225ceb96b205037bdefe0c82b1579d8cacd93c4b98cfa939", + "sha256:323649d8fd4f34036b43a332c8457a9e711c91ac708e3d5238a379a704b53ffb", + "sha256:38a74e63cfb6fcee6b23ad183c6d02da0c0113ae7ad4f433422a15e401c3aa92", + "sha256:3c4fd64f453e8f40cf862420a70da95a71b6487ace75e8e0cf85d73707db6065", + "sha256:3d2e52724b315944b330e9cf5e2dd2a16d7d646a14a3f21a7368e95f6e1f30e8", + "sha256:3dbb30fde6ab28b2455ea2bea5b52a93941c920125b5f2977f70dd9cc69f8c51", + "sha256:3dcc4ead3446e9831c0acc8396d93ab281cfc37d68bc01413f65017750cef13a", + "sha256:3e776b20832067257525de0bb0fdca8b6aec8c3fc9e059cff5df9160f857c9c5", + "sha256:3f3e5ff58de24006928c7ea9ff0c70a01f510816b1d687591b0de5697ea014e5", + "sha256:40aa89b316bd2cb6a5a1ed0f391983272626582cdf14e5c92cfe8d167b4a32c0", + "sha256:41589191e9cea33a2c455fcd75cd8906433b88e2b0eaca0400c753272c007272", + "sha256:45bea1bb6fb1850f2d3169e541c22fb88030976967f8c551181786f5e713100e", + "sha256:4765768de1cb0af0e179f3860e6fa0163e8a7d23faf2fa61fe113eee3748fe02", + "sha256:4776dcfabc2a2346770901da1bae7917deae557b0adc7c3d5e5f7c6e3e4d4c9f", + "sha256:4b1c87517be414f67c3b35c6dbd8bd7c28d664e06d857b4a4224511bdb06ad2e", + "sha256:4f42e6c7330b852b3cb94dedea805345d259b1bc4f3a715640a0c651c221ef47", + "sha256:5152d5e84458a10f0dec83c6934839b5f2d4a9e642fb9f9ea53161923db58aba", + "sha256:5371eeb1cdf51d7cddbc615ca140764117ddbf8b14b8e5c4be112761a570393d", + "sha256:539339b435b7fb501c3ef3695e37cc39e280c7402e4ac28d829124928bb2a8ae", + "sha256:5670edeb6a531104ae594eb48d1595ac28a57cc41603f760ab45f2618b6bf100", + "sha256:599df915cd37dae047e4d885885afff23102d33a33f9900ae95c11195cbe83cb", + "sha256:5c787ef694db5e56151595ec237f960836e672a8770b41f09f9c65c26133291b", + "sha256:65c4b960b556b1db868de77ddc7ecc9a554dd103a9d59a07321ee45657c32b3f", + "sha256:67eeb1e05390fd6ff1ed25bc60379c717ec7c2313305cf85995f469a2ee66e0c", + "sha256:68976d765a78ff3c534e11c8b9f87e83b67cacd461e7074664fb8a0c0b9ab341", + "sha256:6d3a4b72e8dc3fe36680c3f150f0f98c9df3a97e85df1c37781a0c475c1f667a", + "sha256:6e29cc55b647e07f992e7f360b7b44bb6e1ec41d503eab923054e7b6f08caa1a", + "sha256:6f72e5136105006e0eb3360a8f41c7551062d07d055fa7f48551985541b6ab74", + "sha256:6ff641a038b883c572d6ce0f642f54c0e42d568f2827e15cb7c2f78cb8e72ec6", + "sha256:729d9d42a9dcc7f80ab4a12f2cb40b2908c66a13708d6f0792bfebf55b62169f", + "sha256:74673ea73bda79b81b21a9326798f6cc32d22c0845cffb05eca5dec5c50b3a89", + "sha256:7933731d614fdb05c67a64d1e27999cd680994da3c75f1aff85a9eef11ea80d1", + "sha256:797fb2a6ecef2866f7a2d57f897dfb9f34bea60462950b94a22935272f4d7e5c", + "sha256:7b3ac07c8e09d185ff35d68dcbdde948fe9ffb5eb3b67661a5e237391145b0f6", + "sha256:813b50b2cd2172f59df4f71792e0e16702581b0b13c64bd995b29f1121d604df", + "sha256:81d20d83d5bd6ab18dcbe1b477bc3cd71c690011284d1075d08101040f2de66e", + "sha256:94cad00341ed5367144f3dfec98b6a33f285b5eb5c35971f697f8cac14f12a00", + "sha256:953292ca2e5610f472532597b14ff6c91086a0821cfe443580a6b4e27a4ed7a7", + "sha256:9592cfa54519b79fc3ab25efeee1fb4330ae8ba33d6cec24ca57ccf8abcb9983", + "sha256:97164eeeeb1da0d2ba5b72ef62e7fcde121f2b0e140774c5e5b93d902994e119", + "sha256:98b7ac952cfcefc39883684ef4d39a5d81dfa925ea9a7c720713feb665819601", + "sha256:99b6d7c75505f2ca3e470fea659dabe806c947f21d57093af5c97bb9310851e4", + "sha256:9a4e8b69803bff40ba56bb60d08e3e20c23f50bf2076cc8b8df371c92ab4418c", + "sha256:9da22f8b6fe666cc77f69ca74959463007fc0c8e913026b225658bcd91e9d358", + "sha256:9e0ca372021345efccb91845cdfe6c6e51a44067adb8f3d2629f4ab49c2cc8b0", + "sha256:9ebfbc111ff91d183d7c58612ad4f5f6c7d7e95d9ac7b5a5451714713b334f81", + "sha256:9f72002f2f6dd8ad838fcbe7b4e9bdf8daadfe3e7093383336a234da458c77a5", + "sha256:a0490e6755bde5c80787ab4937a1f1d2832ea5e6e1b624b53d5e2852b7d4c303", + "sha256:a0ab0091cb4dbe7f9a163a11d16fae63e3d2b51c9b7f0557ce5a721c95a6b4f4", + "sha256:a6f3354a5a2e78f435bd1a70bb2c245fef31591547ec5d3d95e85038e3ea0edd", + "sha256:a7aa551ea1a6ae2ee58ab31571be1caf5647c31f97588ef2a09ac8e991f9c133", + "sha256:af2a25550171fcdab9a62f1395c5e203f16796326409282d5e6e1222f4d62e0f", + "sha256:b023c79e5d8dd17124f68fcfd8756d6ec236002545769069c12479376c721d70", + "sha256:b39fb90633da4dfef95829f57c5eab4271e8284efdcdc0d00dfb8db9dee6ad78", + "sha256:b535eb78c84779531868a96cc45db1b9d98fd0258bc1994dc4ae63902841d466", + "sha256:b5ebe25f33f43cd3ae92b70a43ad558775513bddcac706474110045795b356a1", + "sha256:b767edad8324d76f8a713a4c48d9998012706455d9f1407c4d41602ff2938fce", + "sha256:bc9107ff5b290edc560898c0dcdf11c260547fd6fd0a1f65936954a92498eef9", + "sha256:bd7f93743ef79a88115d5106620827a108ca2afd83baae71d056f2f90ebb4e94", + "sha256:bd836343c6d3b0a7658a8f7d1df2937f398f4b8465a6a77b47e6fa84edd574ae", + "sha256:c34abfcbc5d33106bbc9128299e05e20f97b81f25dbf19824cf7634d2023c4ec", + "sha256:c7dcd7425cc82945b0d6cb31a0897aeae835d5e68082243e210b59036950b61e", + "sha256:cbd5f01a5a6fd687ce283ccb02d30a831ef4a88e8e8e35019d436be9c58faae9", + "sha256:cce2e0cddd3f04f0d9a5799f948cd4ad7345157819df4e7aea3d4ab24911c07b", + "sha256:d617510363d1d80d50cc601b477e4e817b83de311fea932d85bb9d87913b577a", + "sha256:d978cf7398ecc0a7e4b09c6539e5f066dc0c60efa3dfe53ab2d5ad88610f62fa", + "sha256:db6ba8a8940b0d13495e020e68092323fc7ac22cff00f5398fe1c9d4445e8fc1", + "sha256:dbad1ea774465e6cb95601dc8d8c95dd66708e08de5122f8b98e9a2e472f3b8f", + "sha256:dc2f11f7b16901cdfcd68f3fbf83ea513f3fa1368dfb456fa8e880cc70c64bb8", + "sha256:e0e771e10ffe1acaf32d2925287ff19c4b2ad8f411e32f874a7830d4043211e0", + "sha256:e2f542499995177ce675cbd32349962248cb34a4eee7caba41abfcae1655941c", + "sha256:e467a8c84295e9c3cfb5588b2d33d4649ea75c49caa0e3664dcc4f356f199704", + "sha256:e520611383389b9da89c75ea414adeead142f3acf73d662cfa2d9c09dcce6e26", + "sha256:e6db15e4169f8a73827ab0eb3a5722bb9679781375384cdea5809cf325e13b14", + "sha256:e6eb387020bccd43bf69f4f62f7f9dc154ed12947f10e8ced99ce17115426884", + "sha256:e793840ab6e899c79e09b075b1bfe21f0ff7ce9c11d9d493cee6b2c30c622008", + "sha256:e9083fe4144478a43fbba07169957b6eb3797fd97955145dd614eaa0a934ad79", + "sha256:ea8d23e7d452537fbbe1da12891ccaea5bf890a0ae35007d6c773842ad08ec16", + "sha256:f04201c4ff62ad0b1ddf1a3af9bc49e652eeaff2299a3030f68af2de2e27ec02", + "sha256:f1c232b35229130dd800c8c0dfa5d8aa6d563ced63a438d1ea0ca145e505842a", + "sha256:f20917fc08b96735e9e244219f8b211eeaacff1082406e82bf855669a92c3233", + "sha256:f409c4adb0160689a3297b83bfddf4893942eb8a6a6bf31f034d9ed8ebcd6112", + "sha256:f5f7428004626a36dc76164fe3c5b12a567b198afc3327f7d6721f87b4f73792", + "sha256:faf33b2b03e3b6cecff25b6cdb6fd3295908a8cea29b614beda5e36dc6f978a6", + "sha256:fea3ff1fb12241f12a5d4e7f303e43ac5ab467903c98f0b90539ea9cbe0cab4d" + ], + "index": "pypi", + "version": "==4.2" + }, "fonttools": { "hashes": [ "sha256:0162a6a37b0ca70d8505311d541e291cd6cab54d1a986ae3d2686c56c0581e8f", diff --git a/data/build_weather.py b/data/build_weather.py index b1882f3..61e4f72 100644 --- a/data/build_weather.py +++ b/data/build_weather.py @@ -1,8 +1,29 @@ import pytz +import ephem import requests import datetime from geopy.geocoders import Nominatim +def get_sun_and_moon_phase(lat, long, date_str): + date_str = f"{date_str[:4]}/{date_str[4:6]}/{date_str[6:8]}" + + observer = ephem.Observer() + observer.lat = str(lat) + observer.lon = str(long) + observer.date = date_str + + sun = ephem.Sun() + sun.compute(observer) + + sunrise_time = int(observer.next_rising(sun).datetime().strftime('%Y%m%d')) + sunset_time = int(observer.next_setting(sun).datetime().strftime('%Y%m%d')) + + date = ephem.Date(date_str) + moon = ephem.Moon() + moon.compute(date) + + return (sunrise_time, sunset_time, moon.phase) + def get_timezone(latitude: float, longitude: float): geolocator = Nominatim() location = geolocator.reverse(f"{latitude}, {longitude}") diff --git a/data/sql/build_db.sql b/data/sql/build_db.sql index cec0119..5eaa057 100644 --- a/data/sql/build_db.sql +++ b/data/sql/build_db.sql @@ -143,7 +143,6 @@ CREATE TABLE IF NOT EXISTS weather ( dew_point FLOAT, apparent_temperature FLOAT, air_pressure FLOAT, - wind_speed FLOAT, precipitation FLOAT, rain FLOAT, snowfall FLOAT, diff --git a/data/sql/prefill_parks.sql b/data/sql/prefill_parks.sql index f595702..b02868e 100644 --- a/data/sql/prefill_parks.sql +++ b/data/sql/prefill_parks.sql @@ -19,12 +19,13 @@ INSERT OR IGNORE INTO parks ("MIN04", "Target Field", 339, 8, 404, 8, 328, 23, 0, 44.981667, -93.278333, 827), ("NYC20", "Citi Field", 335, 8, 408, 8, 330, 8, 0, 40.756944, -73.845833, 13), ("NYC21", "Yankee Stadium II", 318, 8, 408, 8, 314, 8, 0, 40.829167, -73.926389, 23), + ("OAK01", "Oakland-Alameda County Coliseum", 330, 8, 400, 8, 330, 8, 0, 37.751667, -122.200556, -16), ("PHI13", "Citizens Bank Park", 329, 10, 401, 6, 330, 13, 0, 39.905833, -75.166389, 0), ("PHO01", "Chase Field", 330, 7.6, 407, 25, 335, 7.6, 1, 33.445526, -112.066664, 1060.36), ("PIT08", "PNC Park", 325, 6, 399, 15, 320, 21, 0, 40.446944, -80.005833, 725), - ("OAK01", "Oakland-Alameda County Coliseum", 330, 8, 400, 8, 330, 8, 0, 37.751667, -122.200556, -16), ("SAN02", "Petco Park", 334, 4, 369, 4, 322, 5, 0, 32.7073, -117.1566, 16), ("SEA03", "T-Mobile Park", 331, 15, 401, 7, 326, 7, 1, 47.591, -122.333, 16), + ("SEO01", "Gocheok Sky Dome", 325, 12, 400, 12, 325, 12, 1, 37.498222, 126.86725, 40), ("SFO03", "Oracle Park", 339, 8, 399, 8, 309, 25, 0, 37.778611, -122.389167, 13), ("STL10", "Busch Stadium III", 336, 8, 400, 8, 335, 8, 0, 38.6225, -90.193056, 440), ("STP01", "Tropicana Field", 315, 11, 404, 9, 322, 11, 1, 27.768333, -82.653333, 39), diff --git a/data/stats_importer.py b/data/stats_importer.py index eec998f..a0cba98 100644 --- a/data/stats_importer.py +++ b/data/stats_importer.py @@ -2,7 +2,7 @@ import os import csv import shutil from data.db_connect import Database -from data.build_weather import get_weather +from data.build_weather import get_weather, get_sun_and_moon_phase class Importer: def __init__(self, database: Database): @@ -191,8 +191,11 @@ class Importer: self.database.insert(insert_team_game, visiting_team_data) self.database.insert(insert_team_game, home_team_data) + parkid = game_stats["park-id"] + print(f"SELECT latitude, longitude FROM parks WHERE park_id = {parkid}") park_data = self.database.select("SELECT latitude, longitude FROM parks WHERE park_id = ?", (game_stats["park-id"],)) - + print(f"latlon {park_data}") + hour = 15 if game_stats["day-night"] == "D" else 19 historic_weather = get_weather(park_data[0], park_data[1], game_stats["date"], hour) historic_weather = historic_weather["hourly"] @@ -202,10 +205,10 @@ class Importer: ( game_id, temperature, humidity, dew_point, apparent_temperature, air_pressure, - wind_speed, precipitation, rain, - snowfall, cloud_cover, wind_speed, - wind_direction, wind_gusts, sun_rise, - sin_set, moon_phase + precipitation, rain, snowfall, + cloud_cover, wind_speed, wind_direction, + wind_gusts, sun_rise, sun_set, + moon_phase ) VALUES ( @@ -214,11 +217,17 @@ class Importer: ?, ?, ?, ?, ?, ?, ?, ?, ?, - ?, ? + ?, ) """ + (sunrise_time, sunset_time, moonphase) = get_sun_and_moon_phase(park_data[0], park_data[1], game_stats["date"]) + weather_data = [ game_id, historic_weather["temperature_2m"][hour], historic_weather["relative_humidity_2m"][hour], - + historic_weather["dew_point_2m"][hour], historic_weather["apparent_temperature"][hour], historic_weather["pressure_msl"][hour], + historic_weather["precipitation"][hour], historic_weather["rain"][hour], historic_weather["snowfall"][hour], + historic_weather["cloud_cover"][hour], historic_weather["wind_speed_10m"][hour], historic_weather["wind_direction_10m"][hour], + historic_weather["wind_gusts_10m"][hour], sunrise_time, sunset_time, + moonphase, ] diff --git a/main.py b/main.py index 84776f4..169fd2c 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ import numpy as np # helps with the math import matplotlib.pyplot as plt # to plot error during training from data.db_connect import Database from data.stats_importer import Importer -from data.build_weather import get_weather +from data.build_weather import get_weather, get_sun_and_moon_phase # input data inputs = np.array([[0, 0, 1, 0], @@ -59,25 +59,27 @@ class NeuralNetwork: return prediction if __name__ == '__main__': - #build_db_path = "./data/sql/build_db.sql" - #fill_parks_path = "./data/sql/prefill_parks.sql" - #fill_teams_path = "./data/sql/prefill_teams.sql" + build_db_path = "./data/sql/build_db.sql" + fill_parks_path = "./data/sql/prefill_parks.sql" + fill_teams_path = "./data/sql/prefill_teams.sql" db_file = "./database/baseball.db" db_conn = Database(db_file) - #db_conn.run_sql_file(build_db_path) - #db_conn.run_sql_file(fill_parks_path) - #db_conn.run_sql_file(fill_teams_path) + db_conn.run_sql_file(build_db_path) + db_conn.run_sql_file(fill_parks_path) + db_conn.run_sql_file(fill_teams_path) - #imp = Importer(db_conn) - #imp.parse_all_data("./data/stats/to_import", "./data/stats/imported/") + imp = Importer(db_conn) + imp.parse_all_data("./data/stats/to_import", "./data/stats/imported/") #we = Weather() #print(we.get_weather(39.26733000, -76.79831000, "20250706", 12)) - park_data = db_conn.select("SELECT latitude, longitude FROM parks WHERE park_id = ? OR park_id = ?", ("ATL03","KAN06",)) - print(park_data[0]) + #park_data = db_conn.select("SELECT latitude, longitude FROM parks WHERE park_id = ?", ("ATL03",)) + #print(get_sun_and_moon_phase(park_data[0], park_data[1], "20250709")) + #historic_weather = get_weather(park_data[0], park_data[1], game_stats["date"], hour) + else: # create neural network