D.cpp

 avatar
unknown
c_cpp
a year ago
5.4 kB
8
Indexable
#include <iostream>
#include <string>
#include <map>
#include <cmath>

class Grade {
    std::string rank; // Maps a numerical score to a letter grade
    int score;
    bool isNumeric;

    static std::map<std::string, int> rankToScore; // Utility for converting grades to scores
    static std::map<int, std::string> scoreToRank; // Utility for converting scores to grades
    bool graded = false; // Tracks if a grade has been assigned

public:
    // Constructors
    Grade() : rank("X"), isNumeric(false), graded(false) {}
    Grade(const std::string& r) : rank(r), graded(true), score(rankToScore[r]), isNumeric(false) {}
    Grade(const char* r) : rank(r), graded(true), isNumeric(false), score(rankToScore[r]){} // Handle const char* directly
    Grade(int s) : score(s), isNumeric(true), graded(true) {
        auto it = scoreToRank.lower_bound(s);
        rank = it != scoreToRank.end() ? it->second : "X";
    }
    Grade(const Grade& other)
        : rank(other.rank), score(other.score), isNumeric(other.isNumeric), graded(other.graded) {
        // Here, you would add any additional behavior needed for copying this object.
        // Since your class doesn't manage resources outside of automatic storage, the default behavior is likely sufficient.
    }
    // Utility function to set grade from score
    void setFromScore(int score) {
        // Assume scoreToRank is properly initialized somewhere
        auto it = scoreToRank.lower_bound(score);
        rank = it != scoreToRank.end() ? it->second : "X";
    }

    // Getters
    std::string GetRank() const { return rank; }
    int GetScores() const {
        if (isNumeric) {
            return score;
        }
        else
        {
            // Assume rankToScore is properly initialized somewhere
            auto it = rankToScore.find(rank);
            return it != rankToScore.end() ? it->second : 0;
        }
    }

    // Comparison operators
    bool operator==(const Grade& other) const {
        // Assuming F and X are treated the same in terms of ranking
        if ((rank == "F" && other.rank == "X") || (rank == "X" && other.rank == "F")) {
            return true;
        }
        return rank == other.rank;
    }
    bool operator!=(const Grade& other) const {
        return !(*this == other);
    }
    bool operator<(const Grade& other) const {
        if (rank == "X" && other.rank != "X") return true;
        if (rank != "X" && other.rank == "X") return false;
        if (rank == other.rank) return false;

        return GetScores() < other.GetScores();
    }
    bool operator>(const Grade& other) const {
        //std::cout << std::endl << "1st test" << std::endl;
        if (rank == "X" && other.rank != "X") return false;
        //std::cout << std::endl << "2nd test" << std::endl;
        if (rank != "X" && other.rank == "X") return true;
        //std::cout << std::endl << "3rd test" << std::endl;
        //std::cout << GetScores() << " and " << other.GetScores() << std::endl;
        if (rank == other.rank) return false;

        return GetScores() > other.GetScores();
        //std::cout << std::endl << "last test" << std::endl;
        //return other < *this;
    }
    bool operator<=(const Grade& other) const {
        return !(*this > other);
    }
    bool operator>=(const Grade& other) const {
        return !(*this < other);
    }



    // Implement other comparison operators based on rank comparison logic

    // Output operator
    friend std::ostream& operator<<(std::ostream& os, const Grade& g) {
        os << g.rank;
        return os;
    }

    // Reset
    void Reset() { rank = "X"; graded = false; isNumeric = false; score = 0; }

    // Conversion to bool
    operator bool() const {
        return rank != "X";
    }

    // Average calculation
    friend Grade Average(const Grade& g1, const Grade& g2) {
        if (!g1 || !g2) return Grade("X");
        int avgScore = std::round((g1.GetScores() + g2.GetScores()) / 2.0);
        //std::cout << std::endl << avgScore << std::endl;
        return Grade(avgScore);
    }

    // Initialization of static maps (this would go outside the class definition)
    static std::map<std::string, int> initializeRankToScore() {
        std::map<std::string, int> m;
        m["A+"] = 95; // A is 90 and above
        m["A"] = 87; // A is 90 and above
        m["A-"] = 82; // A is 90 and above
        m["B+"] = 78; // B is 80-89
        m["B"] = 75; // B is 80-89
        m["B-"] = 70; // B is 80-89
        m["C+"] = 68; // C is 70-79
        m["C"] = 65; // C is 70-79
        m["C-"] = 60; // C is 70-79
        m["F"] = 50;  // F is below 60
        // X is not graded, so it does not need a score equivalent        
        return m;
    }

    static std::map<int, std::string> initializeScoreToRank() {
        std::map<int, std::string> m;
        // The map should be initialized in reverse order for lower_bound to work correctly
        m[100] = "A+";
        m[89] = "A";
        m[84] = "A-";
        m[79] = "B+";
        m[76] = "B";
        m[72] = "B-";
        m[69] = "C+";
        m[66] = "C";
        m[62] = "C-";
        m[59] = "F"; // Use 0 as the lowest possible score that still has a grade
        return m;
    }
};

// Initialize static members
std::map<std::string, int> Grade::rankToScore = Grade::initializeRankToScore();
std::map<int, std::string> Grade::scoreToRank = Grade::initializeScoreToRank();
Editor is loading...
Leave a Comment