Universal Grade Calculator


main.cpp

				
/**Universal Grade Calculator by Austin Metzner*/
#include <iostream>
#include <istream>
#include "classGrade.h"

using namespace std;

int main()
{
    cout << "Welcome to the Universal Grader!" << endl;
    classGrade *myClass = new classGrade;

    string userInput;
    while(userInput != "10"){
        cout<<"======Main Menu====="<<endl;
        cout<<"1. Add a class"<<endl;
        cout<<"2. Calculate class grade"<<endl;
        cout<<"3. Print grades"<<endl;
        cout<<"4. Best and worst section"<<endl;
        cout<<"5. Minimum grade (on final) to pass"<<endl;
        cout<<"6. Change grade"<<endl;
        cout<<"7. Delete class"<<endl;
        cout<<"8. Minimum grade (on final) to receive A"<<endl;
        cout<<"9. Minimum grade (on final) to receive grade of your choice"<<endl;
        cout<<"10. Quit"<<endl<<endl<<"~~";

        getline(cin,userInput);
//OPTION 1 ADD A NEW CLASS
        if(userInput == "1"){
            //classGrade *myClass = new classGrade;
            myClass->addClass();
        }
//OPTION 2 CALCULATE GRADE
        else if(userInput == "2"){
            myClass->totalGrades();
        }
//OPTION 3 PRINT GRADES
        else if(userInput == "3"){
            myClass->printGrades();
        }
//OPTION 4 Best and worst sections
        else if(userInput == "4"){
            myClass->bestNworst();
        }
//OPTION 5 MINIMUM GRADE ON FINAL TO PASS
        else if(userInput == "5"){
            myClass->min2pass();
        }
//OPTION 6 Change GRADE
        else if(userInput == "6"){
            myClass->changeGrade();
        }
//OPTION 7 DELETE CLASS
        else if(userInput == "7"){
            myClass->deleteClass();
        }
//OPTION 8 MINIMUM GRADE ON FINAL TO EARN A
        else if(userInput == "8"){
            myClass->min2A();
        }
//OPTION 8 MINIMUM GRADE ON FINAL TO EARN A GRADE OF USER'S CHOICE
        else if(userInput == "9"){
            myClass->min2grade();
        }
    }
    cout<<"Later alligator"<<endl;
    delete myClass;

    return 0;
}				
			


classGrade.cpp

				
#include "classGrade.h"
#include <iostream>
#include <istream>
using namespace std;

classGrade::classGrade()
{
    head = NULL;
    tail = NULL;
}
classGrade::~classGrade()
{
    this->deleteClass();
}

Section* classGrade::getSectionInfo(Section *node)//Gets section info Checks if section weight entered is less than one
{
    cout<<"Enter name of section: ";
    getline(cin, node->section);
    double x = -1;
    while(0 >= x || x > 1)
    {
        cout<<"Enter section weight (0-1.00): ";
        cin>>x; cin.ignore();
        if( x>0 && x<=1)
        {
            node->sectionWeight = x;
            break;
        }
    }
    int y = -1;
    while(0 > y)
    {
        cout<<"Enter number of grades in section: ";
        cin>>y; cin.ignore();
        if(y >=0)
        {
            node->numGrades = y;
            break;
        }
    }
    node->sectionGrades = new double[node->numGrades]; //Creates array for grades for this section
    return node;
}

Section* classGrade::validGrade(Section *node, int i)//makes sure grade entry is from 0-100
{
    double x = -1;
    while(0 > x || x > 100)
    {
        cout<<"Enter "<<node->section<<" grade "<<(i+1)<<": ";
        cin>>x; cin.ignore();
        if(x>0 && x<=100)
        {
            node->sectionGrades[i] = x;
            node->gradeSum += node->sectionGrades[i];
            return node;
        }
    }
    return node;
}

Section* classGrade::getAvg(Section *node)//calculates section average
{
    node->avgGrade = (node->gradeSum/node->numGrades);//Getting Section Average and weighted grade
    node->weightSum = node->sectionWeight*node->avgGrade;
    return node;
}

