diff --git a/swad_changelog.h b/swad_changelog.h index c73e3ce5..c35a39d8 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -544,10 +544,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.207.3 (2020-04-30)" +#define Log_PLATFORM_VERSION "SWAD 19.207.4 (2020-04-30)" #define CSS_FILE "swad19.193.1.css" #define JS_FILE "swad19.193.1.js" /* + Version 19.207.4: Apr 30, 2020 Fixed bug in test result, reported by Mancia Anguita López. (300363 lines) Version 19.207.3: Apr 30, 2020 Fixed bug removing account. (300335 lines) Version 19.207.2: Apr 30, 2020 Fixed bug creating account, reported by Antonio Becerra. (300334 lines) Version 19.207.1: Apr 30, 2020 Optimization in table of last prefs on user-course. (300323 lines) diff --git a/swad_database.c b/swad_database.c index 5c1e6468..7df70036 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1314,6 +1314,17 @@ mysql> DESCRIBE expanded_folders; "INDEX(FileBrowser,Cod)," "INDEX(WorksUsrCod))"); + /***** Table figures *****/ + /* +mysql> DESCRIBE figures; + + */ + DB_CreateTable ("CREATE TABLE IF NOT EXISTS figures (" + "Name VARCHAR(32) NOT NULL," // Fig_MAX_BYTES_NAME + "Value INT NOT NULL," + "CalcTime DATETIME NOT NULL," + "UNIQUE INDEX(Name))"); + /***** Table file_browser_last *****/ /* mysql> DESCRIBE file_browser_last; diff --git a/swad_figure.c b/swad_figure.c index 32490e05..b4bef0e0 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -65,6 +65,8 @@ extern struct Globals Gbl; /***************************** Private constants *****************************/ /*****************************************************************************/ +#define Fig_MAX_BYTES_NAME 32 + /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ @@ -195,6 +197,7 @@ static void Fig_GetAndShowNumUsrsPerMenu (void); static void Fig_GetAndShowNumUsrsPerTheme (void); static void Fig_GetAndShowNumUsrsPerSideColumns (void); unsigned Fig_GetNumUsrsWhoChoseAnOption (const char *SubQuery); +bool Fig_GetFigureFromCache (const char *Name); /*****************************************************************************/ /************************** Show use of the platform *************************/ @@ -5672,3 +5675,13 @@ unsigned Fig_GetNumUsrsWhoChoseAnOption (const char *SubQuery) return NumUsrs; } + +/*****************************************************************************/ +/************** Get number of users who have chosen an option ****************/ +/*****************************************************************************/ +// Return true is figure is valid (if figure is cached and recently calculated) + +bool Fig_GetFigureFromCache (const char *Name) + { + return Name[0] ? true : false; + } diff --git a/swad_test.c b/swad_test.c index 6aa9fb0f..0322ea96 100644 --- a/swad_test.c +++ b/swad_test.c @@ -2521,7 +2521,7 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, const char *Ptr; char TagText[Tst_MAX_BYTES_TAG + 1]; char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - Tst_AnswerType_t AnsType; + Tst_AnswerType_t AnswerType; bool Shuffle; char StrNumQsts[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; unsigned NumQst; @@ -2593,15 +2593,15 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, while (*Ptr) { Par_GetNextStrUntilSeparParamMult (&Ptr,UnsignedStr,Tst_MAX_BYTES_TAG); - AnsType = Tst_ConvertFromUnsignedStrToAnsTyp (UnsignedStr); - LengthQuery = LengthQuery + 35 + strlen (Tst_StrAnswerTypesDB[AnsType]) + 1; + AnswerType = Tst_ConvertFromUnsignedStrToAnsTyp (UnsignedStr); + LengthQuery = LengthQuery + 35 + strlen (Tst_StrAnswerTypesDB[AnswerType]) + 1; if (LengthQuery > Tst_MAX_BYTES_QUERY_TEST - 128) Lay_ShowErrorAndExit ("Query size exceed."); Str_Concat (Query, NumItemInList ? " OR tst_questions.AnsType='" : " AND (tst_questions.AnsType='", Tst_MAX_BYTES_QUERY_TEST); - Str_Concat (Query,Tst_StrAnswerTypesDB[AnsType], + Str_Concat (Query,Tst_StrAnswerTypesDB[AnswerType], Tst_MAX_BYTES_QUERY_TEST); Str_Concat (Query,"'", Tst_MAX_BYTES_QUERY_TEST); @@ -2647,13 +2647,13 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, Lay_ShowErrorAndExit ("Wrong code of question."); /* Get answer type (row[1]) */ - AnsType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); + AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); /* Get shuffle (row[2]) */ Shuffle = (row[2][0] == 'Y'); /* Set indexes of answers */ - switch (AnsType) + switch (AnswerType) { case Tst_ANS_INT: case Tst_ANS_FLOAT: diff --git a/swad_test_exam.c b/swad_test_exam.c index 2751cf51..ef0d3ea8 100644 --- a/swad_test_exam.c +++ b/swad_test_exam.c @@ -347,9 +347,9 @@ static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, HTM_TxtColonNBSP (Txt_Score); HTM_SPAN_Begin ("class=\"%s\"", Result->Questions[NumQst].StrAnswers[0] ? - (Result->Questions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect - "ANS_BAD") : // Wrong - "ANS_0"); // Blank answer + (Result->Questions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect + "ANS_BAD") : // Wrong + "ANS_0"); // Blank answer HTM_Double2Decimals (Result->Questions[NumQst].Score); HTM_SPAN_End (); HTM_DIV_End (); @@ -505,6 +505,7 @@ static void TstRes_ComputeFloatAnsScore (struct TstRes_Result *Result, if (Result->Questions[NumQst].AnswerIsNotBlank) // If user has answered the answer { AnswerUsr = Str_GetDoubleFromStr (Result->Questions[NumQst].StrAnswers); + // A bad formatted floating point answer will interpreted as 0.0 Result->Questions[NumQst].Score = (AnswerUsr >= Question->Answer.FloatingPoint[0] && AnswerUsr <= Question->Answer.FloatingPoint[1]) ? 1.0 : // If correct (inside the interval) @@ -2307,17 +2308,20 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result) MYSQL_ROW row; unsigned NumQsts; unsigned NumQst; + Tst_AnswerType_t AnswerType; /***** Get questions of a test exam from database *****/ NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get questions" " of a test exam", - "SELECT QstCod," // row[0] - "Indexes," // row[1] - "Answers" // row[2] - " FROM tst_exam_questions" - " WHERE ExaCod=%ld" - " ORDER BY QstInd", + "SELECT tst_exam_questions.QstCod," // row[0] + "tst_questions.AnsType," // row[1] + "tst_exam_questions.Indexes," // row[2] + "tst_exam_questions.Answers" // row[3] + " FROM tst_exam_questions,tst_questions" + " WHERE tst_exam_questions.ExaCod=%ld" + " AND tst_exam_questions.QstCod=tst_questions.QstCod" + " ORDER BY tst_exam_questions.QstInd", Result->ResCod); /***** List questions *****/ @@ -2330,22 +2334,28 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result) { row = mysql_fetch_row (mysql_res); - /* Get question code */ + /* Get question code (row[0]) */ if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); - /* Get indexes for this question (row[1]) */ - Str_Copy (Result->Questions[NumQst].StrIndexes,row[1], + /* Get answer type (row[1]) */ + AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); + + /* Get indexes for this question (row[2]) */ + Str_Copy (Result->Questions[NumQst].StrIndexes,row[2], TstRes_MAX_BYTES_INDEXES_ONE_QST); - /* Get answers selected by user for this question (row[2]) */ - Str_Copy (Result->Questions[NumQst].StrAnswers,row[2], + /* Get answers selected by user for this question (row[3]) */ + Str_Copy (Result->Questions[NumQst].StrAnswers,row[3], TstRes_MAX_BYTES_ANSWERS_ONE_QST); /* Replace each comma by a separator of multiple parameters */ /* In database commas are used as separators instead of special chars */ Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes); - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers); + if (AnswerType == Tst_ANS_MULTIPLE_CHOICE) + // Only multiple choice questions have multiple answers separated by commas + // Other types of questions have a unique answer, and comma may be part of that answer + Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers); } /***** Free structure that stores the query result *****/