summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorSteru <jerrydream111@gmail.com>2024-08-15 20:41:08 +0200
committerOrangerot <purple@orangerot.dev>2024-08-26 11:19:38 +0200
commitdf2cd325395886868e64c4d96ba7a959ef7d204e (patch)
tree0917ed288870d4fcba4e8876682aafc4837058d9 /src/model
parent87e9d4aa8b64e4a8262115f678febb241f2ac3d0 (diff)
Reworked Sport class to work with QObjects instead of JSON objects.
Diffstat (limited to 'src/model')
-rw-r--r--src/model/Competitor.h11
-rw-r--r--src/model/CompetitorWithResults.h4
-rw-r--r--src/model/Sport.cpp159
-rw-r--r--src/model/Sport.h179
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