void classGrade::deleteClass()
{
    Section *current = head;
    Section *tmp = new Section;
    if(current != NULL)
    {
        cout<<"Deleting "<<this->className<<endl;
        while(current != NULL)
        { // Runs until all are deleted
            tmp = current->next;
            cout<<"Deleting "<<current->section<<endl;
            delete current;
            current = tmp;
        }
    head = NULL;
    }
    delete current;
    cout<<"Class successfully deleted"<<endl;
}

void classGrade::addClass()
{
    cout<<"===ADDING CLASS==="<<endl;
    //Establishing class
    cout<<"Enter name of class: ";
    getline(cin, this->className);
    cout<<"The final is by default the last section included in the section count"<<endl;
    cout<<"Enter number of sections: ";
    cin>>this->numSections; cin.ignore(); cout<<endl;

    //Establishing each section and grades
    Section* first = new Section;//Instating head as first section of class
    double finalWeight = 0;//used to calculate weight of final automatically
    first = getSectionInfo(first);
    for(int i = 0; i < first->numGrades; i++)//Inputting grades
    {
        first = validGrade(first, i);
    }
    first = getAvg(first);
    finalWeight += first->sectionWeight;
    cout<<"Section average: "<<first->avgGrade<<endl; cout<<endl;
    head = first;

    Section *current = head;//sets values of each section after head
    for(int i = 1; i < this->numSections-1; i++)
    {
        Section *tmp = new Section;
        tmp = getSectionInfo(tmp);
        for(int i = 0; i < tmp->numGrades; i++)
        {
            validGrade(tmp, i);
        }
        tmp = getAvg(tmp);
        finalWeight += tmp->sectionWeight;
        cout<<"Section average grade: "<<tmp->avgGrade<<endl; cout<<endl;
        current->next = tmp;
        current = current->next;
    }
    //The final
    Section *final = new Section;
    current->next = final;
    if(finalWeight >= 1)
    {
        cout<<"Section weight sum must be less than 1"<<endl;
        return;
    }
    final->section = "Final"; final->sectionGrades = new double[1]; final->numGrades = 1;
    string answer;
    while(answer != "y" && answer != "n")
    {
        final->sectionWeight = 1 - finalWeight; //automatically determines weight of final
        cout<<"Have you taken the final? (y/n)   ";
        getline(cin, answer);
        if(answer == "y")
        {
            cout<<"What was your score?  ";
            cin>>final->gradeSum; cin.ignore();
            final->sectionGrades[0] = final->gradeSum;
            final = getAvg(final);
            this->finalTaken = true;
            break;
        }
        else if (answer == "n") break;
    }
    tail = final; cout<<endl;
}

void classGrade::printGrades()
{
    Section *current = head;
    cout<<"===PRINTING GRADES==="<<endl;
    cout<<endl;
    while(current != NULL)
    {
        if(current == tail && this->finalTaken == false)
        {
            cout<<"Final has not been taken ~"<<endl;
            break;
        }
        else
        {
            cout<<"Name of section: "<<current->section;
            cout<<" | Section weight: "<<current->sectionWeight;
            cout<<" | Number of grades: "<<current->numGrades<<endl;
            for(int i = 0; i < current->numGrades; i++)
            {
                if(i == 0)
                    cout<<current->section<<" "<<(i+1)<<": ";
                else
                    cout<<" | "<<current->section<<" "<<(i+1)<<": ";
                cout<<current->sectionGrades[i];
            }
            cout<<endl;
            cout<<"Average grade in this section: "<<current->avgGrade;
            cout<<" | Weighted grade: "<<current->weightSum<<endl<<endl;
            current = current->next;
        }
    }
    cout<<"=================="<<endl;
    cout<<endl;
}

void classGrade::totalGrades()//Calculates current or final grade
{
    cout<<endl;
    cout<<"===CALCULATING CLASS GRADE==="<<endl<<endl;
    if(this->finalTaken == true)
    {
        Section *current = head;
        double finalGrade = 0; //Current grade is weighted Averages divided by combined weights of classes thus far
        while(current != NULL)
        {
            finalGrade += current->weightSum;
            current = current->next;
        }
        cout<<"Your grade in "<<this->className<<" is: "<<finalGrade<<endl<<endl;
    }
    else//If final not taken
    {
        Section *current = head;
        double currentSum,currentWeight = 0; //Current grade is weighted Averages divided by combined weights of classes thus far
        while(current != tail)
        {
            currentSum += current->weightSum;
            currentWeight += current->sectionWeight;
            current = current->next;
        }
        cout<<"Your grade in "<<this->className<<" thus far is: "<<(currentSum/currentWeight)<<endl;
    } cout<<endl;
}

