Added method to reverse order and statistic method.

This commit is contained in:
Steru 2024-08-05 14:47:45 +02:00
parent 2476684e3c
commit c539242efa
2 changed files with 94 additions and 1 deletions

View file

@ -1,10 +1,18 @@
#include "Sport.h" #include "Sport.h"
// categories
#include <set> #include <set>
// sorting and filtering
#include <map> #include <map>
#include <algorithm> #include <algorithm>
#include <regex> #include <regex>
// float to string formatting
#include <iostream>
#include <iomanip>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonValueRef> #include <QJsonValueRef>
@ -164,7 +172,6 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {
* @brief Sport::getCompetitorsWithMedal Filters all competitors, who have at least one medal. These objects are different from getCompetitorsByCategory !!! * @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}} * @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() { QJsonArray Sport::getCompetitorsWithMedal() {
map<QString, QJsonObject> competitors; map<QString, QJsonObject> competitors;
@ -334,3 +341,83 @@ void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonV
sort_heap(competitors.begin(), competitors.end(), compare); sort_heap(competitors.begin(), competitors.end(), compare);
} }
/**
* @brief Sport::reverseOrder Reverses the order of the competitors.
* @param competitors The competitors of one category.
*/
void Sport::reverseOrder(QJsonArray &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;
}
}
/**
* @brief Sport::addRelativeToFirst Adds a relative value to the result of all competitors. Relative to the first competitor in the QJsonArray.
* Stores the statistic in obj->results->stat for each competitor.
* @param competitors The competitors of one category.
*/
void Sport::addRelativeToFirst(QJsonArray &competitors) {
if (competitors.isEmpty()) return;
QJsonObject reference = competitors[0].toObject();
// 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");
// 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());
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);
}
}
/**
* @brief Sport::calcRelativeStat Calculates the relative deviation of val from ref in percent.
* @param ref The reference value.
* @param val The value to calculate the deviation from.
* @return The deviation from ref to val in percent.
*/
float Sport::calcRelativeStat(QString ref, QString val) {
// check if the value is not a time
if (!ref.contains(":") && !val.contains(":")) {
float fRef = ref.toFloat();
if (fRef == 0) return 0.0;
return ((val.toFloat() * 100)/ fRef) - 100;
}
regex r("\\d+");
smatch mref, mval;
string sref = ref.toUtf8().constData();
string sval = val.toUtf8().constData();
regex_search(sref, mref, r);
regex_search(sval, mval, r);
float timeRef = stof(mref.str(1)) * 60 * 100 + stof(mref.str(2)) * 100 + stof(mref.str(3));
float timeVal = stof(mval.str(1)) * 60 * 100 + stof(mval.str(2)) * 100 + stof(mval.str(3));
return ((timeVal * 100) / timeRef) - 100;
}

View file

@ -33,6 +33,10 @@ public:
void sortByName(QJsonArray &competitors); void sortByName(QJsonArray &competitors);
void sortByCountry(QJsonArray &competitors); void sortByCountry(QJsonArray &competitors);
void sortByResult(QJsonArray &competitors); void sortByResult(QJsonArray &competitors);
void reverseOrder(QJsonArray &competitors);
// statistic function(s)
void addRelativeToFirst(QJsonArray &competitors);
void setDiscipline(QJsonObject discipline) { void setDiscipline(QJsonObject discipline) {
this->discipline = QJsonObject(discipline); this->discipline = QJsonObject(discipline);
@ -80,6 +84,8 @@ private:
bool validateDiscipline(); bool validateDiscipline();
QJsonObject createCompetitorWithMedals(QJsonObject medalComp); QJsonObject createCompetitorWithMedals(QJsonObject medalComp);
float calcRelativeStat(QString ref, QString val);
}; };