Grading Case Study in C++, Sorting Added

By Nicholas Duchon, September 30, 2014

From Venit, Section 6.8, pp 332-342, in C++

Outline:


Problem statement:

I have a class with final averages. I want the program to give each student their grade and print the class list sorted by their final average. Also print the average of all the final averages at the end.

Analysis:

Basically, output and then input characterizations will lead to required variables - THEN work on the algorithms

  1. How many students? Arbitrary, but say less than 100, perhaps less than 50.
    1. Thus: we will need to use arrays
  2. Input per student? Name, ID, average <return>
  3. Output? For each student: name, id, average, grade <return>
  4. Types? string, int, double, char

Basic algorithm:

start
  get intput
    >> assign grades somewhere
  print the unsorted data
  sort the data
  print the sorted data
  print the average of final averages
end

Code:

// File: gradingExample02.cpp
// Date: Sep 29, 2014
// Author: Nicholas Duchon
// Purpose: show parallel arrays with strings, and string i/o
// History:
//    Oct  6, 2014 - added sorting
//    Mar  3, 2017 - added comments about sorting and highlights

#include <string> // for string class
#include <iostream> // for cin and cout
using namespace std;

char getGrade (double score) {
   if (score >= 90) return 'A';
   if (score >= 80) return 'B';
   if (score >= 70) return 'C';
   if (score >= 60) return 'D';
   return 'F';
} // end function getGrade

int initArrays (int m, string n [], int id [], double sc [], char g []) {
   int count = 0;
   while (count < m) {
      cout << "Enter name id score [* to end]: ";
      cin >> n[count];
      if (n[count].compare ("*") == 0) break;
      cin >> id[count] >> sc[count];
      g[count] = getGrade (sc[count]);
      count ++;
   } // end for each input line
   return count;
} // end function initArrays

void printAll (string n [], int id [], double sc [], char g [], int m) {
   printf ("\n%-20s%10s%6s%9s\n",
      "Student Name", "ID number", "Score", "Grade");
   for (int i = 0; i < m; i++)
      printf ("%-20s%10d%6.1f%7c\n", n[i].c_str(), id[i], sc[i], g[i]);
} // end function printAll

// the sort is an insertion sort
// pink is the index of the element to pick from the array and insert
// into the section (low indices) sorted so far (yellow)
// for example:
//   array:  2 6 10 7 4 9 8 5 3 1
//   index:  9 8  7 6 5 4 3 2 1 0  pink = 5, value is 4
//  ops: pick out array[pink] 4, temp=4
//  move left one place: 9, 8 and 5
//     now index is 1, value is 3, and temp >= sc[index], ie, 4 >= 3
//  now insert temp into array at index+1 location: array[2] = temp
// result:
//   array: 2 6 10 7 9 8 5 4 3 1
//   index: 9 8  7
6 5 4 3 2 1 0  pink = 6, value = 7
void sortAll (string n [], int id [], double sc [], char g [], int m) {
   cout << "Sorting called" << endl;
   for (int pink = 0; pink < m; pink++) {
      double insert = sc [pink]; // value to insert into list
      string name   = n  [pink];
      int    ident  = id [pink];
      char   grade  = g  [pink];
      int    index;
      for (index = pink - 1; index >= 0; index--) { // count down
         if (insert < sc[index]) break; // right place found
         sc [index+1] = sc [index]; // not right place yet, move element
         n  [index+1] = n  [index];
         id [index+1] = id [index];
         g  [index+1] = g  [index];
      } // end find the right place to insert pink
      sc [index+1] = insert;
      n  [index+1] = name;
      id [index+1] = ident;
      g  [index+1] = grade;
   } // end for every entry in the original list
} // end function sortAll

double getAverage (double sc [], int m) {
   if (m <= 0) return 0; // make sure we don't divide by 0
   double sum = 0;
   for (int i = 0; i < m; i++)
      sum = sum + sc[i];
   return sum/m;
} // end getAverage

int main () {
   const int max = 50; // needs to be a constant to use in array declarations
   int used;           // the number of student entries actually active
   string names  [max];
   int    ids    [max];
   double scores [max];
   char   grades [max];
  
   used = initArrays (max, names, ids, scores, grades);
   printAll (names, ids, scores, grades, used);
   sortAll  (names, ids, scores, grades, used);
   printAll (names, ids, scores, grades, used);
   cout << "Average is: " << getAverage (scores, used) << endl;
   cout << "Bye" << endl;
   // system ("Pause"); // Visual C++
} // end main

Test Input:

jane 123 88.8
harry 212 78.5
ron  434 67.7
fred 233 98.5
norm 544 87.4
*

Input and Output:

Enter name id score [* to end]: jane 123 88.8
Enter name id score [* to end]: harry 212 78.5
Enter name id score [* to end]: ron  434 67.7
Enter name id score [* to end]: fred 233 98.5
Enter name id score [* to end]: norm 544 87.4
Enter name id score [* to end]: *

Student Name         ID number Score    Grade
jane                       123  88.8      B
harry                      212  78.5      C
ron                        434  67.7      D
fred                       233  98.5      A
norm                       544  87.4      B
Sorting called

Student Name         ID number Score    Grade
fred                       233  98.5      A
jane                       123  88.8      B
norm                       544  87.4      B
harry                      212  78.5      C
ron                        434  67.7      D
Average is: 84.18
Bye