0

here is my code so far. Im pulling data from a txt file and writing to a new file with averages of Age and experience. I'm not getting the right averages. Where is my mistake?

class Program
{
    static int age, exp, id, ageSum = 0, expSum = 0, empSum = 0;
    static double avgAge, avgExp;
    static char type;
    const string INPUT_FILE_NAME =
    "\\Users\\Jon.Jon-PC\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication9\\ConsoleApplication9\\data.txt";
    const string OUTPUT_FILE_NAME =
    "\\Users\\Jon.Jon-PC\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication9\\ConsoleApplication9\\dataout.txt";
    static StreamReader fileIn;
    static StreamWriter fileOut;
    static string lineIn, eligibility;


    static void OpenFiles()
    {
        if (File.Exists(INPUT_FILE_NAME))
        {
            fileIn = File.OpenText(INPUT_FILE_NAME);
            Console.WriteLine("{0} was opened", INPUT_FILE_NAME);
        }
        else
        {
            Console.WriteLine("Error: {0} does not exit\n",
           INPUT_FILE_NAME);
            Environment.Exit(0);
        }
        fileOut = File.CreateText(OUTPUT_FILE_NAME);
        if (File.Exists(OUTPUT_FILE_NAME))
            Console.WriteLine("{0} was created\n",
          OUTPUT_FILE_NAME);
        else
        {
            Console.WriteLine("Error: {0} could not be created\n",
          OUTPUT_FILE_NAME);

            Environment.Exit(0);
        }
    }

    static void ParseLineIn()
    {
        string[] words = new string[4];

        lineIn = lineIn.Trim();
        while (Regex.IsMatch(lineIn, "[ ]{2}"))
            lineIn = lineIn.Replace("  ", " ");
        words = lineIn.Split(' ');
        id = int.Parse(words[0]);
        type = char.Parse(words[1]);
        age = int.Parse(words[2]);
        exp = int.Parse(words[3]);
    }

    static void UpdateTotals()
    {
        empSum++;
        ageSum += age;
        expSum += exp;
    }

    static void CalcAvg()
    {
        avgAge = ageSum / empSum;
        avgExp = expSum / empSum;
    }

    static void PrintAvg()
    {
        fileOut.Write("Avg\t  {0}  {1}", avgAge, avgExp);
    }

    static void CalcRetirement()
    {
        switch (type)
        {
            case 'm':
            case 'M':

                if (age < 55 && exp < 20)
                    eligibility = ("lack of experience age");
                else if (age >= 55 && exp >= 20)
                    eligibility = ("can retire");
                else if (age >= 55 && exp < 20)
                    eligibility = ("lack of experience");
                else if (age < 55 && exp >= 20)
                    eligibility = ("underage");
                else
                    eligibility = ("Your entry is invalid");
                break;

            case 'w':
            case 'W':

                if (age < 63 && exp < 25)
                    eligibility = ("lack of exp age");
                else if (age >= 63 && exp >= 25)
                    eligibility = ("can retire");
                else if (age >= 63 && exp < 25)
                    eligibility = ("lack of exp");
                else if (age < 63 && exp >= 25)
                    eligibility = ("lack age");
                else
                    eligibility = ("Your entry is invalid");
                break;

            case 's':
            case 'S':

                if (age < 60 && exp < 24)
                    eligibility = ("lack of exp age");
                else if (age >= 60 && exp >= 24)
                    eligibility = ("can retire");
                else if (age >= 60 && exp < 24)
                    eligibility = ("lack of exp");
                else if (age < 60 && exp >= 24)
                    eligibility = ("underage");
                else
                    eligibility = ("Your entry is invalid");
                break;
        }
    }

    static void CloseFiles()
    {
        fileIn.Close(); fileOut.Close();
    }


