Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit f870b09

Browse files
Merge branch 'main' into dependabot/pip/projects/Diabetes-Monitoring-Dashboard/requests-2.32.2
2 parents f96ebaf + 7888557 commit f870b09

File tree

32 files changed

+2884
-411
lines changed

32 files changed

+2884
-411
lines changed

README.md

Lines changed: 245 additions & 216 deletions
Large diffs are not rendered by default.

projects/API Based Weather Report/API Based Weather Report.py

Lines changed: 125 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import requests
22
from datetime import datetime
3+
from Util_Functions import (
4+
wind_degree_to_direction,
5+
unix_timestamp_to_localtime,
6+
convert_temperature,
7+
)
38

49

5-
# Function to fetch weather data from OpenWeatherMap API
610
def fetch_weather(api_key, location):
11+
"""
12+
Function to fetch weather data from OpenWeatherMap API.
13+
14+
Parameters:
15+
api_key (str): API key.
16+
location (str): City name.
17+
18+
Returns:
19+
str: The JSON response string.
20+
"""
721
try:
822
# Constructing the API link with the provided API key and location
923
complete_api_link = f"https://api.openweathermap.org/data/2.5/weather?q={location}&appid={api_key}"
@@ -23,25 +37,46 @@ def fetch_weather(api_key, location):
2337
return None
2438

2539

26-
# Function to write weather information to a text file
27-
def write_to_file(location, weather_data):
40+
def write_to_file(weather_data, temperature_unit):
41+
"""
42+
Function to write weather information to a text file.
43+
44+
Parameters:
45+
weather_data (str): The JSON API response string.
46+
temperature_unit (str): 'C' for Celsius, 'F' for Fahrenheit.
47+
"""
48+
2849
try:
2950
# Opening the file "weatherinfo.txt" in write mode
3051
with open("weatherinfo.txt", "w+") as f:
3152
# Getting the current date and time
3253
date_time = datetime.now().strftime("%d %b %Y | %I:%M:%S %p")
3354

3455
# Writing header information to the file
35-
f.write("-------------------------------------------------------------\n")
36-
f.write(f"Weather Stats for - {location.upper()} || {date_time}\n")
37-
f.write("-------------------------------------------------------------\n")
56+
if (
57+
"name" in weather_data
58+
and "sys" in weather_data
59+
and "country" in weather_data["sys"]
60+
):
61+
f.write(
62+
"-------------------------------------------------------------\n"
63+
)
64+
f.write(
65+
f"Weather Stats for - {weather_data['name']} | {weather_data['sys']['country']} "
66+
f"| {date_time}\n"
67+
)
68+
f.write(
69+
"-------------------------------------------------------------\n"
70+
)
3871

3972
# Writing temperature information to the file
4073
if "main" in weather_data and "temp" in weather_data["main"]:
4174
f.write(
42-
"\tCurrent temperature is : {:.2f} °C\n".format(
43-
weather_data["main"]["temp"] - 273.15
75+
"\tCurrent temperature is : "
76+
+ convert_temperature(
77+
weather_data["main"]["temp"], temperature_unit
4478
)
79+
+ "\n"
4580
)
4681

4782
# Writing weather description information to the file
@@ -68,6 +103,42 @@ def write_to_file(location, weather_data):
68103
)
69104
)
70105

106+
# Writing wind direction information to the file
107+
if "wind" in weather_data and "deg" in weather_data["wind"]:
108+
f.write(
109+
"\tCurrent wind direction : "
110+
+ wind_degree_to_direction(weather_data["wind"]["deg"])
111+
+ " \n"
112+
)
113+
114+
# Writing sunrise local time to the file
115+
if (
116+
"sys" in weather_data
117+
and "sunrise" in weather_data["sys"]
118+
and "timezone" in weather_data
119+
):
120+
f.write(
121+
"\tToday's sunrise time : "
122+
+ unix_timestamp_to_localtime(
123+
weather_data["sys"]["sunrise"], weather_data["timezone"]
124+
)
125+
+ " \n"
126+
)
127+
128+
# Writing sunset local time to the file
129+
if (
130+
"sys" in weather_data
131+
and "sunset" in weather_data["sys"]
132+
and "timezone" in weather_data
133+
):
134+
f.write(
135+
"\tToday's sunset time : "
136+
+ unix_timestamp_to_localtime(
137+
weather_data["sys"]["sunset"], weather_data["timezone"]
138+
)
139+
+ " \n"
140+
)
141+
71142
# Printing confirmation message after writing to file
72143
print("Weather information written to weatherinfo.txt")
73144

@@ -76,36 +147,76 @@ def write_to_file(location, weather_data):
76147
print("Error writing to file:", e)
77148

78149

79-
# Main function
80150
def main():
151+
"""
152+
Main function.
153+
"""
81154
# Printing welcome messages and instructions
82155
print("Welcome to the Weather Information App!")
83156
print("You need an API key to access weather data from OpenWeatherMap.")
84157
print(
85158
"You can obtain your API key by signing up at https://home.openweathermap.org/users/sign_up"
86159
)
87160

88-
# Prompting the user to input API key and city name
161+
# Prompting the user to input API key, city name, and temperature unit
89162
api_key = input("Please enter your OpenWeatherMap API key: ")
90163
location = input("Enter the city name: ")
164+
temperature_unit = input(
165+
"Enter the temperature unit. 'C' for Celsius and 'F' for Fahrenheit: "
166+
)
167+
168+
if not (temperature_unit.upper() == "C" or temperature_unit.upper() == "F"):
169+
print("Temperature unit must either be 'C' or be 'F'.")
170+
return
91171

92172
# Fetching weather data using the provided API key and location
93173
weather_data = fetch_weather(api_key, location)
94174

95175
# Checking if weather data was successfully fetched
96176
if weather_data:
177+
# Checking if the API key is invalid
178+
if weather_data["cod"] == "401":
179+
print("Invalid API key.")
180+
return
181+
182+
# Checking if the city is not found
183+
if weather_data["cod"] == "404":
184+
print("City not found.")
185+
return
186+
97187
# Writing weather information to file
98-
write_to_file(location, weather_data)
188+
write_to_file(weather_data, temperature_unit)
99189

