Files
Rennbahn/result.cpp

472 lines
15 KiB
C++

#include "result.h"
#include "ui_result.h"
#include <QTableWidgetItem>
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <iomanip> // setprecision
#include <iostream>
#include <math.h>
#include <qcolor.h>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
Result::Result(DataBase * db, QWidget * parent)
: QWidget(parent), ui(new Ui::Result) {
ui->setupUi(this);
this->db = db;
// prepare dummy data
vector<std::string> header;
// dummy for now
this->rennid = 39;
// test data
header.push_back("Spalte 1");
header.push_back("Spalte 2");
vector<vector<int>> data;
vector<int> subData;
subData.push_back(1);
subData.push_back(2);
data.push_back(subData);
data.push_back(subData);
this->ui->tWResult->resizeColumnsToContents();
this->ui->tWResult->horizontalHeader()->setStretchLastSection(true);
this->ui->tWResult->verticalHeader()->setVisible(true);
// this->model->setHeaderData(0, Qt::Horizontal, "Test");
// connects
// this->ui->pbClose->clicked()
std::stringstream statement;
statement << "select date from rennen where id like "
<< boost::lexical_cast<string>(rennid);
try {
QString renndatum = this->db->getData2(statement.str(), 1).at(0).at(0);
this->setWindowTitle(renndatum);
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "Renndatum konnt aus Datenbank nicht gelesen werden" << endl;
}
// clear stringstream
statement.str(std::string());
statement << "select minimumroundtime from rennen where id like "
<< boost::lexical_cast<string>(rennid);
try {
this->minimumTime =
this->db->getData2(statement.str(), 1).at(0).at(0).toInt();
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "Minimalzeit pro Runde konnte aus Datenbank nicht gelesen "
"werden."
<< endl;
}
vector<string> Fahrernamen;
for (size_t i = 0; i < this->getFahrerIds(this->rennid).size(); i++) {
Fahrernamen.push_back(
this->getFahrerName(this->getFahrerIds(this->rennid).at(i)));
}
vector<int> AutoIds = this->getAutoIds(this->rennid);
this->ui->tWResult->setRowCount(static_cast<int>(AutoIds.size()) * 2 + 4);
this->ui->tWResult->setColumnCount(static_cast<int>(Fahrernamen.size()) +
4);
int row = 0;
int col = 0;
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Auto"));
row += 0;
col += 1;
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Bahn"));
col += 1;
for (string fahrername : Fahrernamen) {
this->ui->tWResult->setItem(
row, col, new QTableWidgetItem(QString::fromStdString(fahrername)));
col += 1;
}
this->ui->tWResult->setItem(row, col,
new QTableWidgetItem("Durchschnitt Auto"));
col += 1;
this->ui->tWResult->setItem(
row, col, new QTableWidgetItem("Durchschnitt Auto gesamt"));
this->ui->tWResult->resizeColumnsToContents();
row = 1;
col = 1;
for (size_t i = 0; i <= AutoIds.size(); i++) {
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Shell"));
row += 1;
this->ui->tWResult->setItem(row, col, new QTableWidgetItem("Dea"));
row += 1;
}
vector<string> AutoNamen;
for (size_t i = 0; i < AutoIds.size(); i++) {
AutoNamen.push_back(this->getAutoName(AutoIds.at(i)));
}
col = 0;
row = 1;
for (string autoname : AutoNamen) {
this->ui->tWResult->setItem(
row, col, new QTableWidgetItem(QString::fromStdString(autoname)));
row += 2;
}
this->ui->tWResult->setItem(row, col,
new QTableWidgetItem("Durchschnitt Person"));
row += 2;
this->ui->tWResult->setItem(
row, col, new QTableWidgetItem("Durchschnitt Person ges"));
row = 1;
col = 2;
vector<vector<float>> zeiten;
vector<float> subZeiten;
for (int fahrer : this->getFahrerIds(this->rennid)) {
for (int car : this->getAutoIds(this->rennid)) {
int shellmin = this->getMinimum(fahrer, 1, this->rennid, car,
this->minimumTime);
int deamin = this->getMinimum(fahrer, 2, this->rennid, car,
this->minimumTime);
subZeiten.push_back(static_cast<float>(shellmin) / 1000);
subZeiten.push_back(static_cast<float>(deamin) / 1000);
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(static_cast<double>(shellmin) / 1000, 3))));
row += 1;
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(static_cast<double>(deamin) / 1000, 3))));
row += 1;
}
zeiten.push_back(subZeiten);
subZeiten.clear();
col += 1;
row = 1;
}
// Durchschnitt Fahrer Shell und Dea
row = static_cast<int>(AutoNamen.size()) * 2 + 1;
col = 2;
for (size_t i = 0; i < Fahrernamen.size(); i++) {
vector<float> shellListe;
vector<float> dealiste;
for (size_t k = 0; k < zeiten.at(i).size(); k++) {
if (k % 2 == 0) {
shellListe.push_back(zeiten.at(i).at(k));
}
else {
dealiste.push_back(zeiten.at(i).at(k));
}
}
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(this->meanVal(shellListe), 3))));
row += 1;
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(this->meanVal(dealiste), 3))));
row -= 1;
col += 1;
shellListe.clear();
dealiste.clear();
}
// Durchschnitt Auto Shell und Dea
col = static_cast<int>(Fahrernamen.size()) + 2;
row = 1;
vector<float> durschnittAuto;
for (size_t i = 0; i < AutoIds.size() * 2; i++) { //*2 weil 2 Bahnen
for (size_t k = 0; k < Fahrernamen.size(); k++) {
durschnittAuto.push_back(zeiten.at(k).at(i));
}
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(this->meanVal(durschnittAuto), 3))));
row += 1;
durschnittAuto.clear();
}
// Durchschnitt Fahrer ges
row = static_cast<int>(AutoIds.size()) * 2 + 3;
col = 2;
for (size_t i = 0; i < Fahrernamen.size(); i++) {
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(this->meanVal(zeiten.at(i)), 3))));
col += 1;
}
// Durchschnitt Auto ges
col = static_cast<int>(Fahrernamen.size()) + 3;
row = 1;
for (size_t i = 0; i < AutoIds.size() * 2; i++) { //*2 weil 2 Bahnen
if (i % 2 == 0) {
vector<float> durschnittAuto;
for (size_t k = 0; k < Fahrernamen.size(); k++) {
durschnittAuto.push_back(zeiten.at(k).at(i));
durschnittAuto.push_back(zeiten.at(k).at(i + 1));
}
this->ui->tWResult->setItem(
row, col,
new QTableWidgetItem(QString::fromStdString(
this->myRound(this->meanVal(durschnittAuto), 3))));
row += 2;
durschnittAuto.clear();
}
}
// Minimum durchschnitt markieren
row = static_cast<int>(AutoIds.size()) * 2 + 3;
col = 2;
vector<float> avgList;
for (size_t i = 0; i < Fahrernamen.size(); i++) {
QString value = this->ui->tWResult->item(row, col)->text();
avgList.push_back(value.toFloat());
col += 1;
}
row = static_cast<int>(AutoIds.size()) * 2 + 3;
col = 2;
for (size_t i = 0; i < Fahrernamen.size(); i++) {
if (this->myMin(avgList) ==
this->ui->tWResult->item(row, col)->text().toFloat()) {
this->ui->tWResult->item(row, col)->setBackground(
QColor(118, 238, 0));
}
col += 1;
}
// minimum abs markieren
// minimum finden
vector<float> temp;
for (size_t i = 0; i < zeiten.size(); i++) {
temp.push_back(this->myMin(zeiten.at(i)));
}
float minimum = this->myMin(temp);
col = 2;
row = 1;
for (size_t i = 0; i < Fahrernamen.size(); i++) {
for (size_t k = 0; k < AutoIds.size() * 2; k++) {
// self.tWRennergebnis.item(row + k, col +
// i).setBackground(QtGui.QColor(255, 215, 0))
if (this->ui->tWResult->item(row + k, col + i)->text().toFloat() ==
minimum) {
this->ui->tWResult
->item(row + static_cast<int>(k), col + static_cast<int>(i))
->setBackground(QColor(255, 215, 0));
}
}
}
this->ui->tWResult->resizeColumnsToContents();
this->ui->tWResult->horizontalHeader()->setStretchLastSection(true);
}
Result::~Result() {
cout << "result closed" << endl;
}
template <typename T> T Result::myMin(vector<T> vec) {
T min;
if (vec.size() > 0) {
min = vec.at(0);
}
else {
return 9999;
}
for (T minItr : vec) {
if (min > minItr) {
min = minItr;
}
}
return min;
}
template <typename T> double Result::meanVal(vector<T> vec) {
T sum = std::accumulate(vec.begin(), vec.end(), 0.0);
double mean = static_cast<double>(sum) / vec.size();
return mean;
}
string Result::myRound(double x, int d = 0) {
std::stringstream stream;
stream << std::fixed << std::setprecision(d) << x;
return stream.str();
}
void Result::closeWindow() {
this->close();
}
vector<int> Result::getFahrerIds(int rennid) {
std::stringstream statement;
statement << "select id_fahrer from zeiten where id_rennen like "
<< boost::lexical_cast<string>(rennid) << " group by id_fahrer";
vector<int> vecToRet;
try {
vector<vector<QString>> ret = this->db->getData2(statement.str(), 1);
for (size_t i = 0; i < ret.size(); i++) {
string strValue = ret.at(i).at(0).toStdString();
vecToRet.push_back(boost::lexical_cast<int>(strValue));
}
return vecToRet;
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "FahrerIds konnten nicht aus Datenbank gelesen "
"werden."
<< endl;
}
return vecToRet;
}
vector<int> Result::getAutoIds(int rennid) {
std::stringstream statement;
statement << "select id_auto from zeiten where id_rennen like "
<< boost::lexical_cast<string>(rennid) << " group by id_auto";
vector<vector<QString>> ret = this->db->getData2(statement.str(), 1);
vector<int> vecToRet;
try {
vector<vector<QString>> ret = this->db->getData2(statement.str(), 1);
for (size_t i = 0; i < ret.size(); i++) {
string strValue = ret.at(i).at(0).toStdString();
vecToRet.push_back(boost::lexical_cast<int>(strValue));
}
return vecToRet;
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "AutoIds konnten nicht aus Datenbank gelesen werden." << endl;
}
return vecToRet;
}
int Result::getMinimum(int fahrerId, int bahnId, int rennId, int autoid,
int minTime) {
std::stringstream statement;
statement << "select zeit from Zeiten where id_rennen like "
<< boost::lexical_cast<string>(rennId) << " and id_fahrer like "
<< boost::lexical_cast<string>(fahrerId) << " and id_auto like "
<< boost::lexical_cast<string>(autoid) << " and id_bahn like "
<< boost::lexical_cast<string>(bahnId);
try {
vector<vector<QString>> res = this->db->getData2(statement.str(), 1);
// filter impossible values
vector<int> validTimes;
for (size_t i = 0; i < res.size(); i++) {
int timeToCompare = res.at(i).at(0).toInt();
if (timeToCompare >= minTime) {
validTimes.push_back(timeToCompare);
}
}
if (validTimes.size() > 0) {
std::vector<int>::iterator result =
std::min_element(validTimes.begin(), validTimes.end());
return *result;
}
else {
return 9999;
}
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "Minimalzeit konnte aus Datenbank nicht gelesen "
"werden."
<< endl;
}
return 9999;
}
float Result::getMean(int fahrerid, int bahnid, int rennid) {
vector<int> autoids = this->getAutoIds(rennid);
vector<int> avg;
for (int car : autoids) {
avg.push_back(
this->getMinimum(fahrerid, bahnid, rennid, car, this->minimumTime));
}
int sum = std::accumulate(avg.begin(), avg.end(), 0);
float floatAvg = 9999;
if (avg.size() > 0) {
floatAvg = static_cast<float>(sum) / static_cast<int>(avg.size());
cout << "avg:" << floatAvg << endl;
return floatAvg;
}
return 9999;
}
string Result::getFahrerName(int id) {
std::stringstream statement;
statement << "select name from fahrer where id like "
<< boost::lexical_cast<string>(id);
vector<vector<QString>> result = this->db->getData2(statement.str(), 1);
if (result.size() > 0) {
try {
return result.at(0).at(0).toStdString();
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "Fehler beim Lesen vom Fahrernamen." << endl;
return "Leer";
}
}
return "Leer";
}
string Result::getAutoName(int id) {
std::stringstream statement;
statement << "select date from Rennen where id like "
<< boost::lexical_cast<string>(this->rennid);
string renndatum;
try {
QString qstrRenndatum =
this->db->getData2(statement.str(), 1).at(0).at(0);
renndatum = qstrRenndatum.toStdString();
} catch (std::exception & e) {
Q_UNUSED(e);
cout << "Renndatum konnte nicht gelesen werden." << endl;
return "nix";
}
try {
// clear stringstream
statement.str(std::string());
statement << "select name from Autokonfiguration where "
"id_auto like "
<< boost::lexical_cast<string>(id) << " and seit < '"
<< renndatum << "' order by seit DESC limit 1";
QString name = this->db->getData2(statement.str(), 1).at(0).at(0);
return name.toStdString();
} catch (std::exception & e) {
Q_UNUSED(e);
}
return "name";
}