    static void PrintReportHeadings()
    {
        fileOut.WriteLine("          Employee Report               ");
        fileOut.WriteLine();
        fileOut.WriteLine(" ID  Age Exp Eligibility ");
        fileOut.WriteLine("---- --- --- ----------- ");
    }

    static void printDetailLine()
    {
        fileOut.WriteLine("{0}  {1}  {2} {3}", id, age, exp, eligibility);
    }

    static void Main(string[] args)
    {
        OpenFiles();
        PrintReportHeadings();
        while ((lineIn = fileIn.ReadLine()) != null)
        {
            UpdateTotals();
            ParseLineIn();
            CalcRetirement();
            printDetailLine();

        }
        CalcAvg();
        PrintAvg();
        CloseFiles();
    }
}

I am pretty new to coding and so I don't know much else besides what I've learned this semester. The data from the file I'm pulling is below. Im supposed to calculate averages of the A and E columns.

       A  E
1235 W 45 20
2536 W 55 21
5894 W 60 30
4597 W 75 35
2597 S 35 10
5689 S 40 20
5489 W 55 39
5872 M 60 40
5569 M 55 25
5566 W 80 20
8865 M 59 35
5598 S 65 35

My current output is below..

          Employee Report               
 ID  Age Exp Eligibility 
---- --- --- ----------- 
1235  45  20 lack of exp age
2536  55  21 lack of exp age
5894  60  30 lack age
4597  75  35 can retire
2597  35  10 lack of exp age
5689  40  20 lack of exp age
5489  55  39 lack age
5872  60  40 can retire
5569  55  25 can retire
5566  80  20 lack of exp
8865  59  35 can retire
5598  65  35 can retire
Avg   51  24

The averages are supposed to be 57.0 and 27.5 What am I missing?

Jon Butler
  • 41
  • 6
  • Perhaps if you print a diagnostic of `empSum`, `ageSum`, and `expSum` at the appropriate time it would be useful for debugging the problem. A dump of your entire program that isn't trimmed down to just what is necessary to reproduce the problem without introducing noise is not terribly friendly towards others. One thing interesting... the averages you are printing out are integer-correct for 13 data points, and you have 13 lines of input with 12 data points. – mah Apr 18 '16 at 18:50
  • 3
    please have a look at [mcve] – Claudius Apr 18 '16 at 18:52
  • 2
    You want to call `ParseLineIn()` before `UpdateTotals()` or else you don't add the last age. Also you are incrementing `empSum` whether the line has age/exp data or not (so you are incrementing it by 1 if the file has a header or a blank line even though they didn't add to the sum). I feel like there are other issues too, but start there.. – Quantic Apr 18 '16 at 18:53
  • You are dividing `int`s which will cause your result to be rounded - simply declare an treat `empSum`, `ageSum` and `expSum` as `double` and you will get the desired results. – Filburt Apr 18 '16 at 18:57
  • thank you, swapped int's to doubles and fixed. – Jon Butler Apr 18 '16 at 19:00
  • Possible duplicate of [Why integer division in c# returns an integer but not a float?](http://stackoverflow.com/questions/10851273/why-integer-division-in-c-sharp-returns-an-integer-but-not-a-float) (or any post directly addressing double instead of float) – Filburt Apr 18 '16 at 19:00
  • @Filburt the situation you're describing as a possible dup might be relevant if instead of 27.5 he was getting 27, but not 24. – mah Apr 18 '16 at 19:21

1 Answers1

0

It may be likely that you are initially incrementing your empSum prior to performing any calculations within the UpdateTotals() method :

while ((lineIn = fileIn.ReadLine()) != null)
{
        UpdateTotals(); // Increments your `empSum` (even for the header row)
        ParseLineIn();
        CalcRetirement();
        printDetailLine();
}

This could cause your averages to be divided by a value 13 that is one larger than you expect 12, which could explain your current issue. You may want to explicitly check if any employee data is on this line prior to incrementing empSum.

Rion Williams
  • 74,820
  • 37
  • 200
  • 327