void classGrade::bestNworst()//Calculates best and worst section
{
    cout<<"===BEST AND WORST SECTIONS==="<<endl;
    Section *current = head;
    Section *worstSection = new Section; Section *bestSection = new Section;
    double worstGrade = 99999; double bestGrade = -1;
    while(current != NULL)
    {
        if(current == tail)
        {
            if(this->finalTaken == false)
                break;
        }
        if(current->avgGrade > bestGrade)
        {
            bestGrade = current->avgGrade;
            bestSection = current;
        }
        if(current->avgGrade < worstGrade)
        {
            worstGrade = current->avgGrade;
            worstSection = current;
        }
        current = current->next;
    }
    cout<<"Your best section in "<<this->className<<" is '"<<bestSection->section<<"' with an average grade of: ";
    cout<<bestSection->avgGrade<<endl;
    cout<<"Your worst section in "<<this->className<<" is '"<<worstSection->section<<"' with an average grade of: ";
    cout<<worstSection->avgGrade<<endl; cout<<endl;
}

void classGrade::min2pass()//Minimum grade on final needed to pass
{
    cout<<endl;
    cout<<"===MINIMUM GRADE ON FINAL TO PASS==="<<endl;
    if(this->finalTaken == true)
    {
        cout<<"This operation calculates the minimum score the user needs to pass this class"<<endl;
        cout<<"The final exam must not have been taken in order to access the function ~"<<endl<<endl;
        return;
    }
    else//If final not taken
    {
        Section *current = head;
        double currentGrade = 0; double grade2pass = 0;
        while(current != tail)
        {
            currentGrade += current->weightSum;
            current = current->next;
        }
        grade2pass = (60 - currentGrade)/tail->sectionWeight;
        cout<<"Assuming a 60 is the deciding point of failure or not..."<<endl;
        cout<<"You need a minimum score of "<<grade2pass<<" on the final in order to pass "<<this->className<<endl;
        if(grade2pass >= 80)
            cout<<"Good luck ~"<<endl;
    }
    cout<<endl;
}

void classGrade::min2A()//Minimum grade on final needed to pass
{
    cout<<endl;
    cout<<"===MINIMUM GRADE ON FINAL TO GET AN -A- IN THE CLASS==="<<endl;
    if(this->finalTaken == true)
    {
        cout<<"This operation calculates the minimum score the user needs to pass this class"<<endl;
        cout<<"The final exam must not have been taken in order to access the function ~"<<endl<<endl;
        return;
    }
    else//If final not taken
    {
        Section *current = head;
        double currentGrade = 0; double grade2pass = 0;
        while(current != tail)
        {
            currentGrade += current->weightSum;
            current = current->next;
        }
        grade2pass = (90 - currentGrade)/tail->sectionWeight;
        cout<<"Assuming a 90 is the deciding point of an -A- or not..."<<endl;
        cout<<"You need a minimum score of "<<grade2pass<<" on the final in order to get an A "<<this->className<<endl;
        if(grade2pass >= 85)
            cout<<"Good luck ~~"<<endl;
    }
    cout<<endl;
}

