diff --git a/notebooks/get_data_notebook.ipynb b/notebooks/get_data_notebook.ipynb new file mode 100644 index 0000000..f544ff7 --- /dev/null +++ b/notebooks/get_data_notebook.ipynb @@ -0,0 +1,459 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Velg start dato og sluttdato\n", + "\n", + "For å kunne hente data og gjøre en analyse trenger programmet å vite hvilken periode du vil hente ut for.\n", + "\n", + "Dataen skrives inn slik: (yyyy, mm, dd, hh, mm)\n", + "Her følger et eksempel: \n", + "yyyy = 2025 # år \n", + "mm = 03 # måned \n", + "dd = 01 # dato \n", + "hh = 12 # time \n", + "mm = 00 # minutt \n", + "\n", + "Denne dataen skrives da inn på følgende hvis: (2025, 03, 01, 12, 00)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Start date => unix timestamp: 1735686000\n", + "End date => unix timestamp: 1735772340\n", + "Unix timestamp => start date: 2025-01-01 00:00:00\n", + "Unix timestamp => end date: 2025-01-01 23:59:00\n" + ] + } + ], + "source": [ + "import sys\n", + "import os\n", + "\n", + "# Gets the absolute path to the src folder\n", + "sys.path.append(os.path.abspath(\"../src\"))\n", + "\n", + "# Now we can import the fucntion from the module\n", + "from my_package.date_to_unix import get_unix_timestamp\n", + "from my_package.date_to_unix import from_unix_timestamp\n", + "\n", + "# Runs the function and store the data\n", + "unix_start_date, unix_end_date = get_unix_timestamp()\n", + "\n", + "# Prints the unix_timestamp\n", + "print(\"Start date => unix timestamp:\", unix_start_date)\n", + "print(\"End date => unix timestamp:\", unix_end_date)\n", + "\n", + "# Run the function to convert from unix_timestamp to date, and store the variables\n", + "start_date, end_date = from_unix_timestamp(unix_start_date, unix_end_date)\n", + "\n", + "# prints the date\n", + "print(\"Unix timestamp => start date:\", start_date)\n", + "print(\"Unix timestamp => end date:\", end_date)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Velg en sted i Norge og få data\n", + "\n", + "Skriv inn et sted du ønsker data fra, foreløpig er det begrenset til Norge\n", + "\n", + "Programmet vil deretter hente data å lagre det i en json fil" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data has been written to /Users/toravestlund/Documents/ITBAITBEDR/TDT4114 - Anvendt programmering/anvendt_mappe/data/json/data_Jorpeland.json\n" + ] + }, + { + "data": { + "text/plain": [ + "{'message': 'Count: 24',\n", + " 'cod': '200',\n", + " 'city_id': 3150742,\n", + " 'calctime': 0.018029492,\n", + " 'cnt': 24,\n", + " 'list': [{'dt': 1735686000,\n", + " 'main': {'temp': 8,\n", + " 'feels_like': 4,\n", + " 'pressure': 989,\n", + " 'humidity': 98,\n", + " 'temp_min': 7.75,\n", + " 'temp_max': 8.95},\n", + " 'wind': {'speed': 8.27, 'deg': 219, 'gust': 13.12},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 501,\n", + " 'main': 'Rain',\n", + " 'description': 'moderate rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 1.54}},\n", + " {'dt': 1735689600,\n", + " 'main': {'temp': 8,\n", + " 'feels_like': 4.84,\n", + " 'pressure': 989,\n", + " 'humidity': 98,\n", + " 'temp_min': 7.75,\n", + " 'temp_max': 8.95},\n", + " 'wind': {'speed': 5.63, 'deg': 225, 'gust': 8.54},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735693200,\n", + " 'main': {'temp': 7.74,\n", + " 'feels_like': 4.16,\n", + " 'pressure': 989,\n", + " 'humidity': 97,\n", + " 'temp_min': 7.19,\n", + " 'temp_max': 8.9},\n", + " 'wind': {'speed': 6.61, 'deg': 222, 'gust': 11.2},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 500,\n", + " 'main': 'Rain',\n", + " 'description': 'light rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 0.19}},\n", + " {'dt': 1735696800,\n", + " 'main': {'temp': 6.33,\n", + " 'feels_like': 2.8,\n", + " 'pressure': 988,\n", + " 'humidity': 97,\n", + " 'temp_min': 6.08,\n", + " 'temp_max': 6.9},\n", + " 'wind': {'speed': 5.47, 'deg': 234, 'gust': 8.53},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 501,\n", + " 'main': 'Rain',\n", + " 'description': 'moderate rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 2.73}},\n", + " {'dt': 1735700400,\n", + " 'main': {'temp': 6.33,\n", + " 'feels_like': 3.35,\n", + " 'pressure': 987,\n", + " 'humidity': 97,\n", + " 'temp_min': 6.08,\n", + " 'temp_max': 7.28},\n", + " 'wind': {'speed': 4.27, 'deg': 225, 'gust': 8.17},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735704000,\n", + " 'main': {'temp': 5.42,\n", + " 'feels_like': 2.52,\n", + " 'pressure': 987,\n", + " 'humidity': 99,\n", + " 'temp_min': 5.41,\n", + " 'temp_max': 7.28},\n", + " 'wind': {'speed': 3.75, 'deg': 248, 'gust': 7.09},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 500,\n", + " 'main': 'Rain',\n", + " 'description': 'light rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 1}},\n", + " {'dt': 1735707600,\n", + " 'main': {'temp': 4.31,\n", + " 'feels_like': 1.6,\n", + " 'pressure': 986,\n", + " 'humidity': 99,\n", + " 'temp_min': 4.29,\n", + " 'temp_max': 6.17},\n", + " 'wind': {'speed': 3.11, 'deg': 274, 'gust': 3.57},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 500,\n", + " 'main': 'Rain',\n", + " 'description': 'light rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 0.61}},\n", + " {'dt': 1735711200,\n", + " 'main': {'temp': 3.31,\n", + " 'feels_like': 0.37,\n", + " 'pressure': 987,\n", + " 'humidity': 97,\n", + " 'temp_min': 2.75,\n", + " 'temp_max': 5.06},\n", + " 'wind': {'speed': 3.14, 'deg': 288, 'gust': 3.4},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 500,\n", + " 'main': 'Rain',\n", + " 'description': 'light rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 0.56}},\n", + " {'dt': 1735714800,\n", + " 'main': {'temp': 3,\n", + " 'feels_like': -0.12,\n", + " 'pressure': 987,\n", + " 'humidity': 97,\n", + " 'temp_min': 2.75,\n", + " 'temp_max': 3.95},\n", + " 'wind': {'speed': 3.29, 'deg': 289, 'gust': 3.54},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 500,\n", + " 'main': 'Rain',\n", + " 'description': 'light rain',\n", + " 'icon': '10n'}],\n", + " 'rain': {'1h': 0.14}},\n", + " {'dt': 1735718400,\n", + " 'main': {'temp': 2.75,\n", + " 'feels_like': -0.07,\n", + " 'pressure': 987,\n", + " 'humidity': 97,\n", + " 'temp_min': 2.19,\n", + " 'temp_max': 3.95},\n", + " 'wind': {'speed': 2.84, 'deg': 265, 'gust': 3.28},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}],\n", + " 'rain': {'1h': 0.1}},\n", + " {'dt': 1735722000,\n", + " 'main': {'temp': 2.74,\n", + " 'feels_like': -0.21,\n", + " 'pressure': 987,\n", + " 'humidity': 96,\n", + " 'temp_min': 2.19,\n", + " 'temp_max': 3.39},\n", + " 'wind': {'speed': 3, 'deg': 279, 'gust': 3.26},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04d'}]},\n", + " {'dt': 1735725600,\n", + " 'main': {'temp': 2.14,\n", + " 'feels_like': -1.38,\n", + " 'pressure': 987,\n", + " 'humidity': 96,\n", + " 'temp_min': 1.64,\n", + " 'temp_max': 2.9},\n", + " 'wind': {'speed': 3.59, 'deg': 274, 'gust': 3.72},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04d'}]},\n", + " {'dt': 1735729200,\n", + " 'main': {'temp': 1.9,\n", + " 'feels_like': -1.5,\n", + " 'pressure': 987,\n", + " 'humidity': 95,\n", + " 'temp_min': 1.64,\n", + " 'temp_max': 2.9},\n", + " 'wind': {'speed': 3.36, 'deg': 277, 'gust': 3.38},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04d'}]},\n", + " {'dt': 1735732800,\n", + " 'main': {'temp': 1.89,\n", + " 'feels_like': -1.23,\n", + " 'pressure': 988,\n", + " 'humidity': 94,\n", + " 'temp_min': 1.09,\n", + " 'temp_max': 2.84},\n", + " 'wind': {'speed': 3, 'deg': 283, 'gust': 2.94},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04d'}]},\n", + " {'dt': 1735736400,\n", + " 'main': {'temp': 1.34,\n", + " 'feels_like': -1.72,\n", + " 'pressure': 988,\n", + " 'humidity': 94,\n", + " 'temp_min': 1.08,\n", + " 'temp_max': 2.28},\n", + " 'wind': {'speed': 2.8, 'deg': 282, 'gust': 2.69},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04d'}]},\n", + " {'dt': 1735740000,\n", + " 'main': {'temp': 0.78,\n", + " 'feels_like': -2.15,\n", + " 'pressure': 988,\n", + " 'humidity': 95,\n", + " 'temp_min': 0.53,\n", + " 'temp_max': 1.73},\n", + " 'wind': {'speed': 2.55, 'deg': 298, 'gust': 2.5},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04d'}]},\n", + " {'dt': 1735743600,\n", + " 'main': {'temp': 0.77,\n", + " 'feels_like': -2.55,\n", + " 'pressure': 989,\n", + " 'humidity': 95,\n", + " 'temp_min': -0.03,\n", + " 'temp_max': 1.73},\n", + " 'wind': {'speed': 2.97, 'deg': 327, 'gust': 3.1},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735747200,\n", + " 'main': {'temp': 0.24,\n", + " 'feels_like': -4.09,\n", + " 'pressure': 990,\n", + " 'humidity': 95,\n", + " 'temp_min': -0.03,\n", + " 'temp_max': 1.33},\n", + " 'wind': {'speed': 4.15, 'deg': 334, 'gust': 4.35},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 600,\n", + " 'main': 'Snow',\n", + " 'description': 'light snow',\n", + " 'icon': '13n'}],\n", + " 'snow': {'1h': 0.32}},\n", + " {'dt': 1735750800,\n", + " 'main': {'temp': 0.23,\n", + " 'feels_like': -4.73,\n", + " 'pressure': 991,\n", + " 'humidity': 95,\n", + " 'temp_min': -0.58,\n", + " 'temp_max': 1.17},\n", + " 'wind': {'speed': 5.18, 'deg': 340, 'gust': 4.9},\n", + " 'clouds': {'all': 100},\n", + " 'weather': [{'id': 600,\n", + " 'main': 'Snow',\n", + " 'description': 'light snow',\n", + " 'icon': '13n'}],\n", + " 'snow': {'1h': 0.25}},\n", + " {'dt': 1735754400,\n", + " 'main': {'temp': 0.22,\n", + " 'feels_like': -4.84,\n", + " 'pressure': 993,\n", + " 'humidity': 93,\n", + " 'temp_min': -0.1,\n", + " 'temp_max': 1.17},\n", + " 'wind': {'speed': 5.35, 'deg': 347, 'gust': 5.68},\n", + " 'clouds': {'all': 99},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735758000,\n", + " 'main': {'temp': -0.03,\n", + " 'feels_like': -4.98,\n", + " 'pressure': 994,\n", + " 'humidity': 92,\n", + " 'temp_min': -0.59,\n", + " 'temp_max': 0.61},\n", + " 'wind': {'speed': 5.04, 'deg': 1, 'gust': 5.74},\n", + " 'clouds': {'all': 95},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735761600,\n", + " 'main': {'temp': -0.34,\n", + " 'feels_like': -4.67,\n", + " 'pressure': 995,\n", + " 'humidity': 91,\n", + " 'temp_min': -1.14,\n", + " 'temp_max': 0.06},\n", + " 'wind': {'speed': 3.96, 'deg': 20, 'gust': 4.67},\n", + " 'clouds': {'all': 89},\n", + " 'weather': [{'id': 804,\n", + " 'main': 'Clouds',\n", + " 'description': 'overcast clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735765200,\n", + " 'main': {'temp': -0.35,\n", + " 'feels_like': -4.09,\n", + " 'pressure': 996,\n", + " 'humidity': 90,\n", + " 'temp_min': -0.89,\n", + " 'temp_max': -0.1},\n", + " 'wind': {'speed': 3.19, 'deg': 16, 'gust': 3.98},\n", + " 'clouds': {'all': 62},\n", + " 'weather': [{'id': 803,\n", + " 'main': 'Clouds',\n", + " 'description': 'broken clouds',\n", + " 'icon': '04n'}]},\n", + " {'dt': 1735768800,\n", + " 'main': {'temp': -0.89,\n", + " 'feels_like': -4.8,\n", + " 'pressure': 997,\n", + " 'humidity': 87,\n", + " 'temp_min': -1.69,\n", + " 'temp_max': -0.1},\n", + " 'wind': {'speed': 3.26, 'deg': 19, 'gust': 3.75},\n", + " 'clouds': {'all': 49},\n", + " 'weather': [{'id': 802,\n", + " 'main': 'Clouds',\n", + " 'description': 'scattered clouds',\n", + " 'icon': '03n'}]}]}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import sys\n", + "import os\n", + "\n", + "# Gets the absolute path to the src folder\n", + "sys.path.append(os.path.abspath(\"../src\"))\n", + "\n", + "# Now we can import the fucntion from the module\n", + "from my_package.get_data import get_data\n", + "\n", + "get_data(unix_start_date, unix_end_date)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/my_package/date_to_unix.py b/src/my_package/date_to_unix.py index cef3b2d..92ea3ce 100644 --- a/src/my_package/date_to_unix.py +++ b/src/my_package/date_to_unix.py @@ -2,45 +2,41 @@ import datetime import time -start_date = input("Choose a start date (yyyy, mm, dd, hh, mm): ") -end_date = input("Choose an end date (yyyy, mm, dd, hh, mm): ") - -# Variables that splits and assign the start date values -start_date = start_date.split(",") -start_year = int(start_date[0]) -start_month = int(start_date[1]) -start_date = int(start_date[2]) -start_hour = int(start_date[3]) -start_minute = int(start_date[4]) - -# Variables that splits and assign the end date values -end_date = end_date.split(",") -end_year = int(end_date[0]) -end_month = int(end_date[1]) -end_date = int(end_date[2]) -end_hour = int(end_date[3]) -end_minute = int(end_date[4]) - -# Converts start date to unix, and print, with the user input -start_date_unix = datetime.datetime(start_year, start_month, start_date, start_hour, start_minute) +def get_unix_timestamp(): + start_date_input = input("Choose a start date (yyyy, mm, dd, hh, mm): ") + end_date_input = input("Choose an end date (yyyy, mm, dd, hh, mm): ") + + # Variables that splits and assign the start date values + start_date_components = start_date_input.split(",") + start_year = int(start_date_components[0]) + start_month = int(start_date_components[1]) + start_date = int(start_date_components[2]) + start_hour = int(start_date_components[3]) + start_minute = int(start_date_components[4]) + + # Variables that splits and assign the end date values + end_date_components = end_date_input.split(",") + end_year = int(end_date_components[0]) + end_month = int(end_date_components[1]) + end_date = int(end_date_components[2]) + end_hour = int(end_date_components[3]) + end_minute = int(end_date_components[4]) + + # Converts dates to timestamp used to convert to unix, and print, with the user input + start_date_timestamp = datetime.datetime(start_year, start_month, start_date, start_hour, start_minute) + end_date_timestamp = datetime.datetime(end_year, end_month, end_date, end_hour, end_minute) + + unix_start = int(time.mktime(start_date_timestamp.timetuple())) + unix_end = int(time.mktime(end_date_timestamp.timetuple())) -# Print regular start date -print("date_time =>", start_date_unix) - -# Print unix start date -print("unix_timestamp => ", - (time.mktime(start_date_unix.timetuple()))) - + # return the unix_start and end timestamp + return unix_start, unix_end -# Converts end date to unix, and print, with the user input -end_date_unix = datetime.datetime(end_year, end_month, end_date, end_hour, end_minute) +def from_unix_timestamp(unix_start, unix_end): + start_from_unix = datetime.datetime.fromtimestamp(unix_start) + end_from_unix = datetime.datetime.fromtimestamp(unix_end) -# Print regular end date -print("date_time =>", end_date_unix) - -# Print unix end date -print("unix_timestamp => ", - (time.mktime(end_date_unix.timetuple()))) + return start_from_unix, end_from_unix diff --git a/src/my_package/get_data.py b/src/my_package/get_data.py index ed83c3f..a3e94c4 100644 --- a/src/my_package/get_data.py +++ b/src/my_package/get_data.py @@ -10,18 +10,19 @@ # Gets the key, from my env file API_KEY = os.getenv("API_KEY") -# User input the city, for the weather -city_name = input("Enter a city in Norway: ") country_code = "NO" # Temporarily standard times -start = 1742079600 -end = 1742166000 +# start_date = 1742079600 +# end_date = 1742166000 # Gets the data from the API - openweathermap.org -def get_data(): +def get_data(start_date, end_date): + # User input the city, for the weather + city_name = input("Enter a city in Norway: ") + # f-string url, to add the "custom" variables to the API-request - url = f"https://history.openweathermap.org/data/2.5/history/city?q={city_name},{country_code}&units=metric&type=hour&start={start}&end={end}&appid={API_KEY}" + url = f"https://history.openweathermap.org/data/2.5/history/city?q={city_name},{"NO"}&units=metric&type=hour&start={start_date}&end={end_date}&appid={API_KEY}" # Saves the API-request for the url response = requests.get(url) @@ -32,11 +33,14 @@ def get_data(): # Converts the data into json data = response.json() - # Ensure the 'data' folder exists in the root of the project - os.makedirs('data', exist_ok=True) # Creates 'data' folder if it doesn't exist + # Ensure the 'json' folder exists inside the 'data' folder at the root of the project + script_dir = os.path.dirname(os.path.abspath(__file__)) # Get the directory of the script + project_root = os.path.abspath(os.path.join(script_dir, os.pardir, os.pardir)) # Navigate to the root of the project + data_dir = os.path.join(project_root, 'data', 'json') + os.makedirs(data_dir, exist_ok=True) # Creates 'data/json' folder if it doesn't exist - # Write the JSON data to a file inside the 'data' folder - file_path = os.path.join('data', 'data.json') # Creates 'data/data.json' + # Write the JSON data to a file inside the 'json' folder + file_path = os.path.join(data_dir, f'data_{city_name}.json') # Creates 'data/json/data_{city_name}.json' # Opens and write the data to a json file with open(file_path, 'w') as json_file: @@ -51,22 +55,24 @@ def get_data(): print("Failed to fetch data from API. Status code:", response.status_code) # Stores the data in the myData variable -myData = get_data() +# myData = get_data(start_date, end_date) + +# # Empty dict for temperature +# temperature = {} -# Empty dict for temperature -temperature = {} +# # Iterates through myData dict, and add the dt (unix_time) and temp to temperature dict +# if "list" in myData: +# for item in myData["list"]: +# if "main" in item and "temp" in item["main"]: +# temperature[item["dt"]] = (item["main"]["temp"]) -# Iterates through myData dict, and add the dt (unix_time) and temp to temperature dict -if "list" in myData: - for item in myData["list"]: - if "main" in item and "temp" in item["main"]: - temperature[item["dt"]] = (item["main"]["temp"]) +# # print(temperature) -# print(temperature) +# # A test plot, to get a visual look of the data +# x_temp = temperature.keys() +# y_temp = temperature.values() -# A test plot, to get a visual look of the data -x_temp = temperature.keys() -y_temp = temperature.values() +# plt.plot(x_temp, y_temp) -plt.plot(x_temp, y_temp) -plt.show() +# # plt.hist(x_temp, y_temp) +# plt.show() \ No newline at end of file