Added another filter and sort functions. Also using mock data to test.

This commit is contained in:
Steru 2024-08-03 20:19:05 +02:00
parent a767d83d81
commit d399c562f5
5 changed files with 155 additions and 38 deletions

View file

@ -12,6 +12,7 @@
#include <QUrlQuery>
// json parsing
#include <QFile>
#include <QJsonValue>
#include <QJsonDocument>
#include <QJsonObject>
@ -29,6 +30,7 @@ using namespace std;
QJsonObject OlympicsAPI::getSportData(OlympicsAPI::Disciplines sport) {
string shortName = this->getDisciplineShort(sport);
if (USE_API_REQUEST) {
// create custom temporary event loop on stack
QEventLoop eventLoop;
@ -63,7 +65,19 @@ QJsonObject OlympicsAPI::getSportData(OlympicsAPI::Disciplines sport) {
throw invalid_argument("API request failed.");
}
}
// if API is not used, open locally stored data
QString filePath = ("../../res/mock/" + shortName + ".json").c_str();
QFile file( filePath );
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
throw invalid_argument("Could not open file to read data of the given discipline.");
} else {
QString text = file.readAll();
file.close();
return (QJsonDocument::fromJson(text.toUtf8())).object();
}
}
/**

View file

@ -8,17 +8,10 @@
#include <string>
#include <QJsonObject>
using namespace std;
// TODO: change this to true to use the olympics api, instead of the mock date in res/mock/
#define USE_API_REQUEST false
/*
* TODO:
* Replace api request code snippet in main with:
*
OlympicsAPI api;
QJsonObject archery = api.getSportData(api.Archery);
qDebug() << "Competitor:" << archery["units"][0]["competitors"][0]["name"].toString();
*
*/
using namespace std;
class OlympicsAPI {

View file

@ -1,12 +1,34 @@
#include "Sport.h"
#include <set>
#include <algorithm>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValueRef>
#include <QString>
// 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) {
QJsonObject l = left.toObject();
if (!l.contains("results")) return true;
QJsonObject r = right.toObject();
if (!r.contains("results")) return false;
float lMark = l["results"].toObject()["mark"].toString().toFloat();
float rMark = r["results"].toObject()["mark"].toString().toFloat();
return lMark < rMark;
}
/**
* @brief Sport::getCategories Reads all possible categories (also called units).
@ -44,5 +66,65 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {
}
}
return competitors;
return QJsonArray(competitors);
}
/**
* @brief Sport::filterByName Filter the competitors by name (case insensitive).
* @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);
}
/**
* @brief Sport::filterByCountry Filter the competitors by their national olympics comittee (case insensitive, short form).
* @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::filterCompetitors(QJsonArray &competitors, QString attribute, QString filter) {
for (int i = 0; i < competitors.size(); i++) {
if (!competitors[i].toObject()[attribute].toString().contains(filter, Qt::CaseInsensitive)) {
// remove the competitor, if the attribute does not fit the filter string
competitors.removeAt(i);
i--;
}
}
}
/**
* @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") ));
}
/**
* @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") ));
}
/**
* @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) {
sortCompetitors(competitors, compareMark);
}
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);
}

View file

@ -23,18 +23,46 @@ public:
set<QString> getCategories();
QJsonArray getCompetitorsByCategory(QString category);
// chainable
QJsonObject filterByName(QJsonObject discipline, QString name);
QJsonObject filterByCountry(QJsonObject discipline, QString name);
// filter to change the current competitor array
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 setDiscipline(QJsonObject discipline) {
this->discipline = 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?)
*/
QJsonObject discipline;
void filterCompetitors(QJsonArray& competitors, QString attribute, QString filter);
void sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare);
};