"Fossies" - the Fresh Open Source Software Archive

Member "fet-5.45.1/src/engine/timetable_defs.cpp" (10 Jun 2020, 12216 Bytes) of package /linux/privat/fet-5.45.1.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "timetable_defs.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.45.0_vs_5.45.1.

    1 /*
    2 File timetable_defs.cpp
    3 */
    4 
    5 /***************************************************************************
    6                           timetable_defs.cpp  -  description
    7                              -------------------
    8     begin                : Sat Mar 15 2003
    9     copyright            : (C) 2003 by Lalescu Liviu
   10     email                : Please see https://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
   11  ***************************************************************************/
   12 
   13 /***************************************************************************
   14  *                                                                         *
   15  *   This program is free software: you can redistribute it and/or modify  *
   16  *   it under the terms of the GNU Affero General Public License as        *
   17  *   published by the Free Software Foundation, either version 3 of the    *
   18  *   License, or (at your option) any later version.                       *
   19  *                                                                         *
   20  ***************************************************************************/
   21 
   22 #include "timetable_defs.h"
   23 
   24 //#include <ctime>
   25 #include <chrono>
   26 
   27 #include <QHash>
   28 
   29 #include <QLocale>
   30 
   31 bool checkForUpdates;
   32 
   33 QString internetVersion;
   34 
   35 int STUDENTS_COMBO_BOXES_STYLE=STUDENTS_COMBO_BOXES_STYLE_SIMPLE;
   36 
   37 /**
   38 FET version
   39 */
   40 const QString FET_VERSION="5.45.1";
   41 
   42 /**
   43 FET language
   44 */
   45 QString FET_LANGUAGE="en_US";
   46 
   47 /**
   48 The output directory. Please be careful when editing it,
   49 because the functions add a FILE_SEP sign at the end of it
   50 and then the name of a file. If you make OUTPUT_DIR="",
   51 there will be problems.
   52 */
   53 QString OUTPUT_DIR;
   54 
   55 bool LANGUAGE_STYLE_RIGHT_TO_LEFT;
   56 
   57 QString LANGUAGE_FOR_HTML;
   58 
   59 /**
   60 Timetable html css javaScript Level, by Volker Dirr
   61 */
   62 int TIMETABLE_HTML_LEVEL;
   63 
   64 bool TIMETABLE_HTML_PRINT_ACTIVITY_TAGS;
   65 
   66 bool PRINT_DETAILED_HTML_TIMETABLES;
   67 
   68 bool PRINT_DETAILED_HTML_TEACHERS_FREE_PERIODS;
   69 
   70 bool PRINT_NOT_AVAILABLE_TIME_SLOTS;
   71 
   72 bool PRINT_BREAK_TIME_SLOTS;
   73 
   74 bool PRINT_ACTIVITIES_WITH_SAME_STARTING_TIME;
   75 
   76 bool DIVIDE_HTML_TIMETABLES_WITH_TIME_AXIS_BY_DAYS;
   77 
   78 bool TIMETABLE_HTML_REPEAT_NAMES;
   79 
   80 bool VERBOSE;
   81 
   82 //these hashes are needed to get the IDs for html and css in timetableexport and statistics
   83 /*QHash<QString, QString> hashSubjectIDs;
   84 QHash<QString, QString> hashActivityTagIDs;
   85 QHash<QString, QString> hashStudentIDs;
   86 QHash<QString, QString> hashTeacherIDs;
   87 QHash<QString, QString> hashRoomIDs;
   88 QHash<QString, QString> hashDayIDs;*/
   89 
   90 /**
   91 A log file explaining how the xml input file was parsed
   92 */
   93 const QString XML_PARSING_LOG_FILENAME="file_open.log";
   94 
   95 /**
   96 The predefined names of the days of the week
   97 */
   98 const QString PREDEFINED_DAYS_OF_THE_WEEK[]={"Monday", "Tuesday", "Wednesday",
   99     "Thursday", "Friday", "Saturday", "Sunday", "Monday2",
  100     "Tuesday2", "Wednesday2", "Thursday2", "Friday2", "Saturday2", "Sunday2",
  101     "Monday3", "Tuesday3", "Wednesday3",
  102     "Thursday3", "Friday3", "Saturday3", "Sunday3", "Monday4",
  103     "Tuesday4", "Wednesday4", "Thursday4", "Friday4", "Saturday4", "Sunday4"};
  104 
  105 /**
  106 File and directory separator
  107 */
  108 const QString FILE_SEP="/";
  109 
  110 QString protect(const QString& str) //used for XML
  111 {
  112     QString p=str;
  113     p.replace("&", "&amp;");
  114     p.replace("\"", "&quot;");
  115     p.replace(">", "&gt;");
  116     p.replace("<", "&lt;");
  117     p.replace("'", "&apos;");
  118     return p;
  119 }
  120 
  121 QString protect2(const QString& str) //used for HTML
  122 {
  123     QString p=str;
  124     p.replace("&", "&amp;");
  125     p.replace("\"", "&quot;");
  126     p.replace(">", "&gt;");
  127     p.replace("<", "&lt;");
  128     //p.replace("'", "&apos;");
  129     return p;
  130 }
  131 
  132 QString protect2vert(const QString& str) //used for HTML
  133 {
  134     QString p=str;
  135     p.replace("&", "&amp;");
  136     p.replace("\"", "&quot;");
  137     p.replace(">", "&gt;");
  138     p.replace("<", "&lt;");
  139     //p.replace("'", "&apos;");
  140 
  141     QString returnstring;
  142     for(int i=0; i<p.size();i++){
  143         QString a=p.at(i);
  144         QString b="<br />";
  145         returnstring.append(a);
  146         returnstring.append(b);
  147     }
  148     return returnstring;
  149 }
  150 
  151 ///////begin tricks
  152 void weight_sscanf(const QString& str, const char* fmt, double* result)
  153 {
  154     assert(QString(fmt)==QString("%lf"));
  155 
  156     bool ok;
  157     double myres=customFETStrToDouble(str, &ok);
  158     if(!ok)
  159         (*result)=-2.5; //any value that does not belong to {>=0.0 and <=100.0} or {-1.0}
  160                         //not -1.0 because of modify multiple constraints min days between activities,
  161                         //-1 there represents any weight
  162                         //potential bug found by Volker Dirr
  163     else
  164         (*result)=myres;
  165 }
  166 
  167 QString CustomFETString::number(int n)
  168 {
  169     return QString::number(n);
  170 }
  171 
  172 QString CustomFETString::number(double x)
  173 {
  174     QString tmp=QString::number(x, 'f', CUSTOM_DOUBLE_PRECISION);
  175     
  176     //remove trailing zeroes AFTER the decimal points
  177     if(tmp.contains('.')){
  178         int n=tmp.length()-1;
  179         int del=0;
  180         while(tmp.at(n)=='0'){
  181             n--;
  182             del++;
  183         }
  184         if(tmp.at(n)=='.'){
  185             n--;
  186             del++;
  187         }
  188         tmp.chop(del);
  189     }
  190 
  191     return tmp;
  192 }
  193 
  194 QString CustomFETString::numberPlusTwoDigitsPrecision(double x)
  195 {
  196     QString tmp=QString::number(x, 'f', CUSTOM_DOUBLE_PRECISION+2);
  197     
  198     //remove trailing zeroes AFTER the decimal points
  199     if(tmp.contains('.')){
  200         int n=tmp.length()-1;
  201         int del=0;
  202         while(tmp.at(n)=='0'){
  203             n--;
  204             del++;
  205         }
  206         if(tmp.at(n)=='.'){
  207             n--;
  208             del++;
  209         }
  210         tmp.chop(del);
  211     }
  212 
  213     return tmp;
  214 }
  215 
  216 double customFETStrToDouble(const QString& str, bool* ok)
  217 {
  218     QLocale c(QLocale::C);
  219 
  220     //tricks to convert numbers like 97.123456789 to 97.123457, to CUSTOM_DOUBLE_PRECISION (6) decimal digits after the decimal point
  221     double tmpd=c.toDouble(str, ok);
  222     if(ok!=0)
  223         if((*ok)==false)
  224             return tmpd;
  225     QString tmps=CustomFETString::number(tmpd);
  226     return c.toDouble(tmps, ok);
  227 }
  228 ///////end tricks
  229 
  230 /*
  231 int XX;
  232 int YY;
  233 int ZZ;
  234 
  235 //random routines
  236 void initRandomKnuth()
  237 {
  238     assert(MM==2147483647);
  239     assert(AA==48271);
  240     assert(QQ==44488);
  241     assert(RR==3399);
  242     
  243     assert(MMM==2147483399);
  244     assert(MMM==MM-248);
  245     assert(AAA==40692);
  246     assert(QQQ==52774);
  247     assert(RRR==3791);
  248     
  249     //a few tests
  250     XX=123; YY=123;
  251     int tttt=randomKnuth1MM1();
  252     assert(XX==5937333);
  253     assert(YY==5005116);
  254     assert(tttt==932217);
  255 
  256     XX=4321; YY=54321;
  257     tttt=randomKnuth1MM1();
  258     assert(XX==208578991);
  259     assert(YY==62946733);
  260     assert(tttt==145632258);
  261 
  262     XX=87654321; YY=987654321;
  263     tttt=randomKnuth1MM1();
  264     assert(XX==618944401);
  265     assert(YY==1625301246);
  266     assert(tttt==1141126801);
  267 
  268     XX=1; YY=1;
  269     tttt=randomKnuth1MM1();
  270     assert(XX==48271);
  271     assert(YY==40692);
  272     assert(tttt==7579);
  273 
  274     XX=MM-1; YY=MMM-1;
  275     tttt=randomKnuth1MM1();
  276     assert(XX==2147435376);
  277     assert(YY==2147442707);
  278     assert(tttt==2147476315);
  279 
  280     XX=100; YY=1000;
  281     tttt=randomKnuth1MM1();
  282     assert(XX==4827100);
  283     assert(YY==40692000);
  284     assert(tttt==2111618746);
  285     //////////
  286     
  287     //unsigned tt=unsigned(time(NULL));
  288     qint64 tt=qint64(time(NULL));
  289     
  290     //XX is the current time
  291     //XX = 1 + ( (unsigned(tt)) % (unsigned(MM-1)) );
  292     XX = 1 + int( tt%(qint64(MM-1)) );
  293     assert(XX>0);
  294     assert(XX<MM);
  295 
  296     //YY is the next random, after initializing YY with the current time
  297     //YY = 1 + ( (unsigned(tt)) % (unsigned(MMM-1)) );
  298     YY = 1 + int( tt%(qint64(MMM-1)) );
  299     assert(YY>0);
  300     assert(YY<MMM);
  301     YY=AAA*(YY%QQQ)-RRR*(YY/QQQ);
  302     if(YY<0)
  303         YY+=MMM;
  304     assert(YY>0);
  305     assert(YY<MMM);
  306     
  307     ZZ=XX-YY;
  308     if(ZZ<=0)
  309         ZZ+=MM-1; //-1 is not written in Knuth TAOCP vol. 2 third edition; I think it would be an improvement. (Later edit: yes, the author confirmed that).
  310     assert(ZZ>0);
  311     assert(ZZ<MM); //again, modified from Knuth TAOCP vol. 2 third edition, ZZ is strictly lower than MM (the author confirmed that, too).
  312 }
  313 
  314 int randomKnuth1MM1()
  315 {
  316     assert(XX>0);
  317     assert(XX<MM);
  318 
  319     XX=AA*(XX%QQ)-RR*(XX/QQ);
  320     if(XX<0)
  321         XX+=MM;
  322 
  323     assert(XX>0);
  324     assert(XX<MM);
  325 
  326     assert(YY>0);
  327     assert(YY<MMM);
  328 
  329     YY=AAA*(YY%QQQ)-RRR*(YY/QQQ);
  330     if(YY<0)
  331         YY+=MMM;
  332     
  333     assert(YY>0);
  334     assert(YY<MMM);
  335 
  336     ZZ=XX-YY;
  337     if(ZZ<=0)
  338         ZZ+=MM-1; //-1 is not written in Knuth TAOCP vol. 2 third edition; I think it would be an improvement. (Later edit: yes, the author confirmed that).
  339     assert(ZZ>0);
  340     assert(ZZ<MM); //again, modified from Knuth TAOCP vol. 2 third edition, ZZ is strictly lower than MM (the author confirmed that, too).
  341     
  342     return ZZ;
  343 }
  344 
  345 int randomKnuth(int k)
  346 {
  347     //like in Knuth TAOCP vol.2, reject some numbers (very few), so that the distribution is perfectly uniform
  348     for(;;){
  349         int U=randomKnuth1MM1();
  350         if( U <= k * ((MM-1)/k) )
  351             return U%k;
  352     }
  353 }
  354 */
  355 
  356 MRG32k3a rng;
  357 
  358 const qint64 MRG32k3a::m1 = Q_INT64_C(4294967087);
  359 const qint64 MRG32k3a::m2 = Q_INT64_C(4294944443);
  360 const qint64 MRG32k3a::a12 = Q_INT64_C(1403580);
  361 const qint64 MRG32k3a::a13n = Q_INT64_C(810728);
  362 const qint64 MRG32k3a::a21 = Q_INT64_C(527612);
  363 const qint64 MRG32k3a::a23n = Q_INT64_C(1370589);
  364 
  365 MRG32k3a::MRG32k3a()
  366 {
  367     //not permitted values, so we check that we don't forget to init this RNG in another place.
  368     s10=s11=s12=0;
  369     s20=s21=s22=0;
  370 }
  371 
  372 MRG32k3a::~MRG32k3a()
  373 {
  374 }
  375 
  376 void MRG32k3a::initializeMRG32k3a(qint64 _s10, qint64 _s11, qint64 _s12,
  377     qint64 _s20, qint64 _s21, qint64 _s22)
  378 {
  379     assert(m1==Q_INT64_C(4294967296)-Q_INT64_C(209));
  380     assert(m1==Q_INT64_C(4294967087));
  381     
  382     assert(m2==Q_INT64_C(4294967296)-Q_INT64_C(22853));
  383     assert(m2==Q_INT64_C(4294944443));
  384     
  385     assert(a12==Q_INT64_C(1403580));
  386     assert(a13n==Q_INT64_C(810728));
  387     
  388     assert(a21==Q_INT64_C(527612));
  389     assert(a23n==Q_INT64_C(1370589));
  390 
  391     assert(_s10>=0);
  392     assert(_s11>=0);
  393     assert(_s12>=0);
  394 
  395     assert(_s20>=0);
  396     assert(_s21>=0);
  397     assert(_s22>=0);
  398 
  399     assert(_s10 < m1);
  400     assert(_s11 < m1);
  401     assert(_s12 < m1);
  402 
  403     assert(_s20 < m2);
  404     assert(_s21 < m2);
  405     assert(_s22 < m2);
  406 
  407     assert(_s10>0 || _s11>0 || _s12>0);
  408     assert(_s20>0 || _s21>0 || _s22>0);
  409     
  410     s10=_s10;
  411     s11=_s11;
  412     s12=_s12;
  413 
  414     s20=_s20;
  415     s21=_s21;
  416     s22=_s22;
  417 }
  418 
  419 void MRG32k3a::initializeMRG32k3a()
  420 {
  421     qint64 _s10, _s11, _s12, _s20, _s21, _s22;
  422 
  423     //qint64 tt=qint64(time(NULL));
  424     
  425     std::chrono::seconds s=std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
  426     qint64 si=static_cast<qint64>(s.count());
  427     //cout<<"si=="<<si<<endl;
  428     assert(si>=0);
  429     _s10=si%m1;
  430     if(_s10==0) //just in case :-)  . It could even be allowed to be 0, but then we wouldn't have a certain guarantee that not all seeds in component 1 are 0.
  431         _s10=1;
  432 
  433     _s20=si%m2;
  434     if(_s20==0) //just in case :-)  . It could even be allowed to be 0, but then we wouldn't have a certain guarantee that not all seeds in component 2 are 0.
  435         _s20=1;
  436 
  437     /*_s10 = 1 + tt%(m1-1);
  438     assert(_s10>=1);
  439     assert(_s10<m1);
  440 
  441     _s20 = 1 + tt%(m2-1);
  442     assert(_s20>=1);
  443     assert(_s20<m2);*/
  444     
  445     //Using ideas and code from https://stackoverflow.com/questions/19555121/how-to-get-current-timestamp-in-milliseconds-since-1970-just-the-way-java-gets
  446     //and https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
  447     //and https://stackoverflow.com/questions/18022927/convert-high-resolution-clock-time-into-an-integer-chrono/18023064
  448     std::chrono::nanoseconds ns=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch());
  449     qint64 nsi=static_cast<qint64>(ns.count());
  450     //cout<<"nsi=="<<nsi<<endl;
  451     assert(nsi>=0);
  452 
  453     _s11=nsi%1000000000;
  454 
  455     std::chrono::nanoseconds ns2=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch());
  456     qint64 nsi2=static_cast<qint64>(ns2.count());
  457     //cout<<"nsi2=="<<nsi2<<endl;
  458     assert(nsi2>=0);
  459 
  460     _s21=nsi2%1000000000;
  461     
  462     _s12=0; //We could try other better methods, but they need to be portable.
  463     _s22=0;
  464     
  465     initializeMRG32k3a(_s10, _s11, _s12, _s20, _s21, _s22);
  466 }
  467 
  468 unsigned int MRG32k3a::uiMRG32k3a()
  469 {
  470     assert(s10>0 || s11>0 || s12>0);
  471     assert(s20>0 || s21>0 || s22>0);
  472 
  473     qint64 p, p1, p2;
  474 
  475     /* Component 1 */
  476     p1 = a12*s11 - a13n*s10;
  477     p1%=m1;
  478     if(p1<0)
  479         p1+=m1;
  480     assert(p1>=0 && p1<m1);
  481     s10 = s11;
  482     s11 = s12;
  483     s12 = p1;
  484 
  485     /* Component 2 */
  486     p2 = a21*s22 - a23n*s20;
  487     p2%=m2;
  488     if(p2<0)
  489         p2+=m2;
  490     assert(p2>=0 && p2<m2);
  491     s20 = s21;
  492     s21 = s22;
  493     s22 = p2;
  494     
  495     /* Combination */
  496     p=p1-p2;
  497     if(p<0)
  498         p+=m1;
  499     assert(p>=0 && p<m1);
  500 
  501     return (unsigned int)(p);
  502 }
  503 
  504 /*double MRG32k3a::dMRG32k3a()
  505 {
  506     double p=double(uiMRG32k3a())/double(m1);
  507 
  508     assert(p>=0.0);
  509     assert(p<1.0);
  510 
  511     return p;
  512 }*/
  513 
  514 int MRG32k3a::intMRG32k3a(int k)
  515 {
  516     qint64 q=(qint64(uiMRG32k3a())*qint64(k))/m1;
  517     assert(q<qint64(k));
  518     int r=int(q);
  519     
  520     return r;
  521 }