Start learning free

LESSON 145 OF 414 · LOOPS & GLOBAL VARIABLES

Student Grades in Scala: Average with a Float Sum

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 = Array(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 = Array(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 size 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:
var sum = 0f
for (grade <- grades) {
	sum += grade
}
When the loop terminates, we know the sum. What should we do next?

We should compute val average = sum / grades.size and return average >= 5:
var sum = 0f
for (grade <- grades) {
	sum += grade
}
val average = sum / grades.size
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

    SCALA · LOOPS & GLOBAL VARIABLES

    Student Grades in Scala, explained

    Problem overview

    The method hasPassed receives an array of integer grades and returns a Boolean: true if the average grade is 5 or more, false otherwise. The average is the sum of the grades divided by how many there are.

    In the first example, the grades 4, 7, 5, 9, 8, 2 add up to 35, and 35 / 6 is about 5.83, so the result is true. In the second, 4, 7, 5, 3, 8, 2 add up to 29, and 29 / 6 is about 4.83, so the result is false.

    Approach: sum, divide, compare

    The task splits into three small jobs, done in order:

    1. Add up all the grades with a loop and a running total.
    2. Divide the total by the number of grades.
    3. Compare the average with 5 and return the answer.

    The loop is the same accumulator pattern as in any running sum: a variable starts at 0, and each grade is added to it. The only new decision is the type of the total, which the next section explains.

    Step by step

    1. Declare var sum = 0f. The f suffix makes the literal a Float, so sum is a Float, a 32-bit decimal number. It is a var because the loop changes it. Without the suffix, 0 would make it an Int.
    2. Loop with for (grade <- grades). The generator takes each element of the array in turn.
    3. Add with sum += grade. The grade is an Int and sum is a Float. Scala converts the Int to a Float on its own, so no cast is needed.
    4. Declare val average = sum / grades.size. The average never changes after it is computed, so it is a val. A Float divided by an Int is a Float, so the fractional part is kept. The length of an array comes from size (length is the same).
    5. Return average >= 5. A comparison is already a Boolean value, so it can be returned directly without an if.

    The solution in Scala

    class Solution {
        def hasPassed(grades: Array[Int]): Boolean = {
            var sum = 0f
            for (grade <- grades) {
                sum += grade
            }
            val average = sum / grades.size
            return average >= 5
        }
    }
    

    Integer division and the Float

    Division on two Int values truncates. In Scala, 35 / 6 is 5 and 29 / 6 is 4, with the fraction dropped. With the Float total, 35f / 6 gives 5.8333335, close to the real quotient. For a threshold like 5, both ways happen to agree on the final answer, since a whole-number average of at least 5 exactly matches a total of at least 5 times the count. The Float version is still the better habit, because it holds the real average, which matters as soon as the threshold is not a whole number or you want to print the average.

    Other details

    • average >= 5 compares a Float with the Int 5. Scala widens the 5 to a Float first.
    • A Float has about seven significant digits. For ordinary grades that is plenty, but a total beyond 16,777,216 can lose exactness: adding 1 to 16777216 as a Float still gives 16777216.

    Complexity

    The loop makes one pass over the n grades, so the time is O(n). The method uses only sum, average and the loop variable, so the extra space is O(1).

    Edge cases and common mistakes

    • Exactly 5. The comparison is >=, so Array(5, 5) passes with an average of exactly 5. Using > would fail it.
    • Just below 5. Array(4, 5) averages 4.5 and returns false.
    • An empty array. The sum is 0 and 0f / 0 is NaN, not a number. Every comparison with NaN is false, so the method returns false and doesn't crash. The statement doesn't promise what to do here.
    • Dividing before summing. The division belongs after the loop. Dividing inside it gives wrong totals.
    • Declaring sum inside the loop. It would reset on every pass.

    Testing

    Try Array(4, 7, 5, 9, 8, 2), which returns true, and Array(4, 7, 5, 3, 8, 2), which returns false. Add Array(5, 5) (true) and Array(4, 5) (false) to check the boundary.

    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free