-1

I'm new to C# and we need to create an array that can hold 100 scores. But it needs to also accept something smaller (txt file with numbers between 0-100). My issue is that even tho I add a txt file that has 50 scores, it will think there is another 50 'blank scores' and it will count those as 0. So when my code does the average, total, and lowest score, it will mess it up. My textbook isn't being very help with the answer.

    private double Total(double[] iArray)
    {
        double total = 0;
        total = iArray.Length;

        return total;
    }
    
    //Average test score 
    private double Average(double[] iArray)
    {
        double total = 0;
        double average;
        for (int index = 0; index < iArray.Length; index++)
        {
            total += iArray[index];//look into later 
        }
        average = (double)total / iArray.Length;
        return average;
    } //done

    //for hightest test score
    private double Highest(double[] iArray)
    {
        double highest = iArray[0];
        for (int index = 1; index < iArray.Length; index++)
        {
            if (iArray[index] > highest)
            {
                highest = iArray[index];
            }
        }
        return highest;

    } //done

    private double Lowest(double[] iArray)
    {
        double lowest = iArray[0];
        for (int index = 1; index < iArray.Length; index++)
        {
            if (iArray[index] < lowest)
            {
                lowest = iArray[index];
            }
        }

        return lowest;
    }//done

    private void addFileButton_Click(object sender, EventArgs e)
    {
        try
        {
            const int SIZE = 100;               //number of test 
            double[] scores = new Double[SIZE]; //array of the test scores
            int index = 0; //loop counter
            int count = 0;
            double highestScore;
            double lowestScore;
            double averageScore;
            double totalScore;

            //Asking user to open a file
            StreamReader inputFile;

            if (openFile.ShowDialog() == DialogResult.OK)
            {
                inputFile = File.OpenText(openFile.FileName);
                
                while (!inputFile.EndOfStream && count < scores.Length)//switching index to count
                {
                    scores[count] = int.Parse(inputFile.ReadLine());
                    count++;
                }

                inputFile.Close();

            }
            else
            {
                MessageBox.Show("Operation Canceled.");
            }

            

            //Display test scores
            for (index = 0; index < count; index++)
            {
                scoreListBox.Items.Add(scores[index].ToString());
            }
            


            //grabbing information 
            highestScore = Highest(scores);
            lowestScore = Lowest(scores);
            averageScore = Average(scores);
            totalScore = Total(scores);


            //display values 
            highesScoreLabel.Text = highestScore.ToString();
            lowestScoreLabel.Text = lowestScore.ToString();
            averageTestScoreLabel.Text = averageScore.ToString();
            totalTestScoresLabel.Text = totalScore.ToString();

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        
    }
Carmen
  • 1
  • 2
    So is your question - "I created an array filled with 100 zeros. I changed 50 of them to other values. Why other 50 are still zero?" (You may want to re-read the [mre] guidance on posting code - it seem like an array of 2-4 elements and one method like `Sum` should be enough to demonstrate the problem, no file reading is needed: `var array = new int[2]; array[0]=5; if (array[1] == 0) Console.Write("Why????");` ) – Alexei Levenkov Sep 16 '22 at 19:02
  • 1
    Why do you need to use an array? List will be better option if you are reading a file – ozan.yarci Sep 16 '22 at 19:08
  • When you allocate an array of 100 size, it will always have a size of 100. any index that hasn't been set, will retain the default value, hence double -> 0's. Use `List` to have something that can change in length in size dynamically – Narish Sep 16 '22 at 19:08
  • Its in the instructions that he wants us to create an application that we add a txt file that can be filled up to 100 "test scores" but it doesn't need to be exactly 100. So I created a txt file with 50 scores in. But when my code does the math, it thinks there are 50 zero test scores. I think its doing that because I set the size to be 100. – Carmen Sep 16 '22 at 19:10
  • I know a list would be a better option, but he wants us to use an Array. Its an introduction class so I think he wants us to learn to use a partial array. – Carmen Sep 16 '22 at 19:11

2 Answers2

2

You might just have to use Array.Resize then:

while (!inputFile.EndOfStream && scores.Count <= SIZE)
{
    scores[count] = int.Parse(inputFile.ReadLine());
    count++;
}
Array.Resize(scores, --count);

See if that works.


This was suggested before the OP's comment clarifying the should specifically use an array:

What if you used a List<double> when collecting the scores, then .ToArray() before you pass it into your other methods?

const int SIZE = 100;
List<double> scores = new List<double>();

[...]

if (openFile.ShowDialog() == DialogResult.OK)
{
    inputFile = File.OpenText(openFile.FileName);
    
    while (!inputFile.EndOfStream && scores.Count <= SIZE)
    {
        scores.Add(int.Parse(inputFile.ReadLine()));
        count++;
    }

    [...]

var arrScores = scores.ToArray();

//grabbing information 
highestScore = Highest(arrScores);
lowestScore = Lowest(arrScores);
averageScore = Average(arrScores);
totalScore = Total(arrScores);

Notice that the while loop has the condition changed for scores.Count <= SIZE to still only allow up to 100 scores.

Daevin
  • 778
  • 3
  • 14
  • 31
  • 1
    or also they can change `double[]` in method signatures to be `List` and the method implementations can remain largely the same – Narish Sep 16 '22 at 19:11
  • 1
    @Narish I just noticed I put `int` instead of `double`, so thanks for that lol but yes, that is also an option. – Daevin Sep 16 '22 at 19:13
0

Instead of constructing the Array yourself and implementing all these methods, I suggest, you read up in LINQ. LINQ stands for Language INtegrated Query and is essentially a bunch of extension methods on IEnumerable<T> that provide all of the functionality you need here.

I rewrote your event handler to use LINQ and it became much simpler.

private void addFileButton_Click(object sender, EventArgs e)
{
    try
    {
        // Easier to follow if we just exit early
        if (openFile.ShowDialog() != DialogResult.OK)
        {
            MessageBox.Show("Operation Canceled.");
            return;
        }
        
        var scores = File.ReadAllLines(openFile.FileName)
            // Always use TryParse to avoid exceptions
            .Select(l => int.TryParse(l, out var score) ? score : -1)
            // Filter out everything that is no valid score
            .Where(s => s >= 0)
            // You could also use ToList() here for a possible minimal performance gain and the possibility to add items later.
            .ToArray();

        // Display test scores
        // We are using foreach instead of for here because we do not care about indexes. We simply want to add each item.
        // We also do not need to add the ToString(), just adding an int is fine.
        foreach (var score in scores)
            scoreListBox.Items.Add(score);

        // grabbing information 
        // We use LINQ methods here. Microsoft was nice enough di implement a bunch of often used methods on collections for us.
        var highestScore = scores.Max();
        var lowestScore = scores.Min();
        var averageScore = scores.Average();
        var totalScore = scores.Sum();


        //display values 
        highesScoreLabel.Text = highestScore.ToString();
        lowestScoreLabel.Text = lowestScore.ToString();
        averageTestScoreLabel.Text = averageScore.ToString();
        totalTestScoresLabel.Text = totalScore.ToString();

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}
wertzui
  • 5,148
  • 3
  • 31
  • 51