Saturday, June 10, 2017

Programming Challenge 11.12 - Course Grade

/* Course Grade - This program uses a structure to store the following data:
   
        * Name                                    Student name
        * Idnum                                   Student ID number
        * Tests                                     Pointer to an array of test scores
        * Average                                Average test score
        * Grade                                   Course grade
   
    The program keeps a list of test scores for a group of students. It asks
    the user how many test scores there are to be and how many students there
    are. It then dynamically allocates an array of structures. Each structure's
    Tests member points to a dynamically allocated array that holds the test
    scores.

    After the arrays have been dynamically allocated, the program asks for the
    ID number and all the test scores for each student. The average test score
    is calculated and stored in the average member of each structure. The course
    grade is computed on the basis of the following grading scale:

        * Average Test Grade                    Course Grade
          91-100                                         A
          81-90                                           B
          71-80                                           C
          61-70                                           D
          60 or below                                 F

    The course grade is then stored in the Grade member of each structure. Once
    all this data is calculated, a table is displayed on the screen listing each
    student's name, ID number, average test score, and course grade.

    Input Validation: It is ensured that all data for each student is entered.
    No negative numbers for any test score are accepted. */

#include "Utility.h"

struct CourseGrade
{
    string name;                /* Student name                              */
    int    IdNum;                /* Student's ID number                      */
    int   *testScores;        /* Pointer to an array of test scores */
    double average;            /* Student's average test score          */   
    char     grade;                /* Student's letter grade                  */

    ~CourseGrade()              /* Destructor */
    {
        delete testScores;
        testScores = nullptr;
    }
};

enum letterGrades
{
    A = 0, B = 1, C = 2, D = 3, F = 4
};

void initStudents(CourseGrade *, const int, const int);
void getScores(CourseGrade *, const int, const int);
void calcAvgScore(CourseGrade *, const int, const int);
void assignGrade(CourseGrade *, const int);
void displayRepCard(const CourseGrade *, const int);
void freeMem(CourseGrade *);

