using System.Collections.Generic;
using System.Threading.Tasks;
public static void Main(string[] args)
List<Location> locations = GetLocations();
SetForecastsAsync(locations).GetAwaiter().GetResult();
locations.ForEach(x => x.Forecasts.RemoveAll(y => y.Date <= DateTime.Today || y.Date > DateTime.Today.AddDays(5)));
OutputResults(locations);
Console.WriteLine(ex.Message);
private static List<Location> GetLocations()
return new List<Location>
new Location{ City = "Marlboro", State = "MA", ZIPCode = "01752", Forecasts = new List<Forecast>() },
new Location{ City = "San Diego", State = "CA", ZIPCode = "92101", Forecasts = new List<Forecast>() },
new Location{ City = "Cheyenne", State = "WY", ZIPCode = "82001", Forecasts = new List<Forecast>() },
new Location{ City = "Anchorage", State = "AK", ZIPCode = "99501", Forecasts = new List<Forecast>() },
new Location{ City = "Austin", State = "TX", ZIPCode = "73301", Forecasts = new List<Forecast>() },
new Location{ City = "Orlando", State = "FL", ZIPCode = "32801", Forecasts = new List<Forecast>() },
new Location{ City = "Seattle", State = "WA", ZIPCode = "98101", Forecasts = new List<Forecast>() },
new Location{ City = "Cleveland", State = "OH", ZIPCode = "44101", Forecasts = new List<Forecast>() },
new Location{ City = "Portland", State = "ME", ZIPCode = "04101", Forecasts = new List<Forecast>() },
new Location{ City = "Honolulu", State = "HI", ZIPCode = "96801", Forecasts = new List<Forecast>() }
private async static Task SetForecastsAsync(List<Location> locations)
List<Task> forecastTasks = new List<Task>();
foreach (Location location in locations)
Task task = SetForecastAsync(location);
await Task.WhenAll(forecastTasks);
private static async Task SetForecastAsync(Location location)
string url = GetWeatherApiUrl(location.ZIPCode);
using (HttpClient client = GetHttpClient())
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
if (!response.IsSuccessStatusCode) return;
string result = await response.Content.ReadAsStringAsync();
ForecastResponse forecastResponse = JsonConvert.DeserializeObject<ForecastResponse>(result, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore, NullValueHandling = NullValueHandling.Ignore });
forecastResponse.Forecasts.RemoveAll(x => !DateTime.TryParse(x.ForecastDateTime, out date));
forecastResponse.Forecasts.RemoveAll(x => !double.TryParse(x.Main.Temperature, out temperature));
var forecasts = forecastResponse.Forecasts.ToLookup(x => DateTime.Parse(x.ForecastDateTime).Date).Select(x => x).ToList();
foreach (var forecast in forecasts)
double averageTemperature = forecast.Average(x => double.Parse(x.Main.Temperature));
bool precipitation = forecast.Any(x => x.Rain != null || x.Snow != null);
location.Forecasts.Add(new Forecast { Date = forecast.Key, AverageTemperature = averageTemperature, PrecipitationExpected = precipitation });
Console.WriteLine(ex.Message);
private static void OutputResults(List<Location> locations)
foreach (Location location in locations)
Console.WriteLine("______________________________");
Console.WriteLine(location.City + ", " + location.State + " (" + location.ZIPCode + ")");
if (!location.Forecasts.Any())
Console.WriteLine("Unable to retrieve forecast data.");
Console.WriteLine("Date" + '\t' + '\t' + "Avg Temp(F)");
Console.WriteLine("------------------------------");
foreach (Forecast forecast in location.Forecasts)
Console.WriteLine(forecast.Date.ToShortDateString() + (forecast.PrecipitationExpected ? "*" : "") + '\t' + forecast.AverageTemperature.ToString("N2") + " F");
private static HttpClient GetHttpClient()
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
private static string GetWeatherApiUrl(string ZIPCode)
return "https://api.openweathermap.org/data/2.5/forecast?APPID=18d9276a9325e3147ac2996320fa24f8&units=Imperial&zip=" + ZIPCode;
Console.WriteLine(ex.Message);
public string City { get; set; }
public string State { get; set; }
public string ZIPCode { get; set; }
public List<Forecast> Forecasts { get; set; }
public DateTime Date { get; set; }
public double AverageTemperature { get; set; }
public bool PrecipitationExpected { get; set; }
public string Cod { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
public string NumberOfDays { get; set; }
public List<Forecast> Forecasts { get; set; }
public CityData City { get; set; }
public string Temperature { get; set; }
[JsonProperty("temp_min")]
public string MinimumTemperature { get; set; }
[JsonProperty("temp_max")]
public string MaximumTemperature { get; set; }
[JsonProperty("pressure")]
public string Pressure { get; set; }
[JsonProperty("sea_level")]
public string SeaLevel { get; set; }
[JsonProperty("grnd_level")]
public string GroundLevel { get; set; }
[JsonProperty("humidity")]
public string Humidity { get; set; }
[JsonProperty("temp_kf")]
public string KFTemperature { get; set; }
public string Id { get; set; }
public string Main { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
public string Icon { get; set; }
public string Cloudiness { get; set; }
public string Speed { get; set; }
public string WindDirection { get; set; }
public class Precipitation
public string VolumeForLast3Hours { get; set; }
public string Pod { get; set; }
public string ForecastTime { get; set; }
public Main Main { get; set; }
[JsonProperty("weather")]
public List<Weather> Weather { get; set; }
public Clouds Clouds { get; set; }
public Wind Wind { get; set; }
public Precipitation Rain { get; set; }
public Precipitation Snow { get; set; }
public Sys Sys { get; set; }
public string ForecastDateTime { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string Name { get; set; }
public Coordinates Coordinates { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("timezone")]
public string TimeZone { get; set; }
[JsonProperty("sunrise")]
public string Sunrise { get; set; }
public string Sunset { get; set; }