C# C# Streams and Data Processing Parsing Data Working with DateTime

index out of bounds

I had a problem on the 3rd task of the challenge when parsing the datetime. if I say values[0] it says to use values[1] but when I use values[1] it says index out of bounds exeption

Program.cs
using System;
using System.IO;

namespace Treehouse.CodeChallenges
{
    public class Program
    {
        public static WeatherForecast ParseWeatherForecast(string[] values) {
            WeatherForecast weatherForecast = new WeatherForecast();

            using (var reader = new StreamReader("WeatherForecast.cs")) {
                string line = "";
                reader.ReadLine();
                while((line = reader.ReadLine()) != null) {

                    values = line.Split(',');
                    DateTime timeOfDay;
                    if(DateTime.TryParse(values[0], out timeOfDay)) {
                        weatherForecast.TimeOfDay = timeOfDay;
                    }

                    string stationID = "HGKL8Q";
                    if(values[0] == stationID) {
                        weatherForecast.WeatherStationId = stationID;
                    }


                }
            }
            Console.WriteLine(weatherForecast.WeatherStationId);

            return weatherForecast;
        }

        public static void Main(string[] arg)
        {
        }
    }
}
WeatherForecast.cs
using System;

/* Sample CSV Data 

weather_station_id,time_of_day,condition,temperature,precipitation_chance,precipitation_amount
HGKL8Q,06/11/2016 0:00,Rain,53,0.3,0.03
HGKL8Q,06/11/2016 6:00,Cloudy,56,0.08,0.01
HGKL8Q,06/11/2016 12:00,PartlyCloudy,70,0,0
HGKL8Q,06/11/2016 18:00,Sunny,76,0,0
HGKL8Q,06/11/2016 19:00,Clear,74,0,0
*/

namespace Treehouse.CodeChallenges
{
    public class WeatherForecast
    {
        public string WeatherStationId { get; set; }
        public DateTime TimeOfDay { get; set; }
    }
}

3 Answers

Tim Strand
Tim Strand
22,345 Points

couple things: 1) your while loop is setting line = reader.readLine() instead of checking for equality == 2) you are passed an array of values (try Console.WriteLine(values)) 3) there is no need to loop the values because you are returning a single item. if you were returning an array of items then you would need a loop. As it is just instantiate your WeatherForecast and then set the station id. Then tryParse your timeOfDay and set that property if its parsed. 4) you are resetting values (passed in string[]) to line.split(',') which returns a 1 item array (you will see why in your console preview) resulting in your out of bounds. Rule of thumb would be dont reset a passed in variable within the method.

andren
andren
28,360 Points

While most of your points are valid I feel I need to point out that the first correction:

1) your while loop is setting line = reader.readLine() instead of checking for equality ==

Is a bit misguided. While it is not common to assign values within conditions it is a valid thing to do, and in this case was in fact intentional.

The point of while loops of the style shown in the code above is to read the file one line at a time and then to stop when it has reached the end. It does this by assigning reader.readLine() to line at the start of each loop and then checking that it does not equal null after that assignment. If it does the loop stops, if it does not the loop runs again, but with line now having a new value since it was reassigned as part of the conditional check. Combining the assignment and null checking into the condition in this way is pretty common when reading files (it is what the teacher does in previous videos), it can also be useful in other situations but is not used that commonly due to the fact that it can indeed look like a mistake if you don't analyze the code first.

andren
andren
28,360 Points

You seem to have misunderstood a pretty fundamental part of the challenge. In this challenge you don't need to (and are not supposed to) use the StreamReader to read and parse any file. The CSV Data shown in WeatherForecast.cs is just there to give you an idea of the type of data you will receive. The actual data is sent in to the method through the values parameter that the method has. In your code you override the passed in data with your own custom one. A parameter whose value is never actually used before it is reassigned is useless, and often a sign that something is off in your code.

Also you only receive the values for one WeatherForecast (which is why the method is setup to return only one, rather than an array) so looping over the data is not needed. To be honest your code should not have passed the first task, and it doing so is likely just a quirk in how the challenge checker verified your code. If you remove your parsing and looping code and just leave the basic assignments like this:

using System;

namespace Treehouse.CodeChallenges
{
    public class Program
    {
        public static WeatherForecast ParseWeatherForecast(string[] values) {
            WeatherForecast weatherForecast = new WeatherForecast();
            weatherForecast.WeatherStationId = values[0];
            DateTime timeOfDay;
            if(DateTime.TryParse(values[1], out timeOfDay)) {
                weatherForecast.TimeOfDay = timeOfDay;
            }
            return weatherForecast;
        }

        public static void Main(string[] arg)
        {
        }
    }
}

Then your code will pass.

Thanks these helped a lot!