Hauptseite | Klassenhierarchie | Alphabetische Liste | Übersicht | Auflistung der Dateien | Datenstruktur-Elemente | Datei-Elemente

zeitverlauf.cpp

gehe zur Dokumentation dieser Datei
00001 // zeitverlauf.cpp
00002 // LFTVideo.cpp  v1.7
00003 //               12.5.2003
00004 // 
00005 // für weitere Informationen:
00006 // siehe header von main.cpp
00007 
00008 #include "zeitverlauf.h"
00009 
00010 #include <qfile.h>
00011 #include <qtextstream.h>
00012 #include <math.h>                       // für floor
00013 
00014 // class MinSec
00016 
00017 MinSec::MinSec (int mins, double secs, long milliseconds) {
00018         double allesInSekunden= mins*60 + secs + (double) milliseconds/1000;
00019         Min=allesInSekunden / 60;
00020 
00021         Sec=((int) allesInSekunden) % 60 ;
00022         Sec += nachkomma(allesInSekunden);
00023 };
00024 
00025 double MinSec::toSecs() const{
00026         return mins()*60+secs();
00027 };
00028 
00029 double MinSec::secsTo(const MinSec &rhs) const{
00030         return rhs.toSecs() - this->toSecs();
00031 };
00032 
00033 MinSec MinSec::addSecs (double s) const{
00034         return MinSec(0, this->toSecs()+s); 
00035 };
00036 
00037 bool operator ==(const MinSec& x, const MinSec& y){
00038         return x.toSecs() == y.toSecs(); 
00039 }
00040 
00041 bool operator <(const MinSec& x, const MinSec& y){
00042         return x.toSecs() < y.toSecs(); 
00043 };
00044 
00045 MinSec operator -(const MinSec& x, const MinSec& y){
00046         return MinSec(0, y.secsTo(x));
00047 }
00048 
00049 /*
00050 // alt:
00051 double operator -(const MinSec& x, const MinSec& y){
00052         qDebug ("verwendet: double operator -(const MinSec& x, const MinSec& y)");
00053         // Konsequenter ist ein Ergebnistyp MinSec
00054         //       der dann evtl. anschliessend erst per toSecs 
00055         //       in double umgewandelt wird. Siehe oben.
00056 
00057         double xx=x.toSecs();
00058         double yy=y.toSecs();
00059         return xx-yy;
00060 }
00061 */
00062 
00063 struct MinSec::less : public binary_function<MinSec, MinSec, bool>{
00064         bool operator()(const MinSec& x, const MinSec& y) const{
00065                         return x < y; };
00066 };
00067 
00068 // helper: führende Null ausgeben, wenn 0123456789
00069 QString leadingZero(int n){
00070         QString temp="";
00071         if (n<10 && n>=0) temp+="0";
00072         temp+="%1"; 
00073         temp=temp.arg(n);
00074         return temp;
00075 };
00076 
00077 // helper: führende Null ausgeben, wenn <100, zwei Nullen, wenn 0123456789
00078 QString leading2Zeros(int n){
00079         QString temp="";
00080         if (n<100 && n>=0) temp+="0";
00081         temp+="%1"; 
00082         temp=temp.arg(leadingZero(n));
00083         return temp;
00084 };
00085 
00086 // helper: nur die Nachkommastellen zurückgeben, immer positiv
00087 double nachkomma (double zahl){
00088         return fabs(zahl-(long)zahl);
00089 }
00090 
00091 // helper: abrunden wenn < .5, aufrunden, wenn >= .5
00092 double runden (double zahl){
00093         return floor(zahl + 0.5);
00094 }
00095 
00096 
00097 QString MinSec::toQString() const{
00098         QString temp=leadingZero(mins())+":"+leadingZero(secs());
00099         temp+="."+leading2Zeros(millisecs());
00100         return temp;
00101 };
00102 
00103 bool MinSec::liesVonTextStream(QTextStream &s){
00104         
00105         QString in;
00106         s >> in;
00107         int minutes; double seconds;
00108         int Doppelpunkt;
00109         Doppelpunkt=in.find(":");
00110         if (Doppelpunkt<=0) return false;
00111 
00112         bool OK1,OK2;
00113         OK1=true;OK2=true;
00114         minutes=in.left(Doppelpunkt).toInt(&OK1);
00115 
00116         // qDebug (in.right(in.length()-Doppelpunkt-1));
00117         seconds=in.right(in.length()-Doppelpunkt-1).toDouble(&OK2);
00118         
00119         *this=MinSec(minutes, seconds);
00120         return OK1 && OK2;
00121 }
00122         
00123 void MinSec::testFloorInt(){
00124         qDebug("\ntestFloorInt");
00125         double a=123.456;
00126         double b=-123.456;
00127         qDebug("floor(...): %f", floor(a)); 
00128         qDebug("(int)...: %d", (int)a);
00129         qDebug("floor(...): %f", floor(b));
00130         qDebug("(int)...: %d", (int)b);
00131         qDebug("positiv: zahl - (int)zahl...: %f", a-(int)a);
00132         qDebug("negativ: zahl - (int)zahl...: %f", b-(int)b);
00133         qDebug("negativ: fmod(zahl,1)...: %f", fmod(b,1));
00134         qDebug("positiv: nachkomma(zahl)...: %f", nachkomma(a));
00135         qDebug("negativ: nachkomma(zahl)...: %f", nachkomma(b));
00136         a=1.5; b=-1.5;
00137         qDebug("runden(%f) = %d", a, runden(a));
00138         qDebug("runden(%f) = %d", b, runden(b));
00139         a=1.4999; b=-1.4999;
00140         qDebug("runden(%f) = %d", a, runden(a));
00141         qDebug("runden(%f) = %d", b, runden(b));
00142 
00143         qDebug("\n");
00144 };
00145 
00146 
00147 void MinSec::testMinSec(){
00148         qDebug("\ntestMinSec");
00149         MinSec ms(1,12);
00150         qDebug("%f", ms.toSecs());
00151         qDebug(ms.toQString());
00152         MinSec ms2(2,13.05);
00153         qDebug(ms2.toQString());
00154         qDebug("%f\n", ms.secsTo(ms2));
00155 
00156         ms=MinSec (1,12,0);
00157         qDebug("%f", ms.toSecs());
00158         qDebug(ms.toQString());
00159         ms2=MinSec (2,13,50);
00160         qDebug(ms2.toQString());
00161         qDebug("%f\n", ms.secsTo(ms2));
00162 
00163         QString testdata="12:34.567";
00164         MinSec liesZeitEin;
00165         liesZeitEin.liesVonTextStream( QTextIStream(&testdata) );
00166         qDebug(liesZeitEin.toQString() );
00167 
00168         QString testdata2="2:4.6";
00169         liesZeitEin.liesVonTextStream( QTextIStream(&testdata2) );
00170         qDebug(liesZeitEin.toQString() );
00171 
00172         qDebug("In mm, ss, ttt zerlegt: %d, %f, %d", 
00173                 liesZeitEin.mins(), liesZeitEin.secs(), liesZeitEin.millisecs());
00174 
00175         qDebug("\n");
00176 }
00177 
00178 
00179 // struct IntervallErgebnis
00181 
00182 QString IntervallErgebnis::toQString() const{
00183         QString temp="";
00184         temp+="%1\t%2\t%3";
00185         temp=temp.arg(Einschaetzung).arg(EinschaetzungDavor).arg(Dauer);
00186         return temp;
00187 }
00188 
00189 ostream& operator<< (ostream& os, const IntervallErgebnis& rhs){
00190         os << rhs.toQString().latin1();
00191         return os;
00192 }
00193 
00194 // class RatingVerlauf
00196 
00197 RatingVerlauf::RatingVerlauf () {
00198         // Konstruktor mit 00:00.000 und null Rating
00199         Sinneinheiten.insert(MinSec2Rating::value_type(MinSec(0,0,0),null));
00200 };
00201 
00202 RatingVerlauf::~RatingVerlauf () {
00203         Sinneinheiten.clear();
00204 };
00205 
00206 void RatingVerlauf::RatingLoeschen(const MinSec &Endmoment){
00207         Sinneinheiten.erase(Endmoment);
00208 }
00209 
00210 void RatingVerlauf::RatingAnhaengen(const MinSec &Endmoment, 
00211                                                                         const RatingSkala Einschaetzung){
00212         Sinneinheiten.insert(MinSec2Rating::value_type(Endmoment,Einschaetzung));
00213 }
00214 
00215 MinSec RatingVerlauf::BisherLetzterMoment(){
00216         MinSec2Rating::iterator it=Sinneinheiten.end();
00217         it--;
00218         return it->first;
00219 }
00220 
00221 IntervallErgebnis RatingVerlauf::RatingAuslesen (const MinSec &Endmoment){
00222         IntervallErgebnis temp(error, error,-1);
00223 
00224         MinSec2Rating::iterator it2, it1;
00225         it2=Sinneinheiten.find(Endmoment);
00226 
00227         if (it2 != Sinneinheiten.end()) // IntervallENDE existiert 
00228                 temp.Einschaetzung=it2->second;
00229                 
00230         if (it2 != Sinneinheiten.begin()) // IntervallANFANG existiert 
00231         {
00232                 it1=it2;  it1--;                        // it1 = gehe einen Schritt zurück
00233                 temp.EinschaetzungDavor=it1->second;
00234         }
00235         if (temp.Einschaetzung != error && temp.EinschaetzungDavor != error)
00236                 temp.Dauer=(it1->first).secsTo(it2->first);
00237 
00238         return temp;
00239 }
00240 
00241 IntervallErgebnis RatingVerlauf::RatingAuslesen (const MinSec2Rating::iterator it){
00242         // TODO: Diese Routine tut eigentlich dasselbe wie
00243         // IntervallErgebnis RatingAuslesen (const MinSec &Endmoment)
00244         // nur noch ELEMENTARER, nämlich mit gegebenem Iterator
00245         // innerhalb der Map (statt einem Zeitpunkt, der erst gesucht werden muss)
00246         // TODO: dies sollte in obiges eingesetzt werden, 
00247         // um Redundanz zu vermeiden
00248 
00249         IntervallErgebnis temp(error, error,-1);
00250 
00251         MinSec2Rating::iterator it2, it1;
00252         it2=it;
00253 
00254         if (it2 != Sinneinheiten.end()) // IntervallENDE existiert 
00255                 temp.Einschaetzung=it2->second;
00256                 
00257         if (it2 != Sinneinheiten.begin()) // IntervallANFANG existiert 
00258         {
00259                 it1=it2;  it1--;                        // it1 = gehe einen Schritt zurück
00260                 temp.EinschaetzungDavor=it1->second;
00261         }
00262         if (temp.Einschaetzung != error && temp.EinschaetzungDavor != error)
00263                 temp.Dauer=(it1->first).secsTo(it2->first);
00264 
00265         return temp;
00266 }
00267 
00268 QString RatingVerlauf::printRating (const MinSec &Endmoment){
00269 
00270         IntervallErgebnis gesamt;
00271         gesamt=RatingAuslesen(Endmoment);
00272         
00273         QString temp;
00274         temp=Endmoment.toQString();
00275         if ( gesamt.Dauer>=0 ) {
00276                 temp+="\t"+gesamt.toQString();
00277         }
00278         return temp;
00279 }
00280 
00281 QString RatingVerlauf::printGesamtenRatingVerlauf (const MinSec& von, 
00282                                                                                                    const MinSec& bis){
00283         qDebug("printGesamtenRatingVerlauf sollte NICHT verwendet werden, "
00284                    "da a) suboptimal und b) riesiger QString als Resultat");
00285         MinSec2Rating::iterator it;
00286         MinSec Zeitpunkt;
00287         QString temp="";
00288         if ( bis < von ) 
00289                 return temp;
00290         
00291         for (it=Sinneinheiten.lower_bound(von); it != Sinneinheiten.end(); ++it){
00292                 Zeitpunkt=(*it).first;
00293                 if (bis < Zeitpunkt) 
00294                         break;
00295 
00296                       // suboptimal, weil darin noch ein map::find()
00297                 temp+=printRating(Zeitpunkt); 
00298                 temp+="\n";
00299         }
00300                 
00301         return temp;
00302 }
00303 
00304 bool RatingVerlauf::liesGesamtenRatingVerlauf (QTextStream &s){
00305 
00306         Sinneinheiten.clear();
00307         
00308         int Einschaetzung;
00309         MinSec Zeitpunkt;
00310         bool OK;
00311         QString Wort; 
00312         QChar c;
00313 
00314 leseSchleife:
00315         while (! s.atEnd()){
00316 
00317                 OK=Zeitpunkt.liesVonTextStream(s);
00318                 if (!OK) {
00319                                         qDebug("Fehler beim Einlesen des Zeitpunktes");
00320                                         return false;
00321                                 }
00322                 s >> c;
00323                 switch (c) {
00324                         case '\t':
00325                                 s >> Wort;
00326                                 Einschaetzung=Wort.toInt(&OK);
00327                                 if (!OK) {
00328                                         qDebug("Fehler beim Umwandeln der Einschaetzung");
00329                                         return false;
00330                                 }
00331                                 RatingAnhaengen(Zeitpunkt, (RatingSkala) Einschaetzung);
00332 
00333                                 s >> c >> Wort     >> c >> Wort >> c >> Wort >> c >> Wort >> c;
00334                                 //  tab  EinschDavor tab   dauer  tab   Klient  tab  Rater  tab
00335                                 
00336                                 if (c!='\n'){  // falls uralte Version, dann ist die Zeile hier zuende
00337                                         s >> Wort >> c  >> Wort >> c >>     Wort    >> c;
00338                                 //      minuten TAB  Sekunden TAB  Millisekunden   BR
00339                                 }
00340 
00341                                 if (c!='\n') {
00342                                         qDebug("Rest der Zeile war nicht OK"); 
00343                                         return false;
00344                                 }
00345                         break;
00346                         case '\n':
00347                                 goto leseSchleife; // nächste Zeile, weil nur 00:00, 
00348                                                    // mittlerweile obsolet
00349                          break;
00350                         default:
00351                                 qDebug("Quatsch beim Einlesen");
00352                                 return false;
00353                          break;
00354                 }
00355         }
00356         return true;
00357 }
00358 
00359 
00360 bool RatingVerlauf::speichereGesamtenRatingVerlauf (QTextStream &s, 
00361                                                                 QString& derKlient, QString& derRater) {
00362 
00363         MinSec Zeitpunkt=MinSec(0,0), ZeitpunktDavor=MinSec(0,0);
00364         RatingSkala Einsch=null, EinschDavor=null;
00365         double Dauer=0;
00366         MinSec2Rating::iterator it;
00367         it = Sinneinheiten.begin();
00368 
00369     for ( ; it!= Sinneinheiten.end(); ++it){
00370                 ZeitpunktDavor=Zeitpunkt;
00371                 Zeitpunkt=it->first;
00372                 Dauer=(Zeitpunkt - ZeitpunktDavor).toSecs(); 
00373 
00374                 EinschDavor=Einsch;
00375                 Einsch=it->second;
00376 
00377                 s << Zeitpunkt.toQString() << '\t';
00378                 s << Einsch << '\t';
00379                 s << EinschDavor << '\t';
00380                 s << Dauer << '\t';
00381                 s << derKlient << '\t';
00382                 s << derRater << '\t';
00383                 s << Zeitpunkt.mins() << '\t';
00384                 s << (int) Zeitpunkt.secs() << '\t';
00385                 s << Zeitpunkt.millisecs() << '\n';
00386         }       
00387         return true; // TODO: Was passiert, wenn innerhalb zB Platte voll?
00388 }
00389 
00390 
00391 // TODO: noch nicht auf Richtigkeit ge-check-t
00392 int RatingVerlauf::verkuerzeUmAufeinanderfolgendGleiche(){
00393 
00394         RatingVerlauf kuerzer;
00395         long anzahlGekuerzter=0;
00396 
00397         IntervallErgebnis interv;
00398         RatingSkala letzteEinschaetzung = error;
00399         MinSec letzterZeitpunkt = MinSec(0,0);
00400 
00401         MinSec2Rating::iterator it;
00402         it = Sinneinheiten.begin();
00403         for ( ; it != Sinneinheiten.end() ; it++){
00404                 interv=RatingAuslesen(it);
00405                 if (interv.Einschaetzung != letzteEinschaetzung) {
00406                         // falls DIESE Einschätzung anders, dann speichere die LETZTE
00407                         kuerzer.RatingAnhaengen(letzterZeitpunkt, letzteEinschaetzung );
00408                 } else{
00409                         // sonst ignorier DIESE und incrementiere nur Zähler
00410                         anzahlGekuerzter++;
00411                 }
00412                 letzteEinschaetzung=interv.Einschaetzung;
00413                 letzterZeitpunkt=it->first;
00414         }
00415         // TODO: Stimmt das? Der letzte wird NIE eingefügt, oder?
00416         kuerzer.RatingAnhaengen(letzterZeitpunkt, letzteEinschaetzung );
00417 
00418 
00419         this->RatingLoeschen(MinSec(0,0)); // leere sicherheitshalber aktuelle Map
00420         this->Sinneinheiten = kuerzer.Sinneinheiten; // TODO: ist das ein COPY ?
00421         return anzahlGekuerzter;
00422 }
00423 
00424 void RatingVerlauf::testRatingVerlauf() {
00425 
00426         qDebug("\nRatingVerlauf::testRatingVerlauf");
00427         RatingAnhaengen (MinSec(0,13,100), TL);
00428         RatingAnhaengen (MinSec(0,23.9), TNL);
00429         RatingAnhaengen (MinSec(0,37.6), KNL);
00430         RatingAnhaengen (MinSec(1,10,0), KL);
00431 
00432         qDebug("letzter Moment " + BisherLetzterMoment().toQString() );
00433 
00434     MinSec EndMoment;
00435         EndMoment=MinSec(1,10);
00436         IntervallErgebnis ges;
00437         ges=RatingAuslesen(EndMoment);
00438         qDebug(ges.toQString());
00439 
00440         qDebug(printRating (MinSec(0,0))); 
00441         qDebug(printRating (MinSec(0,13.1)));
00442         qDebug(printRating (MinSec(0,23.9)));
00443         qDebug(printRating (MinSec(0,37.6)));
00444         qDebug(printRating (MinSec(1,10)));
00445         qDebug(printRating (MinSec(1,11)));
00446 
00447         qDebug("\n\nUnd nun alles in einer Routine:");
00448         qDebug(printGesamtenRatingVerlauf (MinSec(0,0), BisherLetzterMoment()));
00449 
00450         qDebug("\n\nUnd nun nur die mittleren 3:");
00451         qDebug(printGesamtenRatingVerlauf (MinSec(0,12), MinSec(0,38)));
00452 };
00453 
00454 
00455 void testMinSecMap(){
00456         qDebug("\n\ntestMinSecMap();");   
00457         MinSec2Rating verlauf;
00458         MinSec2Rating::iterator theIterator;
00459 
00460         MinSec Endzeitpunkt=MinSec(1,12);
00461         verlauf.insert(MinSec2Rating::value_type(Endzeitpunkt,error));
00462         Endzeitpunkt=Endzeitpunkt.addSecs(7.2);
00463         verlauf.insert(MinSec2Rating::value_type(Endzeitpunkt,KL));
00464         Endzeitpunkt=Endzeitpunkt.addSecs(-69.9);
00465         verlauf.insert(MinSec2Rating::value_type(Endzeitpunkt,null));
00466         verlauf.insert(MinSec2Rating::value_type(Endzeitpunkt,KNL));
00467         // Sollte Werte ergeben bei 
00468         // 00:09.300
00469         // 01:12.000
00470         // 01:19.200
00471 
00472         theIterator = verlauf.begin();
00473     for ( ; theIterator!= verlauf.end(); ++theIterator)
00474         qDebug((*theIterator).first.toQString()+" %d", (*theIterator).second);
00475 
00476         MinSec Endzeitpunkt2=Endzeitpunkt.addSecs(1);
00477         ;
00478         MinSec2Rating::key_compare vergleiche=verlauf.key_comp();
00479         qDebug("a eine Sekunde kleiner als b");
00480         qDebug("vergleich<: %d",vergleiche(Endzeitpunkt, Endzeitpunkt2));
00481         qDebug("vergleich>=: %d",vergleiche(Endzeitpunkt2, Endzeitpunkt));
00482 
00483         qDebug("Bekannter Eintrag bei MinSec(1,19.2): %d",
00484                 verlauf.find(MinSec(1,19.2))->second);
00485         qDebug("Bekannter Eintrag bei MinSec(1,19,200): %d",
00486                 verlauf.find(MinSec(1,19,200))->second);
00487         qDebug("Unbekannter Eintrag(MinSec(1,18)) liefert: end() ): %d",
00488                 verlauf.find(MinSec(1,18))->second);
00489 
00490         qDebug("bounds liefern gleichen, höheren key oder end()");
00491     theIterator=verlauf.lower_bound(MinSec(1,11));
00492         qDebug("lower bound (1:11): "+ theIterator->first.toQString());
00493         theIterator=verlauf.upper_bound(MinSec(1,11));
00494         qDebug("upper bound (1:11): "+ theIterator->first.toQString());
00495 
00496     theIterator=verlauf.lower_bound(MinSec(1,20));
00497         qDebug("lower bound (1:20): "+ theIterator->first.toQString());
00498         theIterator=verlauf.upper_bound(MinSec(1,20));
00499         qDebug("upper bound (1:20): "+ theIterator->first.toQString());
00500 
00501         qDebug("Bei Treffer: lower bound liefert gleichen, "
00502                    "upper bound liefert höheren key (oder end())");
00503     theIterator=verlauf.lower_bound(MinSec(1,12));
00504         qDebug("lower bound (1:12): "+ theIterator->first.toQString());
00505         theIterator=verlauf.upper_bound(MinSec(1,12));
00506         qDebug("upper bound (1:12): "+ theIterator->first.toQString());
00507         theIterator=verlauf.upper_bound(MinSec(1,19.2));
00508         qDebug("upper bound (1:19.200): "+ theIterator->first.toQString());
00509 
00510         qDebug("\nAlso für schon verbrauchte Zeitpunkten: ");
00511         qDebug("Suche nach lower_bound(Reglerstand), rot wenn != end();");
00512         qDebug("(Oder besser einfach direkter Vergleich mit "
00513                    "MinSec BisherLetzterMoment())\n");
00514 };

Erzeugt am Mon Jun 16 18:08:24 2003 für LFTVideo von doxygen 1.3.2