void classGrade::min2grade()//Minimum grade on final needed to pass
{
    cout<<endl;
    bool good = false;
    string grade;
    int percent = 0;
    while (good == false){
        cout<< "Please enter your desired grade from the following: A, B, C, or D."<<endl;
        cin>>grade; cin.ignore();
        if (grade == "A" || grade == "a"){
            percent = 90;
            good = true;
        }else if (grade == "B" || grade == "b"){
            percent = 80;
            good = true;
        }else if (grade == "C" || grade == "c"){
            percent = 70;
            good = true;
        }else if (grade == "D" || grade == "d"){
            percent = 60;
            good = true;
        }
    }
    cout<<"===MINIMUM GRADE ON FINAL TO GET A(N) "<<grade<<" IN THE CLASS==="<<endl;
    if(this->finalTaken == true)
    {
        cout<<"This operation calculates the minimum score the user needs to pass this class"<<endl;
        cout<<"The final exam must not have been taken in order to access the function ~"<<endl<<endl;
        return;
    }
    else//If final not taken
    {
        Section *current = head;
        double currentGrade = 0; double grade2pass = 0;
        while(current != tail)
        {
            currentGrade += current->weightSum;
            current = current->next;
        }
        grade2pass = (percent - currentGrade)/tail->sectionWeight;
        cout<<"Assuming a(n) "<<percent<<" is the deciding point of a(n) "<<grade<<" or not..."<<endl;
        cout<<"You need a minimum score of "<<grade2pass<<" on the final in order to get a(n) "<<grade<<" in "<<this->className<<endl;
    }
    cout<<endl;
}

void classGrade::changeGrade()//Lets user change grades of a section
{
    cout<<"===CHANGING GRADES==="<<endl;
    string input;
    while(input != "q")
    {
        Section *current = head;
        cout<<"Enter 'q' to quit editing"<<endl;
        cout<<"Which section would you like to edit?...  ";
        getline(cin, input);
        if(input == "q")
            return;
        while(current != NULL)
        {
            if(current->section == input)
                break;
            current = current->next;
        }
        if(current == NULL)
            cout<<"Section name not found"<<endl;
        else
        {
            for(int i = 0; i < current->numGrades; i++)
            {
                if(i == 0)
                    cout<<current->section<<" "<<i<<": ";
                else
                    cout<<" | "<<i<<": ";
                cout<<current->sectionGrades[i];
            } cout<<endl;
            int index; //double newGrade;
            cout<<"Which grade would you like to change (select number next to grade)?: ";
            cin>>index; cin.ignore();
            current = updateSectionVal(current, index);
        }
    }
}

Section* classGrade::updateSectionVal(Section *node, int i)//Updates values of section after changes are made
{
    node->gradeSum = 0;
    double x = -1;
    if (node->section == "Final") //If user wants to update the final it will be marked as taken
        this->finalTaken = true;
    while(0 > x || x > 100)
    {
        cout<<"What number would you like to change grade "<<i<<" to?: ";
        cin>>x; cin.ignore();
        if(x>0 && x<=100)
        {
            node->sectionGrades[i] = x;

            break;
        }
    }
    for(int t = 0; t < node->numGrades; t++)
        node->gradeSum += node->sectionGrades[t];
    node = getAvg(node);
    return node;
}				
			


classGrade.h

				
#ifndef CLASSGRADE_H
#define CLASSGRADE_H

#include <iostream>
#include <istream>

using namespace std;

struct Section{ //Every class has multiple
    string section; //Section name contained within class
    double sectionWeight = 0; //Individual section of class weight e.g. HW %30 or .30
    int numGrades = 0; //Number of grades in section e.g. 14 HW assignments throughout the semester
    double *sectionGrades;//Array of grade entries
    double gradeSum = 0; // Sum of Grades of section
    double avgGrade = 0; //AVG. GRADE of section
    double weightSum = 0; // Avg. Grade X Weight of section

    Section *next; //Pointer to next section array
    Section(){} // default constructor
};

class classGrade{
private:
    Section *head;
    Section *tail;
    string className; //Name of class e.g. "Data Structures"
    int numSections; //Number section
    bool finalTaken = false; //Whether or not final will be factored in to current grading process
public:
    classGrade(string name, int count);
    classGrade();
    ~classGrade();
    Section* getSectionInfo(Section *node);
    Section* validGrade(Section *node, int i);
    Section* getAvg(Section *node);
    void deleteClass();
    void addClass();
    void printGrades();
    void totalGrades();
    void bestNworst();
    void min2pass();
    void min2A();
    void changeGrade();
    void min2grade();
    Section* updateSectionVal(Section *node, int i);
};

#endif // CLASSGRADE_H
				
			

Github
YouTube
Repl