patterncsharpMinor
Weather forecast printing
Viewed 0 times
forecastprintingweather
Problem
I receive a weather forecast for 5 days, but in 3 hours intervals.
This classes represent the weather forecast:
This method prints the forecast:
```
static void PrintForecast(Forecast forecast, int days)
{
days = days > 5 ? 5 : days;
DateTime printDate = DateTime.Now.Date;
for (int i = 0; i weatherTimePoint.TimePoint.Date == printDate);
for(int hour = 6; hour weatherTimePoint.TimePoint.Hour == hour);
if (weatherAtHour != null)
{
ChangeColor(ConsoleColor.DarkCyan);
Console.Write("{0}/", hour);
ChangeColor(ConsoleColor.DarkGreen);
Console.Write("{0}({1})/",weatherAtHour.Weather[0].Condition, weatherAtHour.Weather[0].Description);
ChangeColor(ConsoleColor.Red);
Console.Write("{0}{1}",weatherAtHour.ClimaticData.Temperature, UnitsHelper.GetUnit(forecast.Units, UnitsHelper.WeatherField.Temperature));
Console.WriteLine();
}
}
ChangeColor(ConsoleColor.White);
Console.WriteLine("Average humidity:{0}%", timePointsDuringtDay.Average((weatherTimePoint) => weatherTimePoint.ClimaticData.Humidity));
Console.WriteLine("Average pressure:{0} hPa", timePointsDuringtDa
This classes represent the weather forecast:
public class Forecast : ILocation
{
[JsonIgnore()]
public string City { get; set; }
[JsonIgnore()]
public string Country { get; set; }
[JsonProperty("list")]
public IList TimePoints { get; set; }
}
public class WeatherTimePoint
{
[JsonProperty("dt")]
[JsonConverter(typeof(UnixTimeStampConverter))]
public DateTime TimePoint { get; set; }
[JsonProperty("main")]
public ClimaticData ClimaticData { get; set; }
[JsonProperty("weather")]
public IList Weather { get; set; }
[JsonProperty("wind")]
public Wind Wind { get; set; }
[JsonIgnore()]
public Units Units { get; set; }
}This method prints the forecast:
```
static void PrintForecast(Forecast forecast, int days)
{
days = days > 5 ? 5 : days;
DateTime printDate = DateTime.Now.Date;
for (int i = 0; i weatherTimePoint.TimePoint.Date == printDate);
for(int hour = 6; hour weatherTimePoint.TimePoint.Hour == hour);
if (weatherAtHour != null)
{
ChangeColor(ConsoleColor.DarkCyan);
Console.Write("{0}/", hour);
ChangeColor(ConsoleColor.DarkGreen);
Console.Write("{0}({1})/",weatherAtHour.Weather[0].Condition, weatherAtHour.Weather[0].Description);
ChangeColor(ConsoleColor.Red);
Console.Write("{0}{1}",weatherAtHour.ClimaticData.Temperature, UnitsHelper.GetUnit(forecast.Units, UnitsHelper.WeatherField.Temperature));
Console.WriteLine();
}
}
ChangeColor(ConsoleColor.White);
Console.WriteLine("Average humidity:{0}%", timePointsDuringtDay.Average((weatherTimePoint) => weatherTimePoint.ClimaticData.Humidity));
Console.WriteLine("Average pressure:{0} hPa", timePointsDuringtDa
Solution
To save a few lines create a
Then assign each style a color:
Use overloading to encapsulate the styling logic like this:
I think it's a good idea to stick to the
Then you can turn this:
into:
You can go even further and create a special method called
This way your printing becomes even cleaner and you can manipulate the header separately.
The same applies for other cases.
I would remove the helper above the loop and write:
Magic numbers
You should replace all those
make it
to reduce nesting.
I would encapsulate this logic in a method like this:
Then in your weather print you can use link with ease:
Style enum first:enum Style
{
Header,
Hour,
Condition,
Temperature
}Then assign each style a color:
static Dictionary _styles = new Dictionary
{
[Style.Header] = ConsoleColor.Magenta,
...
}Use overloading to encapsulate the styling logic like this:
private static void Print(Style style, string format, params object[] args)
{
Console.ForegroundColor = _styles[style];
Console.Write(format, args);
Console.ResetColor();
}
private static void PrintLine(Style style, string format, params object[] args)
{
Print(style, format, args);
Console.WriteLine();
}I think it's a good idea to stick to the
Print & PrintLine convention like the console does it.Then you can turn this:
ChangeColor(ConsoleColor.Magenta);
Console.WriteLine("== Day {0} ==", printDate.ToLongDateString());into:
Print(Style.Header, "== Day {0} ==", printDate.ToLongDateString());You can go even further and create a special method called
PrintHeader and do all the magic there like so:PrintHeader(printDate)
{
Print(Style.Header, "== Day {0} ==", printDate.ToLongDateString());
}This way your printing becomes even cleaner and you can manipulate the header separately.
The same applies for other cases.
DateTime printDate = DateTime.Now.Date;
for (int i = 0; i < days; i++)
{
printDate = printDate.AddDays(1);
...
}I would remove the helper above the loop and write:
for (int i = 0; i < days; i++)
{
var printDate = DateTime.Now.Date.AddDays(i + 1);
...
}Magic numbers
You should replace all those
5, 6, 21 etc with constants and give them proper names. I have no idea what they mean. You in few week will wonder too why such numbers.if (weatherAtHour != null) {
}make it
if (weatherAtHour == null) { continue; }to reduce nesting.
for (int hour = 6; hour <= 21; hour = hour + 3)I would encapsulate this logic in a method like this:
private static IEnumerable Hours()
{
for (int hour = 6; hour <= 21; hour = hour + 3)
{
yield return hour;
}
}Then in your weather print you can use link with ease:
var weathersAtHour =
Hours()
.Select(hour => timePointsDuringtDay.SingleOrDefault(weatherTimePoint => weatherTimePoint.TimePoint.Hour == hour))
.Where(x => x != null);
foreach (var weatherAtHour in weathersAtHour)
{
...
}Code Snippets
enum Style
{
Header,
Hour,
Condition,
Temperature
}static Dictionary<Style, ConsoleColor> _styles = new Dictionary<Style, ConsoleColor>
{
[Style.Header] = ConsoleColor.Magenta,
...
}private static void Print(Style style, string format, params object[] args)
{
Console.ForegroundColor = _styles[style];
Console.Write(format, args);
Console.ResetColor();
}
private static void PrintLine(Style style, string format, params object[] args)
{
Print(style, format, args);
Console.WriteLine();
}ChangeColor(ConsoleColor.Magenta);
Console.WriteLine("== Day {0} ==", printDate.ToLongDateString());Print(Style.Header, "== Day {0} ==", printDate.ToLongDateString());Context
StackExchange Code Review Q#140069, answer score: 2
Revisions (0)
No revisions yet.