Know Your GPA – Solution

It’s fun supplying your own scores for a semester, which really helps boost your GPA! Still, the challenge for this Month’s Exercise was to input — and validate — a series of grades to calculate your GPA for five courses.

I went through two drafts of my solution. The first had an input routine, get_grade(), obtain the input from 0 through 100, validate and return that value. The main() function translated the value returned, calculated the GPA value, stored it in an array, then generated the average. This solution worked, but it was clunky.

My second draft has the get_grade() function accept and validate input, and return the GPA value directly, not the 0 to 100 grade. This way, the main() function can process everything, both collecting input and calculating the average, in a single loop. Here’s my solution:

#include <stdio.h>
#include <stdlib.h>

#define SIZE 12
#define CLASSES 5

float get_grade(void)
{
    char input[SIZE];
    float grade;
    char *p;

    /* obtain input */
    fgets(input,SIZE,stdin);
    /* convert to float */
    grade = strtod(input,&p);
    /* validate */
    if( p==input )
    {
        puts("Inavlid input");
        exit(1);
    }
    /* confirm range */
    if( grade<0 || grade>100 )
    {
        puts("Input out of range");
        exit(1);
    }

    /* return GPA value */
    if( grade > 89 )
        return(4.0);
    if( grade > 79 )
        return(3.0);
    if( grade > 69 )
        return(2.0);
    if( grade > 59 )
        return(1.0);

    return(0.0);
}

int main()
{
    float gpa,average;
    int x;

    /* obtain input */
    gpa = 0.0;
    for( x=0; x<CLASSES; x++)
    {
        printf("Enter grade (0 to 100) for class #%d: ",x+1);
        gpa += get_grade();
    }
    average = gpa/(float)CLASSES;

    /* output results */
    printf("Your semester GPA is %.1f\n",average);

    return(0);
}

(GitHub)

The get_grade() function uses fgets() to obtain input. The strtod() function converts input to a decimal value, with the if statement (at Line 18) checking for invalid input.

At Line 24, the if statement checks the input range: if( grade<0 || grade>100 ) The program exits on any invalid input. One improvement you could make would be to have it prompt again, which you can code on your own.

Starting at Line 31, a series of if tests return the proper GPA value, with the final return statement tossing back zero for values below 60.

In the main() function, a for loop both gathers input and totals the GPA values returned in the gpa variable. Line 55 calculates the average, dividing gpa by the number of CLASSES, which must be typecast to a float: average = gpa/(float)CLASSES;

Line 58 outputs the result.

Here’s a sample run:

Enter grade (0 to 100) for class #1: 99
Enter grade (0 to 100) for class #2: 98
Enter grade (0 to 100) for class #3: 89
Enter grade (0 to 100) for class #4: 75
Enter grade (0 to 100) for class #5: 100
Your semester GPA is 3.4

And you see that my GPA has improved from when I ran the code in the original Exercise post!

I hope you devised a solution that’s clever and tidy and generates accurate output. The key is to use the strtod() functione to evaluate input. Refer to the Lesson on strtol() for details on how the function validates input. Otherwise, if whatever crazy method you devised to calculate GPA works, congratulations!

2 thoughts on “Know Your GPA – Solution

  1. When you posted this exercise I scribbled down a formula to calculate the grade from the percentage:

    floor((percentage / 10) – 5)

    but for 100% it gives 5 so needs and extra check afterwards to subtract 1 in this case. I can’t think of a way of eliminating this problem. (Unless you want to assume nobody ever gets 100%…!)

    Here are some examples:

    floor((100 / 10) – 5) = 5 <= NEED TO SUBTRACT 1
    floor((90 / 10) – 5) = 4
    floor((89 / 10) – 5) = 3
    floor((80 / 10) – 5) = 3
    floor((79 / 10) – 5) = 2
    floor((70 / 10) – 5) = 2
    floor((69 / 10) – 5) = 1
    floor((60 / 10) – 5) = 1
    floor((59 / 10) – 5) = 0

  2. I’ve had issues similar to that in my code – all the time, in fact. When it arises, I have to test for the condition specifically and then make a fix. I believe something similar happened in last month’s Exercise, where I had to account for day-of-the-month overflow. Anyhoo.

Leave a Reply