Start learning free

LESSON 139 OF 347 · LOOPS & GLOBAL VARIABLES

Student Grades in C#: Average with a foreach Loop

Practice Read the full explanation

Given the grades of a student as an array, determine if the student has passed the class.

A Student has passed the class if the average of grades is 5 or more.

The average is defined as (grades[0] + grades[1] + ... + grades[n - 1]) / n

Example 1:

Input: grades = [4, 7, 5, 9, 8, 2]
Output: true
Explanation:
average = (4 + 7 + 5 + 9 + 8 + 2) / 6 =
= 35 / 6 = 5.833333333... >= 5

Example 2:

Input: grades = [4, 7, 5, 3, 8, 2]
Output: false
Explanation:
average = (4 + 7 + 5 + 3 + 8 + 2) / 6 =
= 29 / 6 = 4.83333.. < 5

Hints:

The problem can be broken in 3 steps:
1. Compute the sum of the array
2. Compute the average by dividing the sum by the length of the array
3. Decide the result based on the average being greater than or equal to 5
Let's start with step 1: How can we compute the sum of the array?

First of all, we should store this sum somewhere as we compute it. That 'somewhere' is a variable, let's name it sum. We have to iterate through every element of grades and add its value to sum. How can we achieve this?

With a loop! Let's use a for loop and a variable grade to iterate through the elements:
sum = 0
for each grade in grades:
	sum += grade
When the loop terminates, we know the sum. What should we do next?

We should compute average = sum / length and return average >= 5:
sum = 0
for each grade in grades:
	sum += grade
average = sum / length
return average >= 5


We have a for loop that performs exactly n iterations (n is the length of grades), thus the Time Complexity is O(n).
The only extra space we use are the variables sum, average and the iterator variable grade inside the loop, thus the Extra Space used is O(1).
STEP 1 OF 5
    Ctrl + Enter to check

    C# · LOOPS & GLOBAL VARIABLES

    Student Grades in C#, explained

    Problem overview

    HasPassed(int[] grades) receives a student's grades and returns true when the average is 5 or more, and false otherwise. The average is the sum of the grades divided by how many there are.

    For [4, 7, 5, 9, 8, 2] the sum is 35 and there are 6 grades, so the average is 35 / 6, about 5.83. That is at least 5, so the answer is true. For [4, 7, 5, 3, 8, 2] the sum is 29 and the average is about 4.83, so the answer is false.

    Approach

    The problem splits into three small jobs, and each one is a line or two of code:

    1. Add up all the grades.
    2. Divide the sum by the number of grades to get the average.
    3. Compare the average with 5 and return the answer.

    Adding up an array needs a running total and a loop that visits each element once. That makes the whole method one pass over the array, which is O(n) time with a handful of variables.

    Step by step

    1. Declare sum as a float starting at 0. It collects the total. Making it a floating-point type matters for the next division, as explained below.
    2. Loop with foreach. foreach (int grade in grades) hands you each grade in turn. You don't need an index, because only the values matter.
    3. Add each grade to sum. sum += grade does it. An int converts to float automatically, so no cast is needed.
    4. Compute the average. Declare a float named average and set it to sum / grades.Length. The array's size is its Length property: capital L, no parentheses.
    5. Return the comparison. average >= 5 is already a bool, so return it directly instead of writing an if that returns true or false.

    The solution in C#

    class Solution {
        public bool HasPassed(int[] grades) {
            float sum = 0;
            foreach (int grade in grades) {
                sum += grade;
            }
            float average = sum / grades.Length;
            return average >= 5;
        }
    }
    

    Some C# details are worth a closer look:

    • Integer division truncates. When both operands are int, C# divides and throws away the fractional part: 9 / 2 is 4, not 4.5. In this lesson the sum is a float, so sum / grades.Length is a floating-point division and the fraction is kept. For the second example, the result is about 4.8333335.
    • The result is a float. When one operand is a float and the other an int, C# converts the int and divides as floats. That is why grades.Length needs no cast here.
    • foreach reads, it doesn't write. The loop variable grade is a copy of each element and can't be assigned to. That is fine here, since the loop only reads.
    • float has limited precision. It keeps about 7 significant digits, so very large integer sums can't all be represented exactly. For grades this is irrelevant. When precision matters, double is the usual choice.

    A useful observation: because the pass mark is a whole number and grades are integers, the test sum >= 5 * grades.Length gives the same answer without any division. Truncating integer division would also give the same true or false here, since cutting off a fraction never moves a value across a whole number boundary. The lesson uses float because it shows what the average really is, and because the habit matters in the many problems where the fraction does count.

    Complexity

    Time: O(n), where n is the number of grades. The loop touches each grade once, and the division and comparison happen once.

    Space: O(1). The method keeps sum, average and the loop variable, whatever the array size.

    Edge cases and common mistakes

    • Exactly 5. The comparison is >=, so an average of exactly 5, as in [5, 5] or [3, 7], passes. Using > would be a bug.
    • An empty array. Here grades.Length is 0. With a float sum, 0 / 0 gives NaN ("not a number") and every comparison with NaN is false, so the method returns false without crashing. With an int sum, the same division throws a DivideByZeroException. If an empty array can reach your code, handle it explicitly.
    • Forgetting the division. Comparing sum itself with 5 passes almost everyone. The sum has to be divided by the count first.
    • Dividing by the wrong number. Using the largest index (Length - 1) instead of Length gives a wrong average.
    • Declaring sum inside the loop. It would reset on every pass. Declare it before the loop.

    Testing

    • [4, 7, 5, 9, 8, 2] gives true.
    • [4, 7, 5, 3, 8, 2] gives false.
    • [5] gives true, because the average is exactly 5.
    • [4] gives false.
    • [10, 0] gives true, since the average is exactly 5.
    Keep going with C#About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free