Reworked Sport class to work with QObjects instead of JSON objects.
This commit is contained in:
parent
5f4431e19c
commit
c527aec94d
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -123,60 +123,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,}");
|
||||
|
@ -189,15 +145,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,8 +187,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;
|
||||
|
||||
|
@ -252,21 +203,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){
|
||||
|
@ -320,9 +271,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;
|
||||
|
@ -361,8 +312,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -370,8 +321,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -380,16 +331,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--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,52 +344,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,35 +395,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();
|
||||
QString reference = competitors.value(0).getMark();
|
||||
|
||||
// validate competitors
|
||||
if (!reference.contains("results")) return;
|
||||
|
||||
QString refVal = reference["results"].toObject()["mark"].toString();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,17 +11,20 @@
|
|||
#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);
|
||||
|
||||
public:
|
||||
enum Role {
|
||||
enum Role
|
||||
{
|
||||
EventName = Qt::UserRole + 1,
|
||||
Competitors
|
||||
};
|
||||
|
@ -30,7 +35,6 @@ class SportModel : public QAbstractListModel {
|
|||
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:
|
||||
|
@ -44,38 +48,40 @@ class SportModel : public QAbstractListModel {
|
|||
QNetworkReply *m_reply = nullptr;
|
||||
};
|
||||
|
||||
class Sport {
|
||||
class Sport
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Sport(QJsonObject discipline) {
|
||||
Sport(QJsonObject discipline)
|
||||
{
|
||||
this->discipline = discipline;
|
||||
}
|
||||
|
||||
set<QString> getCategories();
|
||||
QJsonArray getCompetitorsByCategory(QString category);
|
||||
QJsonArray getCompetitorsWithMedal();
|
||||
QList<CompetitorWithResults> getCompetitorsByCategory(QString category);
|
||||
QList<MedalWinner> getCompetitorsWithMedal();
|
||||
|
||||
// filter to change the current competitor array
|
||||
void lastName(QJsonArray &competitors);
|
||||
void filterByName(QJsonArray &competitors, QString name);
|
||||
void filterByCountry(QJsonArray &competitors, QString nocShort);
|
||||
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(QJsonArray &competitors);
|
||||
void sortByCountry(QJsonArray &competitors);
|
||||
void sortByResult(QJsonArray &competitors);
|
||||
void reverseOrder(QJsonArray &competitors);
|
||||
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(QJsonArray &competitors);
|
||||
void addRelativeToFirst(QList<CompetitorWithResults> &competitors);
|
||||
|
||||
void setDiscipline(QJsonObject discipline) {
|
||||
void setDiscipline(QJsonObject discipline)
|
||||
{
|
||||
this->discipline = QJsonObject(discipline);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
* Analysis of provided competitor objects:
|
||||
*
|
||||
|
@ -110,15 +116,12 @@ private:
|
|||
*/
|
||||
QJsonObject discipline;
|
||||
|
||||
void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter);
|
||||
void sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare);
|
||||
void filterCompetitors(QList<Competitor> &competitors, QString filter);
|
||||
|
||||
bool validateDiscipline();
|
||||
QJsonObject createCompetitorWithMedals(QJsonObject medalComp);
|
||||
|
||||
float calcRelativeStat(QString ref, QString val);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue