Source code for getweather.getweather

import pandas as pd
import json

[docs]def CityInfo(): ''' Introduction: CityInfo()function aims to return a dataset that shows the information such as city id, city, state, country, latitude, longitude of all the cities in the world. Parameters: No parameter. Output: a dataset of city id, city, state, country, latitude, longitude covering all the cities in the world ''' from importlib import resources with resources.open_binary('getweather', 'city.json') as f: content = f.read() content1=content.decode('UTF-8') city=pd.DataFrame(json.loads(content1)) table1=city[['id', 'name', 'state', 'country']] # extract id, name, state, state, country result2=[] # extract lon and lat for i in city['coord']: coord={} coord['lon']=i.get('lon') coord['lat']=i.get('lat') result2.append(coord) result2 table2=pd.DataFrame(result2) city_new=pd.concat([table1, table2], axis=1) # combine table1 and table2 return city_new
[docs]def CityCoord(name): ''' Introduction: This functin allows users to input the city name and then return the longitude and latitude of that city. Parameters: name: a city name Output: a tuple (lon, lat) that contains longitude and latitude of a city. Example: >>>CityCorrd('Taglag') (44.98333, 38.450001) ''' city=CityInfo() if name in list(city['name']): for i in range(len(city['id'])): if city.iloc[i,1]==name: lon=city.iloc[i,4] lat=city.iloc[i,5] return lon, lat else: print("No such city! Please check your city name.")
[docs]def CityId(name): ''' Introduction: This function allows users to input the city name and then return the city id of that city. Parameters: name: a city name Output: a city id Example: >>>CityId('Taglag') 3245 ''' city=CityInfo() if name in list(city['name']): for i in range(len(city['name'])): if city.iloc[i,1]==name: return int(city.iloc[i,0]) else: print("No such city! Please check your city name.")
[docs]def CityIds(*args): ''' Introduction: This function allows users to input any number of city names that they want and then return the city ids of these city. Parameters: *args: any number of city names Output: a string that contains the city ids of all the cities that you input Example: >>>CityIds('London','Shanghai','New York') '2643743,1796236,5128638' ''' ids='' for city in args: cityid=str(CityId(city)) if len(ids)==0: ids=cityid else: ids=ids+','+cityid return ids
[docs]def getonecity(api_key, city_name, status='current'): ''' Introduction: This function can return either current weather and air pollution information or the daily forecast data for 7 days. Parameters: api_key: your api key of the Openweather website. You can access your api key by creating an account on this website: https://home.openweathermap.org/api_keys city_name: one city name status:status could be either 'current' or 'forecast'. If status is set to 'current', this function will return the current weather data; otherwise, it will return the forecast weather data. Output: If you set status to 'current', the output is dataset showing the detailed current weather information of the city you chose. If you set status to 'forecast', the output consists of two parts. The first part is a graph showing the maximum, minimum, and day temperature trends and probability of precipitation in 7 days. The second part is a dataset showing the detailed forecast weather information of the city you chose. ''' if status=='current': #get current weather data # Step1:run the 1st GET request to get weather information and check the status of the request import requests from requests.exceptions import HTTPError try: params1 = {'appid':api_key,'q':city_name,'units':'metric'} # 'units=metric' means temperature in Celsius and wind speed in meter/sec. r1=requests.get('https://api.openweathermap.org/data/2.5/weather', params = params1) r1.raise_for_status() except HTTPError as http_err: print(f'HTTP error occurred: {http_err}') except Exception as err: print(f'Other error occurrred: {err}') # Step2:parse the 1st response R1 = r1.json() import pandas as pd result1=pd.DataFrame({'name':R1['name']},index=[0]) #get city name R1_sys=pd.DataFrame(R1['sys'],index=[0]) # get country name result2=R1_sys[['country']] R1_weather=pd.DataFrame(R1['weather']) #get weather discription result3=R1_weather[['description']] R1_main=pd.DataFrame(R1['main'],index=[0]) #get weather data result4=R1_main R1_wind=pd.DataFrame(R1['wind'], index=[0]) # get wind speed result5=R1_wind[['speed']] result6=pd.DataFrame({'visibility':R1['visibility']},index=[0]) #get visibility # Step3: run the 2nd GET request to get air pollution and check the status of the request ## get lon & lat coord=CityCoord(city_name) lon=coord[0] lat=coord[1] ## run the GET request and check the status of the request try: params2 = {'appid':api_key,'lat':lat,'lon':lon} r2 = requests.get('https://api.openweathermap.org/data/2.5/air_pollution', params = params2) r2.raise_for_status() except HTTPError as http_err: print(f'HTTP error occurred: {http_err}') except Exception as err: print(f'Other error occurrred: {err}') #Step4: parse the 2nd response R2 = r2.json() R2_list=pd.DataFrame(R2['list']) result7=[] for i in R2_list['components']: pollution={} pollution['AirPollution_co']=i.get('co') pollution['AirPollution_nh3']=i.get('nh3') pollution['AirPollution_no']=i.get('no') pollution['AirPollution_no2']=i.get('no2') pollution['AirPollution_o3']=i.get('o3') result7.append(pollution) result7=pd.DataFrame(result7) #Step5: combine the columns of result1 to result7 and return a Python object to the user of the function dataset1=pd.concat([result1,result2,result3,result4,result5,result6,result7], axis=1) dataset1.rename(columns={'speed':'wind_speed'}, inplace = True) return dataset1 elif status=='forecast': # Daily forecast for 7 days # Step1:run the 3rd GET request to get forecast temperature and check the status of the request ## get lon & lat coord=CityCoord(city_name) lon=coord[0] lat=coord[1] ## run the GET request and check the status of the request import requests from requests.exceptions import HTTPError try: params3 = {'appid':api_key,'lat':lat,'lon':lon, 'exclude':'current,minutely,hourly','units':'metric'} # 'current,minutely,hourly' There is no whitespace between current, minutely, and hourly. r3 = requests.get('https://api.openweathermap.org/data/2.5/onecall', params = params3) r3.raise_for_status() except HTTPError as http_err: print(f'HTTP error occurred: {http_err}') except Exception as err: print(f'Other error occurrred: {err}') #Step2: parse the 3rd response import pandas as pd R3 = r3.json() R3_daily = pd.DataFrame(R3['daily']) R3_daily['date']='' ## convert timestamp to normal time import time for i in range(len(R3_daily['dt'])): R3_daily.iloc[i,15]=time.strftime("%Y-%m-%d",time.localtime(R3_daily.iloc[i,0])) R3_daily_temp=pd.DataFrame(dict(R3_daily['temp'])) # get temperature data R3_daily_tempT = pd.DataFrame(R3_daily_temp.values.T, index=R3_daily_temp.columns, columns=R3_daily_temp.index) # transpose R3_daily_temp R3_daily_tempT['date']='' # add 'date' column for i in range(len(R3_daily_tempT['day'])): R3_daily_tempT.iloc[i,6]=R3_daily.iloc[i,15] R3_daily_pop=pd.DataFrame(R3_daily['pop']) # Probability of precipitation y_bar=R3_daily['pop'] # Step3: concat and return a Python object to the user of the function dataset2=pd.concat([R3_daily_tempT,R3_daily_pop], axis=1) dataset2.rename(columns={'day':'day_temperature','min':'min_temperature','max':'max_temperature','night':'night_temperature','eve':'evening_temperature','morn':'morning_temperature','pop':'Probability_of_precipitation'}, inplace = True) dataset2.set_index(['date'], inplace=True) #Step4: draw a graph from matplotlib import pyplot import matplotlib.pyplot as plt x=dataset2.index y_min=R3_daily_tempT['min'] y_max=R3_daily_tempT['max'] y_day=R3_daily_tempT['day'] fig, ax1 = plt.subplots() ax1.plot(x, y_min, color='green', marker='o',label='minimum temperature') ax1.plot(x, y_max, color='red', marker='*',label='maximum temperature') ax1.plot(x, y_day, color='orange', marker="x",label='day temperature') ax1.set_xlabel('day') ax1.set_ylabel("temperature\u2103") plt.legend() # to show the label ax2 = ax1.twinx() #use same x axis with the first plot ax2.bar(x, y_bar,alpha=0.3) ax2.set_ylabel('Probability of precipitation', color='b') plt.title('Daily forecast for 7 days') # rotate the xticklabels for label in ax1.get_xticklabels(): label.set_rotation(70) import os # automatically save picture in working directory path1=os.getcwd() path2='dailyforecast.jpg' path = os.path.join(path1,path2) plt.savefig(path) plt.show() return dataset2 else: print('No such status. Please input either "current" or "forecast".')
[docs]def getcities(api_key, *city_name): ''' Introduction: This is a functio aims to return current weather data for any number of cities you want. Parameters: api_key: your api key of the Openweather website. You can access your api key by creating an account on this website: https://home.openweathermap.org/api_keys *city_name: any number of city names Output: The first part is a bar chart showing the current temperatures of all the cities you chose. The second part is a dataset showing the detailed current weather information of all the cities you chose. ''' # Step1:get city ids ids=CityIds(*city_name) # Step2:run the GET request and check the status of the request import requests from requests.exceptions import HTTPError try: params4 = {'appid':api_key, 'id':ids, 'units':'metric'} r4 = requests.get('https://api.openweathermap.org/data/2.5/group', params = params4) r4.raise_for_status() except HTTPError as http_err: print(f'HTTP error occurred: {http_err}') except Exception as err: print(f'Other error occurrred: {err}') # Step3: parse the response R4 = r4.json() R4_list = pd.DataFrame(R4['list']) result1= R4_list['name'] # City name result1_df=pd.DataFrame(result1) result2=[] # Country name for i in R4_list['sys']: country={} country['country']=i.get('country') result2.append(country) result2 result2_df=pd.DataFrame(result2) result3=[] # Temperature data for main in R4_list['main']: temperature={} temperature['temp']=main.get('temp') temperature['feels_like']=main.get('feels_like') temperature['humidity']=main.get('humidity') temperature['temp_min']=main.get('temp_min') temperature['temp_max']=main.get('temp_max') temperature['pressure']=main.get('pressure') result3.append(temperature) result3 result3_df=pd.DataFrame(result3) result4=[] # wind speed data for i in R4_list['wind']: wind={} wind['wind speed']=i.get('speed') result4.append(wind) result4 result4_df=pd.DataFrame(result4) # Step4: combine the columns of result1 to result4 and return a Python object to the user of the function dataset3=pd.concat([result1_df,result2_df,result3_df,result4_df], axis=1) #Step5:draw a graph from matplotlib import pyplot import matplotlib.pyplot as plt x=dataset3['name'] y=dataset3['temp'] ylabel=[str(y1)+'\u2103' for y1 in y] plt.bar(x, y, alpha=0.3, width=0.1) plt.ylabel('temperature\u2103') for a, b, label in zip(x,y,ylabel): plt.text(a,b,label, ha='center', va='bottom') plt.title('Current Temperature') import os # automatically save picture in working directory path1=os.getcwd() path2='currenttemp.jpg' path = os.path.join(path1,path2) plt.savefig(path) return dataset3
[docs]def getcitycircle(api_key, city_name, cnt=10): ''' Introduction: This function aims to return weather data from cities laid within definite circle that is specified by center point(city that you input) and expected number of cities around this point. Parameters: api_key: your api key of the Openweather website. You can access your api key by creating an account on this website: https://home.openweathermap.org/api_keys city_name: one city name cnt: the number of cities around the center point. The default value is 10. Outputs: The output is a dataframe showing the detailed current weather information of all the cities laid withini a definite circle. ''' #Step1: get city's lon and lat coord=CityCoord(city_name) lon=coord[0] lat=coord[1] #Step2: run the GET request and check the status of the request import requests from requests.exceptions import HTTPError try: params5 = {'appid':api_key,'lat':lat,'lon':lon,'cnt':cnt, 'units':'metric'} r5 = requests.get('https://api.openweathermap.org/data/2.5/find', params = params5) r5.raise_for_status() except HTTPError as http_err: print(f'HTTP error occurred: {http_err}') except Exception as err: print(f'Other error occurred: {err}') # Step3:parse the response and return a Python object to the user of the function R5 = r5.json() import pandas as pd R5_list = pd.DataFrame(R5['list']) result1= R5_list['name'] # city name result1_df=pd.DataFrame(result1) result2=[] # Country name for i in R5_list['sys']: country={} country['country']=i.get('country') result2.append(country) result2_df=pd.DataFrame(result2) result3=[] # Temperature data for i in R5_list['main']: temperature={} temperature['temp']=i.get('temp') temperature['feels_like']=i.get('feels_like') temperature['humidity']=i.get('humidity') temperature['temp_min']=i.get('temp_min') temperature['temp_max']=i.get('temp_max') temperature['pressure']=i.get('pressure') result3.append(temperature) result3_df=pd.DataFrame(result3) result4=[] # wind speed data for i in R5_list['wind']: wind={} wind['wind speed']=i.get('speed') result4.append(wind) result4_df=pd.DataFrame(result4) weather=pd.DataFrame(dict(R5_list['weather'])) # weather description result5=[] for i in range(len(R5_list['weather'])): description={} description['description']=weather.iloc[0,i].get('description') result5.append(description) result5_df=pd.DataFrame(result5) # combine the columns of result1 to result5 dataset=pd.concat([result1_df,result2_df,result3_df,result4_df,result5_df], axis=1) return dataset