Added method to get medal winners. Adjusted sort result method to also work with the medal winners.
This commit is contained in:
parent
0445396ffa
commit
77f8836508
|
@ -12,19 +12,69 @@ https://olympics.com/en/paris-2024/sports
|
||||||
Pictograms:
|
Pictograms:
|
||||||
https://olympics.com/en/paris-2024/the-games/the-brand/pictograms
|
https://olympics.com/en/paris-2024/the-games/the-brand/pictograms
|
||||||
|
|
||||||
API Request for Archery Data:
|
### API Request for Archery Data (replace ARC with other short from table below for different disciplines):
|
||||||
```js
|
```js
|
||||||
await (await fetch("https://sph-s-api.olympics.com/summer/schedules/api/ENG/schedule/discipline/ARC", {
|
await (await fetch("https://sph-s-api.olympics.com/summer/schedules/api/ENG/schedule/discipline/ARC", {
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
})).json();
|
})).json();
|
||||||
```
|
```
|
||||||
Table for \[ABC\]:
|
|
||||||
|
**NOTE:** You can switch between API and mock data in "src/api/OlympicsAPI.h" with the defined value "USE_API_REQUEST".
|
||||||
|
|
||||||
|
### Table for discipline short names from the IOC (International Olympics Comittee):
|
||||||
|
|
||||||
|Sport|Short|
|
|Sport|Short|
|
||||||
|---|---|
|
|---|---|
|
||||||
|
|AquaticsArtisticSwimming|SWA|
|
||||||
|
|AquaticsDiving|DIV|
|
||||||
|
|AquaticsMarathonSwimming|OWS|
|
||||||
|
|AquaticsSwimming|SWM|
|
||||||
|
|AquaticsWaterPolo|WPO|
|
||||||
|Archery|ARC|
|
|Archery|ARC|
|
||||||
|
|Athletics|ATH|
|
||||||
|
|Badminton|BDM|
|
||||||
|Basketball3v3|BK3|
|
|Basketball3v3|BK3|
|
||||||
|
|Basketball|BKB|
|
||||||
|
|Boxing|BOX|
|
||||||
|
|Breaking|BKG|
|
||||||
|
|CanoeingSprint|CSP|
|
||||||
|
|CanoeingSlalom|CSL|
|
||||||
|
|CyclingBMXFreestyle|BMF|
|
||||||
|
|CyclingBMXRacing|BMX|
|
||||||
|
|CyclingMaountainBike|MTB|
|
||||||
|
|CyclingRoad|CRD|
|
||||||
|
|CyclingTrack|CTR|
|
||||||
|
|EquestrianDressage|EDR|
|
||||||
|
|EquestrianEventing|EVE|
|
||||||
|
|EquestrianJumping|EJP|
|
||||||
|
|Fencing|FEN|
|
||||||
|
|FieldHockey|HOC|
|
||||||
|
|Football|FBL|
|
||||||
|
|Golf|GLF|
|
||||||
|
|GymnasticsArtistic|GAR|
|
||||||
|
|GymnasticsRhythmic|GRY|
|
||||||
|
|GymnasticsTrampoline|GTR|
|
||||||
|
|HandballIndoor|HBL|
|
||||||
|
|Judo|JUD|
|
||||||
|
|ModernPentathlon|MPN|
|
||||||
|
|Rowing|ROW|
|
||||||
|
|Rugby7|RU7|
|
||||||
|
|Sailing|SAL|
|
||||||
|
|Shooting|SHO|
|
||||||
|
|Skateboarding|SKB|
|
||||||
|
|SportClimbing|CLB|
|
||||||
|
|Surfing|SRF|
|
||||||
|
|TableTennis|TTE|
|
||||||
|Taekwondo|TKW|
|
|Taekwondo|TKW|
|
||||||
|
|Tennis|TEN|
|
||||||
|
|Triathlon|TRI|
|
||||||
|
|VolleyballBeach|VBV|
|
||||||
|
|VolleyballIndoor|VVO|
|
||||||
|
|Weightlifting|WLF|
|
||||||
|
|WrestlingFreestyle|WRE|
|
||||||
|
|WrestlingGrecoRoman|WRG|
|
||||||
|
|
||||||
|
### Sport Specifics
|
||||||
|
|
||||||
Archery:
|
Archery:
|
||||||
- rules: https://olympics.com/en/paris-2024/sports/archery
|
- rules: https://olympics.com/en/paris-2024/sports/archery
|
||||||
|
|
30768
res/mock/JUD.json
Normal file
30768
res/mock/JUD.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -121,20 +121,20 @@ string OlympicsAPI::getDisciplineShort(OlympicsAPI::Disciplines sport) {
|
||||||
case OlympicsAPI::Disciplines::ModernPentathlon: return "MPN";
|
case OlympicsAPI::Disciplines::ModernPentathlon: return "MPN";
|
||||||
case OlympicsAPI::Disciplines::Rowing: return "ROW";
|
case OlympicsAPI::Disciplines::Rowing: return "ROW";
|
||||||
case OlympicsAPI::Disciplines::Rugby7: return "RU7";
|
case OlympicsAPI::Disciplines::Rugby7: return "RU7";
|
||||||
case OlympicsAPI::Disciplines::Sailing: return "SAL"; break;
|
case OlympicsAPI::Disciplines::Sailing: return "SAL";
|
||||||
case OlympicsAPI::Disciplines::Shooting: return "SHO"; break;
|
case OlympicsAPI::Disciplines::Shooting: return "SHO";
|
||||||
case OlympicsAPI::Disciplines::Skateboarding: return "SKB"; break;
|
case OlympicsAPI::Disciplines::Skateboarding: return "SKB";
|
||||||
case OlympicsAPI::Disciplines::SportClimbing: return "CLB"; break;
|
case OlympicsAPI::Disciplines::SportClimbing: return "CLB";
|
||||||
case OlympicsAPI::Disciplines::Surfing: return "SRF"; break;
|
case OlympicsAPI::Disciplines::Surfing: return "SRF";
|
||||||
case OlympicsAPI::Disciplines::TableTennis: return "TTE"; break;
|
case OlympicsAPI::Disciplines::TableTennis: return "TTE";
|
||||||
case OlympicsAPI::Disciplines::Taekwondo: return "TKW"; break;
|
case OlympicsAPI::Disciplines::Taekwondo: return "TKW";
|
||||||
case OlympicsAPI::Disciplines::Tennis: return "TEN"; break;
|
case OlympicsAPI::Disciplines::Tennis: return "TEN";
|
||||||
case OlympicsAPI::Disciplines::Triathlon: return "TRI"; break;
|
case OlympicsAPI::Disciplines::Triathlon: return "TRI";
|
||||||
case OlympicsAPI::Disciplines::VolleyballBeach: return "VBV"; break;
|
case OlympicsAPI::Disciplines::VolleyballBeach: return "VBV";
|
||||||
case OlympicsAPI::Disciplines::VolleyballIndoor: return "VVO"; break;
|
case OlympicsAPI::Disciplines::VolleyballIndoor: return "VVO";
|
||||||
case OlympicsAPI::Disciplines::Weightlifting: return "WLF"; break;
|
case OlympicsAPI::Disciplines::Weightlifting: return "WLF";
|
||||||
case OlympicsAPI::Disciplines::WrestlingFreestyle: return "WRE"; break;
|
case OlympicsAPI::Disciplines::WrestlingFreestyle: return "WRE";
|
||||||
case OlympicsAPI::Disciplines::WrestlingGrecoRoman: return "WRG"; break;
|
case OlympicsAPI::Disciplines::WrestlingGrecoRoman: return "WRG";
|
||||||
default: return "ARC"; // default, which should not be possible, because of enum
|
default: return "ARC"; // default, which should not be possible, because of enum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include "Sport.h"
|
#include "Sport.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
@ -8,6 +9,21 @@
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonValueRef>
|
#include <QJsonValueRef>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
// QJsonArray filter function, provide with input array and evaluation function
|
||||||
|
QJsonArray filter(QJsonArray input, function<bool (QJsonObject)> eval) {
|
||||||
|
QJsonArray output;
|
||||||
|
|
||||||
|
for (const QJsonValueRef &elemRef :input) {
|
||||||
|
QJsonObject elem = elemRef.toObject();
|
||||||
|
if(eval(elem)) {
|
||||||
|
output.append(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
// static compare function for specific attribute in competitors
|
// static compare function for specific attribute in competitors
|
||||||
function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QString attribute) {
|
function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QString attribute) {
|
||||||
|
@ -20,14 +36,37 @@ function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QStr
|
||||||
|
|
||||||
// static compare function for the results of a competitor in a specific competition (also called mark)
|
// static compare function for the results of a competitor in a specific competition (also called mark)
|
||||||
bool compareMark(const QJsonValue &left, const QJsonValue &right) {
|
bool compareMark(const QJsonValue &left, const QJsonValue &right) {
|
||||||
|
// check if one competitor has no mark
|
||||||
QJsonObject l = left.toObject();
|
QJsonObject l = left.toObject();
|
||||||
if (!l.contains("results")) return true;
|
if (!l.contains("results")) return true;
|
||||||
QJsonObject r = right.toObject();
|
QJsonObject r = right.toObject();
|
||||||
if (!r.contains("results")) return false;
|
if (!r.contains("results")) return false;
|
||||||
|
|
||||||
float lMark = l["results"].toObject()["mark"].toString().toFloat();
|
QString lMark = l["results"].toObject()["mark"].toString();
|
||||||
float rMark = r["results"].toObject()["mark"].toString().toFloat();
|
QString rMark = r["results"].toObject()["mark"].toString();
|
||||||
return lMark < rMark;
|
|
||||||
|
// 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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,19 +122,95 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {
|
||||||
QJsonObject unit = unitRef.toObject();
|
QJsonObject unit = unitRef.toObject();
|
||||||
|
|
||||||
// search all units with the same category
|
// search all units with the same category
|
||||||
if (QString::compare(unit["eventUnitName"].toString(), category, Qt::CaseSensitive) == 0) {
|
if (unit["eventUnitName"].toString().compare(category, Qt::CaseSensitive) != 0) continue;
|
||||||
|
|
||||||
// add all competitors from one unit
|
// add all competitors from one unit
|
||||||
for (const QJsonValueRef &comp : unit["competitors"].toArray()) {
|
for (const QJsonValueRef &comp : unit["competitors"].toArray()) {
|
||||||
competitors.push_back(comp.toObject());
|
competitors.push_back(comp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QJsonArray(competitors);
|
return QJsonArray(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() {
|
||||||
|
map<QString, QJsonObject> competitors;
|
||||||
|
|
||||||
|
// filter all units, which have medal events
|
||||||
|
QJsonArray units = filter(this->discipline["units"].toArray(), [](QJsonObject unit){
|
||||||
|
// search all units with Final, Gold or Bronze in their name, because these are the categories with the medal winners
|
||||||
|
QString unitName = unit["eventUnitName"].toString();
|
||||||
|
return unitName.contains("Bronze", Qt::CaseSensitive)
|
||||||
|
|| unitName.contains("Gold", Qt::CaseSensitive)
|
||||||
|
|| unitName.contains("Final", Qt::CaseSensitive);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const QJsonValueRef &unitRef : units) {
|
||||||
|
QJsonObject unit = unitRef.toObject();
|
||||||
|
|
||||||
|
// filter all competitors, who won medals
|
||||||
|
QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {
|
||||||
|
if (!comp.contains("results")) return false;
|
||||||
|
|
||||||
|
QString medalType = comp["results"].toObject()["medalType"].toString();
|
||||||
|
return !medalType.isEmpty();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const QJsonValueRef &medalCompRef : medalComps) {
|
||||||
|
QJsonObject medalComp = medalCompRef.toObject();
|
||||||
|
|
||||||
|
QString name = medalComp["name"].toString();
|
||||||
|
QString medalType = medalComp["results"].toObject()["medalType"].toString();
|
||||||
|
|
||||||
|
// check if competitor has other medal(s)
|
||||||
|
if (competitors.find(name) == competitors.end()) {
|
||||||
|
competitors.insert({name, createCompetitorWithMedals(medalComp)});
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the medal count
|
||||||
|
QJsonObject updatedMedalCount = QJsonObject(competitors.find(name)->second["medals"].toObject());
|
||||||
|
|
||||||
|
int amount = updatedMedalCount[medalType].toInt() + 1;
|
||||||
|
updatedMedalCount.remove(medalType);
|
||||||
|
updatedMedalCount.insert(medalType, amount);
|
||||||
|
|
||||||
|
// create new medals QJsonObject and set it in the map
|
||||||
|
competitors.find(name)->second["medals"] = updatedMedalCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert map to QJsonArray
|
||||||
|
QJsonArray output;
|
||||||
|
for (const pair<QString, QJsonObject> &competitor : competitors) {
|
||||||
|
output.append(competitor.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject Sport::createCompetitorWithMedals(QJsonObject comp) {
|
||||||
|
// create new competitor QJsonObject and add it to the competitor map
|
||||||
|
QJsonObject medals {
|
||||||
|
{"ME_GOLD", 0},
|
||||||
|
{"ME_SILVER", 0},
|
||||||
|
{"ME_BRONZE", 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
QJsonObject medalComp {
|
||||||
|
{"code", comp["code"].toString()},
|
||||||
|
{"name", comp["name"].toString()},
|
||||||
|
{"noc", comp["noc"].toString()},
|
||||||
|
{"medals", medals}
|
||||||
|
};
|
||||||
|
|
||||||
|
return medalComp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sport::filterByName Filter the competitors by name (case insensitive).
|
* @brief Sport::filterByName Filter the competitors by name (case insensitive).
|
||||||
* @param competitors The competitors of one category.
|
* @param competitors The competitors of one category.
|
||||||
|
@ -147,7 +262,12 @@ void Sport::sortByCountry(QJsonArray &competitors) {
|
||||||
* @param competitors The competitors of one category.
|
* @param competitors The competitors of one category.
|
||||||
*/
|
*/
|
||||||
void Sport::sortByResult(QJsonArray &competitors) {
|
void Sport::sortByResult(QJsonArray &competitors) {
|
||||||
sortCompetitors(competitors, compareMark);
|
if (competitors.isEmpty()) return;
|
||||||
|
|
||||||
|
QJsonObject comp = competitors[0].toObject();
|
||||||
|
|
||||||
|
if (comp.contains("results")) sortCompetitors(competitors, compareMark);
|
||||||
|
else if (comp.contains("medals")) sortCompetitors(competitors, compareMedals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) {
|
void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
|
|
||||||
set<QString> getCategories();
|
set<QString> getCategories();
|
||||||
QJsonArray getCompetitorsByCategory(QString category);
|
QJsonArray getCompetitorsByCategory(QString category);
|
||||||
|
QJsonArray getCompetitorsWithMedal();
|
||||||
|
|
||||||
// filter to change the current competitor array
|
// filter to change the current competitor array
|
||||||
void lastName(QJsonArray &competitors);
|
void lastName(QJsonArray &competitors);
|
||||||
|
@ -58,11 +59,24 @@ private:
|
||||||
* - medalType
|
* - medalType
|
||||||
* - irk
|
* - irk
|
||||||
* [- winnerLoserTie] (only if provided in the discipline?)
|
* [- 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;
|
QJsonObject discipline;
|
||||||
|
|
||||||
void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter);
|
void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter);
|
||||||
void sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare);
|
void sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare);
|
||||||
|
QJsonObject createCompetitorWithMedals(QJsonObject medalComp);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue