#include "result.h" #include "ui_result.h" #include #include #include #include // setprecision #include #include #include #include #include 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 header; // dummy for now this->rennid = 39; // test data header.push_back("Spalte 1"); header.push_back("Spalte 2"); vector> data; vector 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(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(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 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 AutoIds = this->getAutoIds(this->rennid); this->ui->tWResult->setRowCount(static_cast(AutoIds.size()) * 2 + 4); this->ui->tWResult->setColumnCount(static_cast(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 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> zeiten; vector 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(shellmin) / 1000); subZeiten.push_back(static_cast(deamin) / 1000); this->ui->tWResult->setItem( row, col, new QTableWidgetItem(QString::fromStdString( this->myRound(static_cast(shellmin) / 1000, 3)))); row += 1; this->ui->tWResult->setItem( row, col, new QTableWidgetItem(QString::fromStdString( this->myRound(static_cast(deamin) / 1000, 3)))); row += 1; } zeiten.push_back(subZeiten); subZeiten.clear(); col += 1; row = 1; } // Durchschnitt Fahrer Shell und Dea row = static_cast(AutoNamen.size()) * 2 + 1; col = 2; for (size_t i = 0; i < Fahrernamen.size(); i++) { vector shellListe; vector 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(Fahrernamen.size()) + 2; row = 1; vector 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(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(Fahrernamen.size()) + 3; row = 1; for (size_t i = 0; i < AutoIds.size() * 2; i++) { //*2 weil 2 Bahnen if (i % 2 == 0) { vector 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(AutoIds.size()) * 2 + 3; col = 2; vector 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(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 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(k), col + static_cast(i)) ->setBackground(QColor(255, 215, 0)); } } } this->ui->tWResult->resizeColumnsToContents(); this->ui->tWResult->horizontalHeader()->setStretchLastSection(true); } Result::~Result() { cout << "result closed" << endl; } template T Result::myMin(vector 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 double Result::meanVal(vector vec) { T sum = std::accumulate(vec.begin(), vec.end(), 0.0); double mean = static_cast(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 Result::getFahrerIds(int rennid) { std::stringstream statement; statement << "select id_fahrer from zeiten where id_rennen like " << boost::lexical_cast(rennid) << " group by id_fahrer"; vector vecToRet; try { vector> 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(strValue)); } return vecToRet; } catch (std::exception & e) { Q_UNUSED(e); cout << "FahrerIds konnten nicht aus Datenbank gelesen " "werden." << endl; } return vecToRet; } vector Result::getAutoIds(int rennid) { std::stringstream statement; statement << "select id_auto from zeiten where id_rennen like " << boost::lexical_cast(rennid) << " group by id_auto"; vector> ret = this->db->getData2(statement.str(), 1); vector vecToRet; try { vector> 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(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(rennId) << " and id_fahrer like " << boost::lexical_cast(fahrerId) << " and id_auto like " << boost::lexical_cast(autoid) << " and id_bahn like " << boost::lexical_cast(bahnId); try { vector> res = this->db->getData2(statement.str(), 1); // filter impossible values vector 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::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 autoids = this->getAutoIds(rennid); vector 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(sum) / static_cast(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(id); vector> 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(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(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"; }