Lab is ready
This commit is contained in:
21
weather/weather.py
Normal file
21
weather/weather.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from weather.weather_apis import (
|
||||
geocode_location,
|
||||
geocode_ip_address,
|
||||
get_weather_office,
|
||||
get_forecast
|
||||
)
|
||||
|
||||
def print_weather(location=None, metric=False, verbose=False):
|
||||
"""Prints out a weather report using the provided location, or using
|
||||
the user's current location if no location was provided.
|
||||
When metric is True, prints out the weather in metric units.
|
||||
When verbose is True, prints out a more detailed report.
|
||||
"""
|
||||
print("Not finished...") # YOUR CODE HERE!
|
||||
|
||||
# This is a clunky way to check whether this module was called directly with `python weather.py`,
|
||||
# or whether it's being imported by another module. If the module is being called, then we
|
||||
# should actually run `print_weather`. But if this module is just being imported, we probably don't
|
||||
# want this module to call any functions. We'll leave that up whoever is doing the importing.
|
||||
if __name__ == "__main__":
|
||||
print_weather()
|
80
weather/weather_apis.py
Normal file
80
weather/weather_apis.py
Normal file
@@ -0,0 +1,80 @@
|
||||
# Weather APIs
|
||||
|
||||
# This module contains functions which interact with external APIs related to weather.
|
||||
# The module relies on USA-specific services; it will need to be extended using local
|
||||
# services for other regions.
|
||||
|
||||
# The National Weather Service (NWS) provides weather forecasting services across US
|
||||
# states and territories. NWS divides the country into a grid of 2.5km squares, and
|
||||
# provides a forecast for each grid square.
|
||||
|
||||
import geocoder
|
||||
import requests
|
||||
|
||||
def geocode_location(location_string):
|
||||
"""Translates a location string into latitude and longitude coordinates.
|
||||
Uses the OpenStreetMap API. Returns a dict with keys 'lat' and 'lng'
|
||||
as shown below. When no result is found, returns None.
|
||||
|
||||
>>> geocode_location('11 Wall Street, New York')
|
||||
{"lat": -74.010865, "lng": 40.7071407}
|
||||
"""
|
||||
result = geocoder.osm(location_string)
|
||||
if result:
|
||||
lat, lng = result.latlng
|
||||
return {'lat': lat, 'lng': lng}
|
||||
|
||||
def geocode_ip_address(ip_address=None):
|
||||
"""Translates an IP address into latitude and longitude coodrdinates.
|
||||
When no IP address is provided, uses the user's current IP address.
|
||||
|
||||
>>> geocode_ip_address()
|
||||
{'lat': 23.6585116, 'lng': -102.0077097}
|
||||
"""
|
||||
result = geocoder.ip(ip_address or 'me')
|
||||
if result:
|
||||
lat, lng = result.latlng
|
||||
return {'lat': lat, 'lng': lng}
|
||||
|
||||
def get_weather_office(lat, lng):
|
||||
"""Looks up the NWS weather office for a pair of lat/lng coordinates.
|
||||
Returns a dict containing keys 'office', 'x', and 'y'.
|
||||
If no matching weather office is found, returns None.
|
||||
|
||||
>>> coords = geocode_ip_address()
|
||||
>>> get_weather_office(coords['lat'], coords['lng'])
|
||||
{'office': 'BUF', 'x': 39, 'y': 59}
|
||||
"""
|
||||
url = "https://api.weather.gov/points/{},{}".format(lat, lng)
|
||||
response = requests.get(url)
|
||||
if response.ok:
|
||||
result = response.json()
|
||||
return {
|
||||
"office": result['properties']['gridId'],
|
||||
"x": result['properties']['gridX'],
|
||||
'y': result['properties']['gridY']
|
||||
}
|
||||
|
||||
def get_forecast(office, x, y, metric=False):
|
||||
"""Fetches the weather forecast for the given NWS office, and (x, y) NWS grid tile.
|
||||
Returns a list of time periods, where each time period is a dict containing keys
|
||||
as shown below. If no forecast can be found, returns None.
|
||||
When metric is True, returns temperatures in Celcius and wind speeds in km/hr.
|
||||
|
||||
"""
|
||||
url = "https://api.weather.gov/gridpoints/{}/{},{}/forecast".format(office, x, y)
|
||||
if metric:
|
||||
url += "?units=si"
|
||||
response = requests.get(url)
|
||||
if response.ok:
|
||||
result = response.json()
|
||||
forecast = []
|
||||
for period in result['properties']['periods']:
|
||||
forecast.append({
|
||||
'name': period['name'],
|
||||
'temperature': period['temperature'],
|
||||
'wind_speed': period['windSpeed'],
|
||||
'wind_direction': period['windDirection'],
|
||||
'description': period['shortForecast'],
|
||||
})
|
||||
return forecast
|
15
weather/weather_cli.py
Normal file
15
weather/weather_cli.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from argparse import ArgumentParser
|
||||
from weather.weather import print_weather
|
||||
|
||||
def weather_cli():
|
||||
"""Provides a command-line interface for weather.
|
||||
This function creates an ArgumentParser, which parses command line arguments.
|
||||
Then it calls `print_weather` with the provided arguments.
|
||||
"""
|
||||
parser = ArgumentParser("weather", description="Prints out a weather report")
|
||||
parser.add_argument("-l", "--location", help="Location for weather forecast")
|
||||
parser.add_argument("-m", "--metric", action="store_true", help="Use metric units")
|
||||
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
|
||||
args = parser.parse_args()
|
||||
print_weather(location=args.location, metric=args.metric, verbose=args.verbose)
|
||||
|
Reference in New Issue
Block a user