Advertisement
bhalash

players.csv parser

Apr 23rd, 2012
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.25 KB | None | 0 0
  1. /*
  2.     Author: Mark Grealish (s00123474@itsligo.ie)
  3.     Description: A simple CSV parser and viewer.
  4.     Date: Eh, today.
  5.    
  6.     Attribution:
  7.     The player data is that of my World of Warcraft guild because I never grabbed the sample file.
  8.     It was scraped from the World of Warcraft Armory website:
  9.     http://us.battle.net/wow/en/guild/arthas/Def%C3%ADant/
  10. */
  11.  
  12. using System;
  13. using System.IO;
  14. using System.Collections.Generic;
  15.  
  16. public class CsvReader
  17. {  
  18.     //
  19.     // ++++GLOBAL VARIABLES++++
  20.     //
  21.        
  22.     // I go in the door with a null value because I use this as a check elsewhere.
  23.     public static string path = "players.csv";
  24.     public static bool debug = false;
  25.  
  26.     static void Main()
  27.     {  
  28.         //
  29.         // ++++MAIN MENU++++
  30.         //
  31.         int n = 42;
  32.        
  33.         do
  34.         {
  35.             Console.Clear();
  36.             // Output in option one is limmited! There is a note, below, about this.
  37.             Console.WriteLine("1. View the contents of {0}.", path);
  38.             Console.WriteLine("2. Search for a specific record in {0}.", path);
  39.             Console.WriteLine();
  40.             Console.WriteLine("4. Exit.");
  41.             Console.WriteLine();
  42.             n = IntParse("Selection: ");
  43.            
  44.             switch ( n )
  45.             {
  46.                 case 1:
  47.                     // Putting Console.Clear(); here makes my life easier. Messy, but fuck it.
  48.                     Console.Clear();
  49.                     CsvView( path, -1 );
  50.                     break;
  51.                 case 2:
  52.                     Console.Clear();
  53.                     CsvSearch( path );
  54.                     break;
  55.                 case 4:
  56.                     break;
  57.                 default:
  58.                     break;
  59.             }
  60.         } while ( n != 4 );
  61.     }
  62.  
  63.     //
  64.     // ++++LOAD CSV FILE++++
  65.     //
  66.    
  67.     private static string[] CsvLoad( string path )
  68.     {  
  69.         /*
  70.         In this method I loop through and read the file twice. This isn't a perfect solution, but eh, it works.
  71.         Update: I looked around, and this actually is a recommended method to return to the top in a simple parser.
  72.         There's an alternate method that involves a list which seems fairly simple to implement, but it's too much
  73.         work right now. /lazy
  74.        
  75.         I counted rows above so the one-dimensional array is the exact size of the file. AKA: MOAR EFFICENCY.
  76.         Back to the topic of efficiency: I want to emulate the Unix/Linux style of file management,
  77.         which is to not lock the file except during read/write. Correspondingly, the only time I open the file
  78.         is when I call this method. This array is then piped to wherever it is needed.
  79.         */
  80.        
  81.         // Count rows. Start with row 1.
  82.         int row = 0;
  83.         StreamReader count = new StreamReader( path );
  84.         string line = "";
  85.        
  86.         while ( line != null )
  87.         {
  88.             row++;
  89.             line = count.ReadLine();
  90.         }
  91.        
  92.         count.Close();
  93.  
  94.         // The array for the data.
  95.         string[] csvData = new string[row];
  96.        
  97.         // Fill up the array.
  98.         StreamReader data = new StreamReader( path );
  99.         int n = 0;
  100.        
  101.         while ( n < row )
  102.         {
  103.             csvData[n] = line;
  104.             line = data.ReadLine();
  105.             n++;
  106.         }
  107.                    
  108.         return csvData;
  109.     }  
  110.    
  111.     //
  112.     // ++++VIEW CSV FILE+++
  113.     //
  114.    
  115.     static void CsvView( string path, int rec )
  116.     {
  117.         /*
  118.         This method takes the record and actually handles the output. The default value is "-1". If it is -1, the
  119.         entire array will be output. If it is any other number <= csv.Length, then only that given record will
  120.         be displayed.
  121.         */
  122.         Console.Clear();
  123.        
  124.         // 1. Grab the array containing the CSV data.
  125.         string[] csv = CsvLoad( path );
  126.         // 2. Put the first line into a string.
  127.         string line = csv[1];
  128.         // 3. Split that line into an array.
  129.         string[] field = line.Split( ',' );
  130.         // 4. Use the above arrays to output the respective rows and fields of the array.
  131.         // int rows = 20;
  132.         int rows = csv.Length;
  133.         // There was a note above about this: In the above line I demonstrate my ability to output the entire array.       
  134.         // However, I limit the display to ten records for ease of life when debugging this program.
  135.         int cols = field.Length;
  136.         // Table format.
  137.         string tFormat = "{0,-15}";
  138.         string hFormat = "{0,-15}{1,-15}{2,-15}{3,-15}";
  139.         // A spot of sanity checking during debugging.     
  140.         // Console.WriteLine( csv.Length );
  141.         // Console.WriteLine( field.Length );
  142.         // Console.WriteLine();
  143.  
  144.         // Probably worth a few points to untangle this mess:
  145.         // 1. Output the line header ("Player, ...") in one go.
  146.         // 2. Output the line break once per column.
  147.         // 3. Double loop: Once per line, output each field from that line, as Split().
  148.         // 4. Following on from 3., output the user's citation once per line, per their score.
  149.  
  150.         Console.WriteLine( String.Format (hFormat, "Player #:", "Name:", "Score:", "Citation:" ));
  151.        
  152.         // Remove the equals for three columns instead of four.
  153.         for ( int i = 0; i <= cols; i++ )
  154.             Console.Write(String.Format( tFormat, "----------" ));
  155.            
  156.         Console.WriteLine();   
  157.                
  158.         // The quote unquote main event:
  159.         // Seriously, this segment made more sense when I was rancidly drunk.
  160.         if ( rec < 0 )
  161.         {
  162.             for ( int i = 1; i < rows; i++ )
  163.             {
  164.                 line = csv[i];
  165.                 field = line.Split( ',' );
  166.            
  167.                 for ( int j = 0; j < cols; j++ )
  168.                 {
  169.                     Console.Write( String.Format( tFormat, field[j] ));
  170.                 }
  171.            
  172.                 // Totally, totally, *totally* hacked this line in to fit the exercise. Sorry, Vivion.
  173.                 Console.Write( String.Format( tFormat, PlayerCitation(field[2]) )); // <<--Parentheses, oh my!
  174.                 Console.WriteLine();
  175.             }
  176.         }
  177.         else if ( rec > 0 )
  178.         {
  179.             // Blatant copy/paste to avoid a better fix.
  180.             line = csv[rec];
  181.             field = line.Split( ',' );
  182.            
  183.             for ( int j = 0; j < cols; j++ )
  184.             {
  185.                 Console.Write( String.Format( tFormat, field[j] ));
  186.             }
  187.            
  188.             // Totally, totally, *totally* hacked this line in to fit the exercise. Sorry, Vivion.
  189.             Console.Write( String.Format( tFormat, PlayerCitation(field[2]) )); // <<--Parentheses, oh my!
  190.             Console.WriteLine();
  191.         }
  192.        
  193.         // And then home.  
  194.         Back();
  195.     }
  196.    
  197.     //
  198.     // ++++SEARCH++++
  199.     //
  200.    
  201.     static void CsvSearch( string path )
  202.     {
  203.         Console.Clear();
  204.        
  205.         // The example array.
  206.         string[] csv = CsvLoad( path );
  207.        
  208.         // Array elements, spread out for debugging.
  209.    
  210.         // Example string.
  211.         Console.Write( "Enter search string (case sensitive): " );
  212.         string query = Convert.ToString( Console.ReadLine() );
  213.  
  214.         // n serves two purposes:
  215.         // 1.  Loop counter in the loop.
  216.         // 2.  The loop will break at the element containing our string.
  217.         // 2a. After the loops breaks, n will be used to output that element
  218.         int element = 1;
  219.         int sentinel = 0;
  220.        
  221.         try
  222.         {
  223.             do
  224.             {
  225.                 // teh loopage.
  226.                 sentinel = csv[element].IndexOf( query );
  227.                 element++;
  228.                 // IndexOf() changes the value of sentinel to -1 if the item isn't found in the string.
  229.                 // When the string is matched, sentinel becomes 7, and the loop breaks.
  230.                 if ( sentinel >= 0 )
  231.                     break;
  232.             } while ( (element < csv.Length) );
  233.         }
  234.         catch ( IndexOutOfRangeException )
  235.         {
  236.             // The search throws up an error if nothing is matched. I dump the error in here and handle it separately, below.
  237.             // I liken this to a little box filled with screaming monsters. Monsters.
  238.         }
  239.        
  240.         // This is to correct for...unexpected behaviour elsewhere.
  241.         // I had to give element a value of 1 or it crashed out. Therefore the line /after/ the matched string was output.
  242.         // I therefore subtract 1 from element to correct for this.
  243.         // A workaround, not a fix.
  244.         element -= 1;
  245.        
  246.         if ( debug )
  247.         {
  248.             // Debugging.
  249.             Console.WriteLine();
  250.             Console.WriteLine("Sentinel value: {0}", sentinel);
  251.             Console.WriteLine("Element value: {0}", element);  
  252.             if ( sentinel > 0 )
  253.                 Console.WriteLine("Matched string: {0}", csv[element]);
  254.             else if ( sentinel <= 0 )
  255.                 Console.WriteLine("Not found, sorry. :(");
  256.             Console.WriteLine();
  257.             Console.ReadLine();
  258.         }
  259.        
  260.         if ( sentinel > 0 )
  261.         {
  262.             Console.Clear();
  263.             // The pretty output goes here.
  264.             Console.WriteLine("Record matched!");  
  265.             CsvView( path, element );
  266.         }
  267.         else if ( sentinel < 0 )
  268.         {  
  269.             Console.Clear();
  270.             Console.WriteLine("String not matched, sorry. :(");
  271.             Back();
  272.         }
  273.    
  274.        
  275.         /*
  276.         I ran into some problems with the output. I could write a method to output either the entire array, or one line as needed.
  277.         But eh, whatever.
  278.        
  279.         This was the final part of the project I approached. My own overall assessment of my performance is moments of brilliance
  280.         interspersed with hours of raw, bumbling mediocrity. I spoke to other classmates, and apparently my approach to handling
  281.         the file with an array was unique. The code in this project is stripped down from a fully-featured CSV parser that I wrote.
  282.         Balancing this was my often lazy implementation of X or Y feature.
  283.        
  284.         However! The end-user should see a flawless experience in line with the expectations of the project. Small victories.
  285.         */
  286.     }
  287.  
  288.     //
  289.     // ++++CITATIONS++++
  290.     //
  291.    
  292.     private static string PlayerCitation( string sScore )
  293.     {
  294.         /*
  295.         The achievement scores in my players.csv file are higher than those in the sample file.
  296.         (This is the same sample file that, in hindsight, I should have probably downloaded.)
  297.         To accomodate this, I have modified the score criteria to fit my .csv file. Behold:
  298.        
  299.              Exercise:           Mine:
  300.              < 400               < 4000
  301.             >= 400 && <= 599    >= 4000 && <= 5999
  302.             >= 600 && <= 699    >= 6000 && <= 6999
  303.             >= 700 && <= 999    >= 7000 && <= 9999
  304.              > 999               > 9999
  305.        
  306.         In short, I added a zero. /toot
  307.         */
  308.  
  309.         string citOne   = "Sluggish Snail";
  310.         string citTwo   = "Ambling Armadillo";
  311.         string citThree = "Bobbing Bobcat";
  312.         string citFour  = "Rocketing Rabbit";
  313.         string citFive  = "Turbocharged Cheetah";
  314.        
  315.         // Take in the player score (their achievement points), and convert it to an int value.
  316.         int score = Convert.ToInt32( sScore );
  317.         string citation = "";
  318.                    
  319.         if ( score < 4000 )
  320.             citation = citOne;
  321.         if ( (score >= 4000) && (score <= 5999) )
  322.             citation = citTwo;
  323.         if ( (score >= 6000) && (score <= 6999) )
  324.             citation = citThree;
  325.         if ( (score >= 7000) && (score <= 9999) )
  326.             citation = citFour;
  327.         if ( (score > 9999) )
  328.             citation = citFive;
  329.            
  330.         return citation;
  331.     }
  332.    
  333.     //
  334.     // ++++GO BACK++++
  335.     //
  336.    
  337.     static void Back()
  338.     {
  339.         // Pause before returning. 
  340.         Console.WriteLine();   
  341.         Console.Write("Press [RETURN] to return to the main menu.");
  342.         Console.ReadLine();
  343.     }
  344.  
  345.     //
  346.     // ++++PARSE INT++++
  347.     //
  348.    
  349.     private static int IntParse( string userPrompt )
  350.     {  
  351.         // A boolean variable to test the int (or double, as the case may be).
  352.         bool evalInt = false;
  353.         int parsedInt = 0;
  354.  
  355.         do
  356.         {
  357.             // Send the relevant string to the console.
  358.             Console.Write(userPrompt);
  359.             // Read/test the user's input.
  360.             evalInt = Int32.TryParse( Console.ReadLine(), out parsedInt );
  361.  
  362.             // If it doesn't parse, loop. If it does, move on.
  363.             if ( !evalInt )
  364.                 InputFail();
  365.                
  366.         // Keep asking the luser for input until they give us something valid.
  367.         } while ( !evalInt );
  368.  
  369.         // Return the parsed input.
  370.         return parsedInt;
  371.     }
  372.  
  373.     // 
  374.     // ++++PARSE DOUBLE++++
  375.     //
  376.    
  377.     private static double DoubleParse( string userPrompt )
  378.     {  
  379.         bool evalDouble = false;
  380.         double parsedDouble = 0;
  381.  
  382.         do
  383.         {
  384.             Console.Write( userPrompt );
  385.             evalDouble = Double.TryParse( Console.ReadLine(), out parsedDouble );
  386.  
  387.             if ( !evalDouble )
  388.                 InputFail();
  389.                
  390.         } while ( !evalDouble );
  391.  
  392.         return parsedDouble;
  393.     }
  394.    
  395.     // 
  396.     // ++++BAD USER! BAD!++++
  397.     //
  398.    
  399.     static void InputFail()
  400.     {
  401.         // Part of the Int/Double parse methods.
  402.         Console.WriteLine("Invalid input. Please enter a numerical value.");
  403.     }
  404. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement