Abdullah Kaya
Abdullah Kaya

Reputation: 23

How can I calculate University grade average in case of literal grades?

I am trying to write a C program that gets data from the user and calculates his/her average.

It simply gets the credit of lecture and letter grade of lecture. Litelal grade system is given below:

Gain can be found by multiplying corresponding value of letter grade (eg. AA=4) and Credit number of lesson. For example, if grade is "AA", the gain contribution of that lecture to the average value will be 4*credit_of_lecture.

The weight grade average is calculated by total_gain/total_credit_number.

For each lecture

  1. Gain is calculated.
  2. Gains are added to each other.
  3. Average is calculated.

Another example

If my current weigth grade average is 3.00 with 47 credits, then this means I have 141 gain points so far. This semester I take 2 courses letter grade of one of them is AA with 3 credits and the other is BB with 3 credits. For this semestr my gain will be 21 (4*3 + 3*3). 21 is added to former gain (141). Total gain is now 162. total credit is 47+3+3= 53. New weitgh grade average is 162/53= 3.05

My code

The thing I couldn't do is that when user enters AA or BA how to use condition state to set gain? If user enters aa with 3 credits then the gain will be 12 and if user enters ba with 2 credits gain will be 7

To simplfy, (e.g) I obtained 47 credits so far and my grade average is 2.66.

This semester I take 6 courses

What will be the my final grade average?

int main(){
    int sayi,i,j /*credit number of the lectur*/;
    int kredi /*obtained credit*/, abd, gain;
    float gurtalama; //current grade average

    int x[2],n[5];// x will be letter grade n will be name of the lecture.

    printf("number of obtained credits: "); //gets the number of obtained credits
    scanf("%d",&kredi);

    printf("current grade average : "); // current weight grade average
    scanf("%f",&gurtalama);

    printf("how many lectures you take this semestr? : "); // number of lectures are get to decide how many times the for loop will work
    scanf("%d",&sayi);

    for(i=0;i<sayi;i++) {
        printf("Name of the lecture: "); // this is for not to confuse it may not be necessary
        scanf("%s",&n);

        printf("Credit number of lecture: "); //for each lecture, lecture credit
        scanf("%d",&j);

        printf("Letter grade of lecture: "); // letter grade to convert it into 4 based system
        scanf("%s",&x);

        printf("%s ",n);            //Name of the lecture
        printf("%d Kredi. ",j);     //Credit of lecture
        printf("%s \n",x);          //letter grade of lecture
    }
}

Upvotes: 2

Views: 218

Answers (1)

Roberto Caboni
Roberto Caboni

Reputation: 7490

Your problem is to translate literal grades to numeric values-

There are different ways to achieve your goal: I choose a solution that performs direct comparison of input grades with the set of allowed ones. This can be done in an elegant way by defining a look-up table.

The proposed solution will not contain:

  • The input retrieval from the user. This is up to you, especially because if you correctly define the engine, the user interface is a detail that can be implemented in different ways (not only with a loop of scanfs but also, for example, processing an input text file).
  • A case insensitive management. Only capital letters grades (eg. "BA") will be admitted. You will easily be able to accept lower characters grades with minor changes.
  • The management of extra lecture info such as lecture name.

The example code

#include <stdio.h>
#include <string.h>

typedef struct
{
  char  literal[3];
  float numeric;
} GradeInfo_t; 

typedef struct
{
  /* Add all the extra info relevant to you: lecture name etcetera */
  unsigned int credits;
  char         grade[3];
} LectureInfo_t;

As you can see, if you want to write efficient code, some structures can be defined in order to put together relevant data. In this way you will be able (later) to define and array of structs that will make possible to you to loop through them.

The first structure will make possible the association between the single grade and its numerical value. The second one contains input lectures info.

/* Look-Up table to translate litaral grades into numeric values */
static const GradeInfo_t gradeLUT[] =
{
  { "AA", 4.0 },
  { "BA", 3.5 },
  { "BB", 3.0 },
  { "CB", 2.5 },
  { "CC", 2.0 },
  { "DC", 1.5 },
  { "DD", 1.0 },
  { "FF", 0.0 }
};

static const LectureInfo_t lecturesTestArray[] =
{
  { 4, "BB" }, 
  { 3, "AA" }, 
  { 4, "CC" }, 
  { 5, "BA" }, 
  { 3, "BB" }, 
  { 4, "DD" },
  { 4, "QQ" }, /* Unexpected literal. Will the program skip it? */
  { 3, "DC" }, 
  { 6, "AA" }, 
  { 5, "BA" }, 
  { 4, "CB" }, 
  { 2, "FF" }, 
};

Here I use the previosly defined structs in order to define two arrays:

  1. a look-up table with all the grades string literals and their corresponding numerical values
  2. a test set of lectures with their credits-grades couples. In inserted also a wrong grade. I want the program to discard it. The expected average grade is 2,75581395348837.


int main(void)
{
  /* Here you get grades and lecture info from the user. I define them        *
   * globally using a test array.                                             */
  int totalCredits = 0, i, j;
  int testElems=(sizeof(lecturesTestArray)/sizeof(LectureInfo_t));
  int totalGradeValues=(sizeof(gradeLUT)/sizeof(GradeInfo_t));;
  float gainsSum = 0, average;

  /* For every element of the test lecture array */
  for( i=0; i<testElems; i++)
  {
    /* Until a matching grade is found */
    for( j=0; j<totalGradeValues; j++)
    {
      /* Compare current lecture grade with current gradeInfo */
      if(strcmp(lecturesTestArray[i].grade, gradeLUT[j].literal) == 0 )
      {
        /* that's it! Process its data */
        totalCredits += lecturesTestArray[i].credits;
        gainsSum += lecturesTestArray[i].credits * gradeLUT[j].numeric;
        break;
      }
    }

    /* Just for fun: let's check that the "wrong" grade has been skipped */
    if( j == totalGradeValues )
    {
      printf("Grade %s (index %d) is wrong and has not been processed!\n", lecturesTestArray[i].grade, i);
    }
  }

  /* Test array consumed! Lets calculate average and print it */
  average = gainsSum / totalCredits;

  printf("Average grade is %0.2f", average);

  return 0;
}

The main. I just loop through the test values finding the grade related to them and updating the calculation. I skip the wrong input value. I finally calculate the average value printing it (with just two decimals, like in your example).

This is the output:

Grade QQ (index 6) is wrong and has not been processed!
Average grade is 2.76

Upvotes: 1

Related Questions