Code Kata 4 Part 3 Once More with Feeling

If you followed along on my Code Kata 4 journey, you know I messed this one up bad. I mean real bad. Well, I got some programming reps in and that is always good. Yesterday, I played in the land of make believe that I had not messed up. As a result, I got the Soccer thing setup in less than 20 minutes. So that solved Code Kata 4 Part 2. With that we continue in the land of make believe and do Code Kata 4 Part 3. Only this time we are going to have some feeling.

So, it is exactly the same as the combined one from the other day?

Nope, I followed the spirit of the kata and instead of building a generic machine that could handle an unknown file. I did what it wanted me to do. Strip out the common code and bring it together.

So let’s take a look at the weather and soccer problems with their new button click events.

btnCombineWeather_Click

private void btnCombineWeather_Click(object sender, EventArgs e)
        {
            lbResults.Items.Clear();
 
            foreach (List<string> i in getData(txtWeatherPath.Text))
            {
                if(i.Count > 3)
                {
                    lbResults.Items.Add(i[0] + "\t" + i[1] + " \t" + i[2]);
                }
            }
        }

btnCombineSoccer_Click

private void btnCombineSoccer_Click(object sender, EventArgs e)
       {
           int smallest = 10000;
           lbResults.Items.Clear();
           foreach (List<string> i in getData(txtSoccerPath.Text))
           {
               if (i.Count > 9)
               {
                   lbResults.Items.Add(i[6] + " \t" + i[8]);
                   if(int.Parse(i[6]) - int.Parse(i[8]) < smallest)
                   {
                       smallest = int.Parse(i[6]) - int.Parse(i[8]);
                   }
               }
           }
 
           lbResults.Items.Add(smallest);
       }

So, don’t they look close. Actually following the kata made for a much faster process. It took me less than 45 minutes to have this built and tested. There was one minor hiccup. I fixed it by moving the conditional and results adding stuff to the button logic and returning a list of list of strings that contained the whole cleaned up file.

Let’s walk through the weather process.

  • Clear Results listbox of any previous results.
  • Get the data form the weather.dat file and take each list of strings…
  • To check if the list has more than 3 items since we are going to access the first 3 items
  • If it does then add it to the results listbox with the proper format.

So let’s look at the soccer process.

  • Declare a smallest integer with a really big number. This is an m value in my Production Operations Management class.
  • Clear out the previous result set.
  • Get the data from the soccer.dat file and take each list of strings…
  • To check if it has 9 elements in the list.
  • If yes execute my throw away line that populates the value pair in the results listbox.
  • Finally a if statement to check if the two value’s difference is smaller than the current small value.
  • If yes then set the smallest value
  • After all that, display the smallest variable in the results listbox.

So we have each click pretty clean. The code is still similar but I think trying to squeeze any more de-duplication will make it hard to understand and oddly enough probably add more code. Let’s not go down the path of make a generic column header reading thingy. So we have the input and output handled, what about the actual data pull.

getData

private List<List<string>> getData(string path, List<char>illegalCharacters = null)
       {
           List<string> cleanLine = new List<string>();
           List<List<string>> dataset = new List<List<string>>();
           
           bool lineHasillegal;
 
           using (StreamReader reader = new StreamReader(path))
           {
               while (reader.Peek() != -1)
               {
                   cleanLine = new List<string>();
 
                   foreach (string segment in reader.ReadLine().Trim().Split(' '))
                   {
                       lineHasillegal = false;
 
                       if (segment.Trim() != string.Empty)
                       {
                           if(illegalCharacters != null)
                           {
                               foreach (var i in illegalCharacters)
                               {
                                   if (segment.Contains(i))
                                   {
                                       lineHasillegal = true;
                                       break;
                                   }
                               }
                           }
 
                           if (!lineHasillegal)
                           {
                               cleanLine.Add(segment.Trim());
                           }   
                       }
                   }
 
                   dataset.Add(cleanLine);
               }
               return dataset;
           }
       }

Here is the meat and potato part of the code. It is almost contained in one screen on my monitor. This is my gold standard for a function that is short enough. I did not pull any tricks like removing white space or doing any single line if else logic. I stuck with my format and almost got the length requirement so I am happy.

Let’s get into it shall we?

  • Create the cleanLine list
  • Create the very wacky list of list of strings. It is kind of Cyrus the Great of list, right?
  • After that create an illegal character flag.
  • Open the file up using a stream reader
  • Then running a loop until we run out of lines in the file with the Peek function.
  • Clean up any old lines with cleanLine instantiation.
  • Then go into the foreach loop to segment the line of text broken up at space values
  • Make sure the illegal values are set to false for this line
  • Check if the segment we are working with actually has a value and if it does
  • Check if we have any illegal characters list and if we do…
  • Cycle through the illegal character list, which is an optional parameter.
  • If an illegal character is found in the segment, set the illegal flaf to true, break out of the illegal for loop and…
  • Check if the illegal value is false if it is then add to the clean line list. Here is where we end up if the illegal character list was not used.
  • Then take whatever the clean line is and add it to the dataset.
  • When we run out of lines return the dataset.

So where do we go from here on Code Kata 4 Part 3?

Well first, that is it on Code Kata 4 Part 3. This post has gotten too long. As a result, I will finish Code Kata 4 tomorrow by looking into the questions. This will also allow all the temporal problems to come back together so we can evaluate the good, the bad and the ugly of Code Kata 4.

Leave a Reply

Your email address will not be published.