100190
# Printing weather information to console
101191
print(
102-
"Current temperature is: {:.2f} °C".format(
103-
weather_data["main"]["temp"] - 273.15
104-
)
192+
"Current City : "
193+
+ weather_data["name"]
194+
+ ", "
195+
+ weather_data["sys"]["country"]
196+
)
197+
print(
198+
"Current temperature is: "
199+
+ convert_temperature(weather_data["main"]["temp"], temperature_unit)
105200
)
106201
print("Current weather desc : " + weather_data["weather"][0]["description"])
107202
print("Current Humidity :", weather_data["main"]["humidity"], "%")
108203
print("Current wind speed :", weather_data["wind"]["speed"], "kmph")
204+
print(
205+
"Current wind direction:",
206+
wind_degree_to_direction(weather_data["wind"]["deg"]),
207+
)
208+
print(
209+
"Today's sunrise time :",
210+
unix_timestamp_to_localtime(
211+
weather_data["sys"]["sunrise"], weather_data["timezone"]
212+
),
213+
)
214+
print(
215+
"Today's sunset time :",
216+
unix_timestamp_to_localtime(
217+
weather_data["sys"]["sunset"], weather_data["timezone"]
218+
),
219+
)
109220
else:
110221
# Printing error message if weather data fetching fails
111222
print("Failed to fetch weather data. Please check your input and try again.")
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
from datetime import datetime, timedelta
2+
3+
4+
def wind_degree_to_direction(str_wind_degree):
5+
"""
6+
Convert wind degree to wind direction.
7+
8+
Parameters:
9+
str_wind_degree (str): Wind degree from API (0 to 360)
10+
11+
Returns:
12+
str: Wind direction (e.g., N, NE, E, etc.)
13+
Or message "API Wind Degree data format error!"
14+
"""
15+
# convert wind degree from str to int.
16+
try:
17+
wind_degree = int(str_wind_degree)
18+
except ValueError:
19+
return "API Wind Degree data format error!"
20+
21+
directions = [
22+
"N",
23+
"NNE",
24+
"NE",
25+
"ENE",
26+
"E",
27+
"ESE",
28+
"SE",
29+
"SSE",
30+
"S",
31+
"SSW",
32+
"SW",
33+
"WSW",
34+
"W",
35+
"WNW",
36+
"NW",
37+
"NNW",
38+
]
39+
index = int((wind_degree + 11.25) // 22.5) % 16
40+
return directions[index]
41+
42+
43+
def unix_timestamp_to_localtime(str_unix_timestamp, str_timezone_offset_seconds):
44+
"""
45+
Convert unix timestamp to localtime (for sunrise and sunset).
46+
47+
Parameters:
48+
str_unix_timestamp (str): Unix timestamp (e.g., "1717715516")
49+
str_timezone_offset_seconds (str): timezone offset in second (e.g., "28800" represents UTC+8)
50+
51+
Returns:
52+
str: local_time (e.g., "2024-06-07 07:11:56")
53+
Or message "API sunset/sunrise data format error!"
54+
Or message "API timezone data format error!"
55+
"""
56+
# Convert strings to integers
57+
try:
58+
unix_timestamp = int(str_unix_timestamp)
59+
except ValueError:
60+
return "API sunset/sunrise data format error!"
61+
62+
try:
63+
timezone_offset_seconds = int(str_timezone_offset_seconds)
64+
except ValueError:
65+
return "API timezone data format error!"
66+
67+
# Convert Unix timestamp to UTC datetime
68+
utc_time = datetime.utcfromtimestamp(unix_timestamp)
69+
70+
# Apply timezone offset
71+
local_time = utc_time + timedelta(seconds=timezone_offset_seconds)
72+
73+
return local_time.strftime("%Y-%m-%d %H:%M:%S")
74+
75+
76+
def convert_temperature(str_temperature_kelvin, temperature_unit):
77+
"""
78+
Convert temperature in Kelvin degree to Celsius degree or Fahrenheit degree based on second parameter .
79+
80+
Parameters:
81+
str_temperature_kelvin (str): temperature in Kelvin degree (e.g., "291.19")
82+
temperature_unit (str): "C" for Celsius, "F" for Fahrenheit
83+
84+
Returns:
85+
str: temperature (e.g., "21.07 °C" or "67.12 °F")
86+
Or message "API temperature data format error!"
87+
Or message "Temperature unit must either be 'C' or be 'F'!"
88+
"""
89+
# Convert strings to integers
90+
try:
91+
temperature_k = float(str_temperature_kelvin)
92+
except ValueError:
93+
return "API temperature data format error!"
94+
95+
# Validate temperature_unit
96+
unit = str(temperature_unit).upper()
97+
if not (unit == "C" or unit == "F"):
98+
return "Temperature unit must either be 'C' or be 'F'!"
99+
100+
# Converting
101+
if unit == "C":
102+
temperature_c = temperature_k - 273.15
103+
return f"{temperature_c:.2f} °C"
104+
105+
if unit == "F":
106+
temperature_f = temperature_k * 9 / 5 - 459.67
107+
return f"{temperature_f:.2f} °F"
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import unittest
2+
from Util_Functions import (
3+
wind_degree_to_direction,
4+
unix_timestamp_to_localtime,
5+
convert_temperature,
6+
)
7+
8+
9+
class MyTestCase(unittest.TestCase):
10+
def test_wind_degree_to_direction(self):
11+
self.assertEqual("ENE", wind_degree_to_direction("60"))
12+
self.assertEqual("SE", wind_degree_to_direction("130"))
13+
self.assertEqual("W", wind_degree_to_direction("280"))
14+
15+
def test_wind_degree_to_direction_parameter_format_error(self):
16+
self.assertEqual(
17+
"API Wind Degree data format error!", wind_degree_to_direction("abc")
18+
)
19+
20+
def test_unix_timestamp_to_localtime(self):
21+
self.assertEqual(
22+
"2024-06-07 07:11:56", unix_timestamp_to_localtime("1717715516", "28800")
23+
)
24+
25+
def test_unix_timestamp_to_localtime_unix_timestamp_format_error(self):
26+
self.assertEqual(
27+
"API sunset/sunrise data format error!",
28+
unix_timestamp_to_localtime("abc", "28800"),
29+
)
30+
31+
def test_unix_timestamp_to_localtime_timezone_format_error(self):
32+
self.assertEqual(
33+
"API timezone data format error!",
34+
unix_timestamp_to_localtime("1717715516", "abc"),
35+
)
36+
37+
def test_convert_temperature_to_celsius(self):
38+
self.assertEqual("15.44 °C", convert_temperature("288.59", "C"))
39+
40+
def test_convert_temperature_to_fahrenheit(self):
41+
self.assertEqual("59.79 °F", convert_temperature("288.59", "F"))
42+
43+
def test_convert_temperature_temperature_format_error(self):
44+
self.assertEqual(
45+
"API temperature data format error!", convert_temperature("abc", "F")
46+
)
47+
48+
def test_convert_temperature_temperature_unit_error(self):
49+
self.assertEqual(
50+
"Temperature unit must either be 'C' or be 'F'!",
51+
convert_temperature("288.59", "H"),
52+
)
53+
54+
55+
if __name__ == "__main__":
56+
unittest.main()

projects/Calculate Age/src/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)