diff options
| author | Steru <jerrydream111@gmail.com> | 2024-08-15 20:41:08 +0200 | 
|---|---|---|
| committer | Steru <jerrydream111@gmail.com> | 2024-08-16 23:53:26 +0200 | 
| commit | 492a726497785e8072e76a415dbbfdbd498e1b92 (patch) | |
| tree | 5bfa142e175fb0e667b3e0af794e1e59deac80ce /src/model | |
| parent | 70d5f014e50b9255dcb5c36122a109cc049c8936 (diff) | |
Reworked Sport class to work with QObjects instead of JSON objects.
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/Competitor.h | 11 | ||||
| -rw-r--r-- | src/model/CompetitorWithResults.h | 4 | ||||
| -rw-r--r-- | src/model/Sport.cpp | 159 | ||||
| -rw-r--r-- | src/model/Sport.h | 179 | 
4 files changed, 151 insertions, 202 deletions
| diff --git a/src/model/Competitor.h b/src/model/Competitor.h index 1121a5b..e5b0251 100644 --- a/src/model/Competitor.h +++ b/src/model/Competitor.h @@ -39,8 +39,19 @@ public:      QString getName() { return this->name; }      QString getNOC() { return this->noc; } +    void setCode(int code) { this->code = code; } +    void setName(QString name) { this->name = name; } +    void setNOC(QString noc) { this->noc = noc; } +      bool setCompetitor(const QJsonObject &competitor); +    static bool compareName(const Competitor &left, const Competitor &right) { +        return left.name.compare(right.name) < 0; +    } +    static bool compareNOC(const Competitor &left, const Competitor &right) { +        return left.noc.compare(right.noc) < 0; +    } +  private:      int code;      QString name; diff --git a/src/model/CompetitorWithResults.h b/src/model/CompetitorWithResults.h index a313db2..f57b773 100644 --- a/src/model/CompetitorWithResults.h +++ b/src/model/CompetitorWithResults.h @@ -15,6 +15,7 @@ class CompetitorWithResults : public Competitor {      Q_PROPERTY(QString mark READ mark)      Q_PROPERTY(QString medalType READ medalType) +    Q_PROPERTY(QString statistic READ statistic WRITE setStatistic)  public:      CompetitorWithResults() : Competitor() { @@ -34,15 +35,18 @@ public:      }      bool setResults(const QJsonObject &results); +    void setStatistic(QString stat) { this->statistic = stat; }      QString getMark() { return this->mark; }      QString getMedalType() { return this->medalType; } +    QString getStatistic() { return this->statistic; }      static bool compare(CompetitorWithResults lComp, CompetitorWithResults rComp);  private:      QString mark;      QString medalType; +    QString statistic;  }; diff --git a/src/model/Sport.cpp b/src/model/Sport.cpp index c7a9c72..4b822fa 100644 --- a/src/model/Sport.cpp +++ b/src/model/Sport.cpp @@ -124,60 +124,16 @@ QJsonArray filter(QJsonArray input, function<bool (QJsonObject)> eval) {      return output;  } -// static compare function for specific attribute in competitors -function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QString attribute) { -    return [attribute](const QJsonValue &left, const QJsonValue &right) { -        QString l = left.toObject()[attribute].toString(); -        QString r = right.toObject()[attribute].toString(); -        return l.compare(r) < 0; -    }; -} - -// static compare function for the results of a competitor in a specific competition (also called mark) -bool compareMark(const QJsonValue &left, const QJsonValue &right) { -    // check if one competitor has no mark -    QJsonObject l = left.toObject(); -    if (!l.contains("results")) return true; -    QJsonObject r = right.toObject(); -    if (!r.contains("results")) return false; - -    QString lMark = l["results"].toObject()["mark"].toString(); -    QString rMark = r["results"].toObject()["mark"].toString(); - -    // check if the marks are numerical values -    if (!lMark.contains(":") && !rMark.contains(":")) return lMark.toFloat() < rMark.toFloat(); - -    // compare time values if not numerical -    QString lTime(""), rTime(""); - -    for (QChar c : lMark) if (c.isDigit()) lTime.append(c); -    for (QChar c : rMark) if (c.isDigit()) rTime.append(c); - -    return lTime.compare(rTime) < 0; -} - -// static compare function for the amount of medals a competitor has gotten -bool compareMedals(const QJsonValue &left, const QJsonValue &right) { -    QJsonObject lMedals = left.toObject()["medals"].toObject(); -    QJsonObject rMedals = right.toObject()["medals"].toObject(); - -    int gold = lMedals["ME_GOLD"].toInt() - rMedals["ME_GOLD"].toInt(); -    int silver = lMedals["ME_SILVER"].toInt() - rMedals["ME_SILVER"].toInt(); -    int bronze = lMedals["ME_BRONZE"].toInt() - rMedals["ME_BRONZE"].toInt(); - -    return gold < 0 || (gold == 0 && (silver < 0 || (silver == 0 && bronze < 0))); -} -  /**   * @brief Sport::lastName Reduce the full name to the part that is marked in capital letters (probably last name).   * @param competitors The competitors of one category.   */ -void Sport::lastName(QJsonArray &competitors) { +void Sport::lastName(QList<Competitor> &competitors) {      // validate competitors -    if (competitors.isEmpty() || !competitors[0].toObject().contains("name")) return; +    if (competitors.isEmpty()) return; -    for (int i = 0; i < competitors.size(); ++i) { -        string fullName = competitors[i].toObject()["name"].toString().toUtf8().constData(); +    for (Competitor comp : competitors) { +        string fullName = comp.getName().toUtf8().constData();          // regex to identify names, written in CAPS          regex r("[A-Z']{2,}"); @@ -190,15 +146,10 @@ void Sport::lastName(QJsonArray &competitors) {          for (string s : m) lastName = lastName + s + " ";          // remove last space -        QJsonValue nameValue = QJsonValue(QString(lastName.substr(0, lastName.size() - 1).c_str())); +        QString name = QString(lastName.substr(0, lastName.size() - 1).c_str()); -        // create new object with replaced name -        QJsonObject comp(competitors[i].toObject()); -        comp.remove("name"); -        comp.insert("name", nameValue); - -        // replace competitor in array -        competitors.replace(i, comp); +        // replace competitor name in list +        comp.setName(name);      }  } @@ -237,8 +188,8 @@ set<QString> Sport::getCategories() {   * @param category The category to search in.   * @return An QJsonArray with all competitors as QJsonValueRef, which can be casted to QJsonObject.   */ -QJsonArray Sport::getCompetitorsByCategory(QString category) { -    QJsonArray competitors; +QList<CompetitorWithResults> Sport::getCompetitorsByCategory(QString category) { +    QList<CompetitorWithResults> competitors;      if (!validateDiscipline()) return competitors; @@ -253,21 +204,21 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {          // add all competitors from one unit          for (const QJsonValueRef &compRef : unit["competitors"].toArray()) { -            competitors.push_back(compRef.toObject()); +            competitors.push_back(CompetitorWithResults(compRef.toObject()));          }      } -    return QJsonArray(competitors); +    return competitors;  }  /**   * @brief Sport::getCompetitorsWithMedal Filters all competitors, who have at least one medal. These objects are different from getCompetitorsByCategory !!!   * @return All competitors, who won at least one medal. Structure of one competitor: {code, name, noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE}}   */ -QJsonArray Sport::getCompetitorsWithMedal() { +QList<MedalWinner> Sport::getCompetitorsWithMedal() {      map<QString, QJsonObject> competitors; -    if (!validateDiscipline()) return QJsonArray(); +    if (!validateDiscipline()) return QList<MedalWinner>();      // filter all units, which have medal events      QJsonArray units = filter(this->discipline["units"].toArray(), [](QJsonObject unit){ @@ -321,9 +272,9 @@ QJsonArray Sport::getCompetitorsWithMedal() {      }      // convert map to QJsonArray -    QJsonArray output; +    QList<MedalWinner> output;      for (const pair<QString, QJsonObject> &competitor : competitors) { -        output.append(competitor.second); +        output.append(MedalWinner(competitor.second));      }      return output; @@ -362,8 +313,8 @@ QJsonObject Sport::createCompetitorWithMedals(QJsonObject comp) {   * @param competitors The competitors of one category.   * @param name The (part of the) name to search for.   */ -void Sport::filterByName(QJsonArray &competitors, QString name) { -    filterCompetitors(competitors, QString("name"), name); +void Sport::filterByName(QList<Competitor> &competitors, QString name) { +    filterCompetitors(competitors, name);  }  /** @@ -371,8 +322,8 @@ void Sport::filterByName(QJsonArray &competitors, QString name) {   * @param competitors The competitors of one category.   * @param nocShort The (part of the) national olympics comittee short name to search for.   */ -void Sport::filterByCountry(QJsonArray &competitors, QString nocShort) { -    filterCompetitors(competitors, QString("noc"), nocShort); +void Sport::filterByCountry(QList<Competitor> &competitors, QString nocShort) { +    filterCompetitors(competitors, nocShort);  }  /** @@ -381,16 +332,12 @@ void Sport::filterByCountry(QJsonArray &competitors, QString nocShort) {   * @param attribute The attribute to filter by.   * @param filter The string, which should be contained.   */ -void Sport::filterCompetitors(QJsonArray &competitors, QString attribute, QString filter) { -    for (int i = 0; i < competitors.size(); i++) { -        QJsonObject comp = competitors[i].toObject(); - -        if (!comp.contains(attribute) || !comp[attribute].toString().contains(filter, Qt::CaseInsensitive)) { -            // remove the competitor, if the attribute does not fit the filter string -            competitors.removeAt(i); +void Sport::filterCompetitors(QList<Competitor> &competitors, QString filter) { +    for (qsizetype i = 0; i < competitors.size(); i++) { +        if (competitors.value(i).getNOC().contains(filter)) { +            competitors.remove(i);              i--;          } -      }  } @@ -398,52 +345,49 @@ void Sport::filterCompetitors(QJsonArray &competitors, QString attribute, QStrin   * @brief Sport::sortByName Sort the competitors by their name (alphabetical, ascending).   * @param competitors The competitors of one category.   */ -void Sport::sortByName(QJsonArray &competitors) { -    sortCompetitors(competitors, genCompare( QString("name") )); +void Sport::sortByName(QList<Competitor> &competitors) { +    if (competitors.isEmpty()) return; +    sort(competitors.begin(), competitors.end(), Competitor::compareName);  }  /**   * @brief Sport::sortByCountry Sort the competitors by their national olympic comittee short name (alphabetical, ascending).   * @param competitors The competitors of one category.   */ -void Sport::sortByCountry(QJsonArray &competitors) { -    sortCompetitors(competitors, genCompare( QString("noc") )); +void Sport::sortByCountry(QList<Competitor> &competitors) { +    if (competitors.isEmpty()) return; +    sort(competitors.begin(), competitors.end(), Competitor::compareNOC);  }  /**   * @brief Sport::sortByResult Sort the competitors by their results in one specific category (numerical, ascending).   * @param competitors The competitors of one category.   */ -void Sport::sortByResult(QJsonArray &competitors) { +void Sport::sortByResult(QList<CompetitorWithResults> &competitors) {      if (competitors.isEmpty()) return; - -    QJsonObject comp = competitors[0].toObject(); - -    if (comp.contains("results")) sortCompetitors(competitors, compareMark); -    else if (comp.contains("medals")) sortCompetitors(competitors, compareMedals); +    sort(competitors.begin(), competitors.end(), CompetitorWithResults::compare);  }  /** - * @brief Sport::sortCompetitors Sorts the given QJsonArray according to the compare function. + * @brief Sport::sortByMedals Sort the competitors by their medal amounts in one specific category (numerical, ascending).   * @param competitors The competitors of one category. - * @param compare A function to compare two competitors with each other. This defines the order.   */ -void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) { -    make_heap(competitors.begin(), competitors.end(), compare); -    sort_heap(competitors.begin(), competitors.end(), compare); +void Sport::sortByMedals(QList<MedalWinner> &competitors) { +    if (competitors.isEmpty()) return; +    sort(competitors.begin(), competitors.end(), MedalWinner::compare);  }  /**   * @brief Sport::reverseOrder Reverses the order of the competitors.   * @param competitors The competitors of one category.   */ -void Sport::reverseOrder(QJsonArray &competitors) { +void Sport::reverseOrder(QList<Competitor> &competitors) {      int iterations = competitors.size() / 2; // automatically rounds down      for (int i = 0; i < iterations; i++) { -        QJsonObject temp = competitors[i].toObject(); -        competitors[i] = competitors[competitors.size() - 1 - i].toObject(); -        competitors[competitors.size() - 1 - i] = temp; +        Competitor temp = competitors.value(i); +        competitors.replace(i, competitors.value(competitors.size() - 1 - i)); +        competitors.replace(competitors.size() - 1 - i, temp);      }  } @@ -452,35 +396,22 @@ void Sport::reverseOrder(QJsonArray &competitors) {   * Stores the statistic in obj->results->stat for each competitor.   * @param competitors The competitors of one category.   */ -void Sport::addRelativeToFirst(QJsonArray &competitors) { +void Sport::addRelativeToFirst(QList<CompetitorWithResults> &competitors) {      if (competitors.isEmpty()) return; -    QJsonObject reference = competitors[0].toObject(); - -    // validate competitors -    if (!reference.contains("results")) return; - -    QString refVal = reference["results"].toObject()["mark"].toString(); +    QString reference = competitors.value(0).getMark(); -    for (int i = 0; i < competitors.size(); i++) { -        QJsonObject competitor = competitors[i].toObject(); -        QJsonObject results = competitor["results"].toObject(); - -        if (results.contains("stat")) results.remove("stat"); +    for (CompetitorWithResults comp : competitors) { +        QString results = comp.getMark();          // format relative float value to string with 2 digits after decimal point and sign          stringstream sstream; -        sstream << fixed << setprecision(2) << calcRelativeStat(refVal, results["mark"].toString()); +        sstream << fixed << setprecision(2) << calcRelativeStat(reference, results["mark"].toString());          QString stat(sstream.str().c_str());          stat.append("%");          if (stat.at(0).isNumber()) stat = QString("+").append(stat); -        results.insert("stat", stat); - -        competitor.remove("results"); -        competitor.insert("results", results); - -        competitors.replace(i, competitor); +        comp.setStatistic(stat);      }  } diff --git a/src/model/Sport.h b/src/model/Sport.h index 6a68570..2ca83a3 100644 --- a/src/model/Sport.h +++ b/src/model/Sport.h @@ -1,6 +1,8 @@  #ifndef ITAT_CHALLANGE_OLYMPICS_SPORT_H  #define ITAT_CHALLANGE_OLYMPICS_SPORT_H +#include "MedalWinner.h" +#include "CompetitorWithResults.h"  #include <QAbstractListModel>  #include <QNetworkAccessManager>  #include <qcontainerfwd.h> @@ -9,33 +11,35 @@  #include <QJsonObject>  #include <QJsonDocument>  #include <QString> +#include <QList>  #include "EventInfo.h"  using namespace std; -class SportModel : public QAbstractListModel { +class SportModel : public QAbstractListModel +{    Q_OBJECT    Q_PROPERTY(QString discipline READ discipline WRITE setDiscipline NOTIFY disciplineChanged); -  public:  -    enum Role { -      EventName = Qt::UserRole + 1, -      Competitors -    }; - -    explicit SportModel(QObject *parent = nullptr); +public: +  enum Role +  { +    EventName = Qt::UserRole + 1, +    Competitors +  }; -    virtual int rowCount(const QModelIndex &parent) const override; -    virtual QVariant data(const QModelIndex &index, int role) const override; -    virtual QHash<int, QByteArray> roleNames() const override; +  explicit SportModel(QObject *parent = nullptr); +  virtual int rowCount(const QModelIndex &parent) const override; +  virtual QVariant data(const QModelIndex &index, int role) const override; +  virtual QHash<int, QByteArray> roleNames() const override; -    QString discipline() const; -    void setDiscipline(const QString &discipline); -  public slots: -    void request(QString discipline); -    void parseData(); +  QString discipline() const; +  void setDiscipline(const QString &discipline); +public slots: +  void request(QString discipline); +  void parseData();    signals:      void disciplineChanged(); @@ -47,81 +51,80 @@ class SportModel : public QAbstractListModel {      QNetworkReply *m_reply = nullptr;  }; -class Sport { +class Sport +{  public: - -    Sport(QJsonObject discipline) { -        this->discipline = discipline; -    } - -    set<QString> getCategories(); -    QJsonArray getCompetitorsByCategory(QString category); -    QJsonArray getCompetitorsWithMedal(); - -    // filter to change the current competitor array -    void lastName(QJsonArray &competitors); -    void filterByName(QJsonArray &competitors, QString name); -    void filterByCountry(QJsonArray &competitors, QString nocShort); - -    // sort functions to change the order of the current competitor array -    void sortByName(QJsonArray &competitors); -    void sortByCountry(QJsonArray &competitors); -    void sortByResult(QJsonArray &competitors); -    void reverseOrder(QJsonArray &competitors); - -    // statistic function(s) -    void addRelativeToFirst(QJsonArray &competitors); - -    void setDiscipline(QJsonObject discipline) { -        this->discipline = QJsonObject(discipline); -    } +  Sport(QJsonObject discipline) +  { +    this->discipline = discipline; +  } + +  set<QString> getCategories(); +  QList<CompetitorWithResults> getCompetitorsByCategory(QString category); +  QList<MedalWinner> getCompetitorsWithMedal(); + +  // filter to change the current competitor array +  void lastName(QList<Competitor> &competitors); +  void filterByName(QList<Competitor> &competitors, QString name); +  void filterByCountry(QList<Competitor> &competitors, QString nocShort); + +  // sort functions to change the order of the current competitor array +  void sortByName(QList<Competitor> &competitors); +  void sortByCountry(QList<Competitor> &competitors); +  void sortByResult(QList<CompetitorWithResults> &competitors); +  void sortByMedals(QList<MedalWinner> &competitors); +  void reverseOrder(QList<Competitor> &competitors); + +  // statistic function(s) +  void addRelativeToFirst(QList<CompetitorWithResults> &competitors); + +  void setDiscipline(QJsonObject discipline) +  { +    this->discipline = QJsonObject(discipline); +  }  private: - -    /* -     * Analysis of provided competitor objects: -     * -     * Attributes: -     * - code -     * - noc (national olympics comittee) -     * - name (sometimes the country name? mostly the competitors name) -     * - order -     * [- results] (only if the results are out!) -     * -     * -     * Analysis of provided result objects: -     * -     * Attributes: -     * - position -     * - mark -     * - medalType -     * - irk -     * [- winnerLoserTie] (only if provided in the discipline?) -     * -     * Analysis of where to find the medal winners: -     * -     * Search for ... in category name. -     * - "Bronze" -     * - "Gold" -     * - "Final" -     * -     * ! ATTENTION ! -     * When searching for "Final" there might be "Final A", "Final B", etc. -     * The results will only be in ONE of these categories! -     * -> which is good... cause then we can count occurences. -     */ -    QJsonObject discipline; - -    void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter); -    void sortCompetitors(QJsonArray &competitors,  function<bool (const QJsonValue &left, const QJsonValue &right)> compare); - -    bool validateDiscipline(); -    QJsonObject createCompetitorWithMedals(QJsonObject medalComp); - -    float calcRelativeStat(QString ref, QString val); - +  /* +   * Analysis of provided competitor objects: +   * +   * Attributes: +   * - code +   * - noc (national olympics comittee) +   * - name (sometimes the country name? mostly the competitors name) +   * - order +   * [- results] (only if the results are out!) +   * +   * +   * Analysis of provided result objects: +   * +   * Attributes: +   * - position +   * - mark +   * - medalType +   * - irk +   * [- winnerLoserTie] (only if provided in the discipline?) +   * +   * Analysis of where to find the medal winners: +   * +   * Search for ... in category name. +   * - "Bronze" +   * - "Gold" +   * - "Final" +   * +   * ! ATTENTION ! +   * When searching for "Final" there might be "Final A", "Final B", etc. +   * The results will only be in ONE of these categories! +   * -> which is good... cause then we can count occurences. +   */ +  QJsonObject discipline; + +  void filterCompetitors(QList<Competitor> &competitors, QString filter); + +  bool validateDiscipline(); +  QJsonObject createCompetitorWithMedals(QJsonObject medalComp); + +  float calcRelativeStat(QString ref, QString val);  }; - -#endif  +#endif | 