int main()
{
    CourseGrade *students = nullptr;

    int numStudents = 0;
    int numTests = 0;

    cout << "\n\tGaborone - Rainbow Secondary School "
          << "Gradebook\n\n\n"
          << "\tGrade Entry\n\n";
    cout << "\tHow many students are in your class? ";
    cin >> numStudents;
   
    cout << "\tHow many tests have been written?    ";
    cin >> numTests;

    students = new CourseGrade[numStudents]();

    initStudents(students, numStudents, numTests);
    getScores(students, numStudents, numTests);
    calcAvgScore(students, numStudents, numTests);
    assignGrade(students, numStudents);
    displayRepCard(students, numStudents);
    freeMem(students);

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: initStudents

    This function accepts a dynamically allocated array of
    structs as argument. It causes each each student's
    testScores member to point to a dynamically allocated
    array that holds the student's test scores.
   ********************************************************** */

void initStudents(CourseGrade *students, const int numStudents,
                        const int numTests)
{
    for (int index = 0; index < numStudents; index++)
    {
        students[index].testScores = new int[numTests]();
    }
}

/* **********************************************************
   Definition: getScores

    This function accepts a dynamically allocated array of
    structs as argument. It asks the user to enter the name of
    each student, his or her student ID and the scores for a
    number of tests. This input is stored in the appropriate
    members of the CourseGrade structure.
   ********************************************************** */

void getScores(CourseGrade *students, const int numStudents,
                    const int numTests)
{
    for (int studentIdx = 0; studentIdx < numStudents; studentIdx++)
    {
        cout << "\n\tStudent name: ";
        cin.ignore();
        getline(cin, students[studentIdx].name);

        /* Verifies that the name struct member isn't empty */
        while (students[studentIdx].name.empty() ||
                 isblank(students[studentIdx].name[0]) &&
               !isalpha(students[studentIdx+1].name[studentIdx]))
        {
            cout << "\tStudent name: ";
            getline(cin, students[studentIdx].name);
        }

        cout << "\tStudent ID:   ";
        cin >> students[studentIdx].IdNum;

        while (students[studentIdx].IdNum == students[studentIdx - 1].IdNum ||
                 students[studentIdx].IdNum == 0)
        {
            cout << "\n\tStudent ID:   " << students[studentIdx].IdNum
                  << " taken.\n"
                  << "\tStudent ID:   ";
            cin >> students[studentIdx].IdNum;
        }

        for (int blank = 0; blank < 1; blank++)
        {
            cout << "\n";
        }

        for (int testIdx = 0; testIdx < numTests; testIdx++)
        {
            cout << "\tTest score " << (testIdx + 1) << ": ";
            cin >> students[studentIdx].testScores[testIdx];

            /* Validate Input */
            while (students[studentIdx].testScores[testIdx] <= 0 ||
                    students[studentIdx].testScores[testIdx] > 100)
            {
                cout << "\n\tInvalid score!\n"
                      << "\tTest score " << (testIdx + 1) << ": ";
                cin >> students[studentIdx].testScores[testIdx];
            }
        }
    }
}

/* **********************************************************
   Definition: calcAvgScore

    This function accepts a dynamically allocated array of
    structs as argument. It calculates the average score for
    each student, and stores it in the appropriate structure
    member.
   ********************************************************** */

void calcAvgScore(CourseGrade *students, const int numStudents,
                        const int numTests)
{
    for (int studentIdx = 0; studentIdx < numStudents; studentIdx++)
    {
        double total = 0.0;

        for (int testIdx = 0; testIdx < numTests; testIdx++)
        {
            /* Calculate the sum-total of test scores for each student */
            total += students[studentIdx].testScores[testIdx];

            /* Get the average score for each student */
            students[studentIdx].average = total / numTests;
        }
    }
}

/* **********************************************************
   Definition: assignGrade

    This function accepts a dynamically allocated array of
    structs as argument. The nested ternary operator inside
    this function determines the letter grade based on the
    average score achieved by each student. It assigns and
    stores the letter grade to the 'grade' member.
   ********************************************************** */

void assignGrade(CourseGrade *students, const int numStudents)
{
    /* Char array to hold the letter grades */
    const char letterGrades[] = { 'A', 'B', 'C', 'D', 'F' };

    for (int studentIdx = 0; studentIdx < numStudents; studentIdx++)
    {
        students[studentIdx].average > 90 ?   students[studentIdx].grade = letterGrades[A] :
        students[studentIdx].average >= 81 && students[studentIdx].average < 91 ?
                                                         students[studentIdx].grade = letterGrades[B] :
        students[studentIdx].average >= 71 && students[studentIdx].average < 81 ?
                                                          students[studentIdx].grade = letterGrades[C] :
        students[studentIdx].average >= 61 && students[studentIdx].average < 71 ?
                                                          students[studentIdx].grade = letterGrades[D] :
                                                          students[studentIdx].grade = letterGrades[F];     
    }
}

/* **********************************************************
   Definition: displayRepCard

    This function accepts a dynamically allocated array of
    structures as argument. It displays a table on the screen,
    listing each students name, ID, average score and letter
    grade.
   ********************************************************** */

void displayRepCard(const CourseGrade *students, const int numStudents)
{
    cout << "\n\n\tGaborone - Rainbow Secondary School\n\n"
          << "\tSTUDENT REPORT CARD\n\n"
          << "\tStudent Name"
          << setw(25) << right << "Student ID"
          << setw(19) << right << "Average Score"
          << setw(23) << right << "Letter Grade\n";

    cout << "\t" << setw(79) << right << setfill('-') << "\n";
    cout << setfill(' ');

    for (int studentIdx = 0; studentIdx < numStudents; studentIdx++)
    {
        cout << fixed << showpoint << setprecision(2) << "\t";

        cout << setw(25) << left  << students[studentIdx].name
              << setw(12) << right << students[studentIdx].IdNum
              << setw(19) << right << students[studentIdx].average
              << setw(22) << right << students[studentIdx].grade << "\n";
    }
}

/* **********************************************************
   Definition: freeMem

    This function accepts a dynamically allocated array of
    structs as argument. It frees the memory.
   ********************************************************** */

void freeMem(CourseGrade *students)
{
    delete[] students;
    students = nullptr;
}

Example Output:





No comments:

Post a Comment