Version19.159

This commit is contained in:
acanas 2020-04-03 01:55:39 +02:00
parent bff637ba46
commit f690d1ed72
5 changed files with 64 additions and 48 deletions

View File

@ -497,7 +497,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD: En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 19.158 (2020-04-02)" #define Log_PLATFORM_VERSION "SWAD 19.159 (2020-04-03)"
#define CSS_FILE "swad19.146.css" #define CSS_FILE "swad19.146.css"
#define JS_FILE "swad19.153.js" #define JS_FILE "swad19.153.js"
/* /*
@ -522,11 +522,11 @@ Param
// TODO: En la lista de conectados central, poner el logo de la institución a la que pertenece el usuario // TODO: En la lista de conectados central, poner el logo de la institución a la que pertenece el usuario
// TODO: Miguel Damas: al principio de los exámenes tendría que poner cuánto resta cada pregunta // TODO: Miguel Damas: al principio de los exámenes tendría que poner cuánto resta cada pregunta
// TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores // TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores
// TODO: Los exámenes de test que no se han confirmado // TODO: Integrar pull requests con traducciones del alemán del usuario eruedin en GitHub
deben aparecer en la base de datos con un código especial, // TODO: Comprobar si la puntuación de cada pregunta de un examen se recalcula al mostrarlo o se saca de la base de datos
no contando en la nota y no mostrándose la fecha de finalización. y qué pasa cuando se edita una pregunta
El botón de confirmar envío de examen debería ser verde.
Version 19.159: Apr 03, 2020 Code refactoring and bug fixing in tests. (285052 lines)
Version 19.158: Apr 02, 2020 Lot of code refactoring in tests. (285031 lines) Version 19.158: Apr 02, 2020 Lot of code refactoring in tests. (285031 lines)
5 changes necessary in database: 5 changes necessary in database:
ALTER TABLE tst_exams RENAME INDEX TstCod TO ExaCod; ALTER TABLE tst_exams RENAME INDEX TstCod TO ExaCod;

View File

@ -1030,8 +1030,8 @@ void MchRes_ShowOneMchResult (void)
} }
/***** Get match result data *****/ /***** Get match result data *****/
MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod, TstExa_ResetExam (&Exam);
&Exam); MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Exam);
/***** Check if I can view this match result *****/ /***** Check if I can view this match result *****/
switch (Gbl.Usrs.Me.Role.Logged) switch (Gbl.Usrs.Me.Role.Logged)
@ -1289,7 +1289,7 @@ void MchRes_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod,
/*****************************************************************************/ /*****************************************************************************/
static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod, static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
struct TstExa_Exam *Exam) struct TstExa_Exam *Exam)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;

View File

@ -467,6 +467,7 @@ void Tst_ShowNewTest (void)
if (Tst_GetParamsTst (&Test,Tst_SHOW_TEST_TO_ANSWER)) // Get parameters from form if (Tst_GetParamsTst (&Test,Tst_SHOW_TEST_TO_ANSWER)) // Get parameters from form
{ {
/***** Get questions *****/ /***** Get questions *****/
TstExa_ResetExam (&Exam);
Tst_GetQuestionsForNewTestFromDB (&Test,&Exam); Tst_GetQuestionsForNewTestFromDB (&Test,&Exam);
if (Exam.NumQsts) if (Exam.NumQsts)
{ {
@ -540,6 +541,7 @@ void Tst_RequestAssessTest (void)
/***** Get basic parameters of the exam *****/ /***** Get basic parameters of the exam *****/
/* Get test exam code from form */ /* Get test exam code from form */
TstExa_ResetExam (&Exam);
if ((Exam.ExaCod = TstExa_GetParamExaCod ()) <= 0) if ((Exam.ExaCod = TstExa_GetParamExaCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong test exam."); Lay_ShowErrorAndExit ("Wrong test exam.");
@ -559,11 +561,12 @@ void Tst_RequestAssessTest (void)
/***** Update test exam in database *****/ /***** Update test exam in database *****/
TstExa_ComputeScoresAndStoreExamQuestions (&Exam, TstExa_ComputeScoresAndStoreExamQuestions (&Exam,
false); // Don't update question score false); // Don't update question score
TstExa_UpdateExamInDB (&Exam);
/***** Show question and button to send the test *****/ /***** Show question and button to send the test *****/
/* Start alert */ /* Start alert */
Ale_ShowAlert (Ale_INFO,"Por favor, revise el test antes de enviarlo."); // TODO: Need translation!!! Ale_ShowAlert (Ale_WARNING,"Por favor, revise sus respuestas antes de enviar el examen:"); // TODO: Need translation!!!
/* Show the same test exam to be answered */ /* Show the same test exam to be answered */
Tst_ShowTestExamToFillIt (&Exam,NumTst,Tst_CONFIRM); Tst_ShowTestExamToFillIt (&Exam,NumTst,Tst_CONFIRM);
@ -600,6 +603,7 @@ void Tst_AssessTest (void)
/***** Get basic parameters of the exam *****/ /***** Get basic parameters of the exam *****/
/* Get test exam code from form */ /* Get test exam code from form */
TstExa_ResetExam (&Exam);
if ((Exam.ExaCod = TstExa_GetParamExaCod ()) <= 0) if ((Exam.ExaCod = TstExa_GetParamExaCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong test exam."); Lay_ShowErrorAndExit ("Wrong test exam.");
@ -617,9 +621,13 @@ void Tst_AssessTest (void)
/***** Get answers from form to assess a test *****/ /***** Get answers from form to assess a test *****/
Tst_GetAnswersFromForm (&Exam); Tst_GetAnswersFromForm (&Exam);
/***** Get if test exam will be visible by teachers *****/
Exam.AllowTeachers = Par_GetParToBool ("AllowTchs");
/***** Update test exam in database *****/ /***** Update test exam in database *****/
TstExa_ComputeScoresAndStoreExamQuestions (&Exam, TstExa_ComputeScoresAndStoreExamQuestions (&Exam,
Gbl.Usrs.Me.Role.Logged == Rol_STD); // Update question score? Gbl.Usrs.Me.Role.Logged == Rol_STD); // Update question score?
TstExa_UpdateExamInDB (&Exam);
/***** Begin box *****/ /***** Begin box *****/
Box_BoxBegin (NULL,Txt_Test_result, Box_BoxBegin (NULL,Txt_Test_result,
@ -693,9 +701,6 @@ static void Tst_GetAnswersFromForm (struct TstExa_Exam *Exam)
Par_GetParMultiToText (StrAns,Exam->Questions[NumQst].StrAnswers, Par_GetParMultiToText (StrAns,Exam->Questions[NumQst].StrAnswers,
TstExa_MAX_BYTES_ANSWERS_ONE_QST); /* If answer type == T/F ==> " ", "T", "F"; if choice ==> "0", "2",... */ TstExa_MAX_BYTES_ANSWERS_ONE_QST); /* If answer type == T/F ==> " ", "T", "F"; if choice ==> "0", "2",... */
} }
/***** Get if test exam will be visible by teachers *****/
Exam->AllowTeachers = Par_GetParToBool ("AllowTchs");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -878,11 +883,6 @@ static void Tst_ShowTestExamToFillIt (struct TstExa_Exam *Exam,
[Tst_REQUEST] = ActReqAssTst, [Tst_REQUEST] = ActReqAssTst,
[Tst_CONFIRM] = ActAssTst, [Tst_CONFIRM] = ActAssTst,
}; };
static char *TxtButton[Tst_NUM_REQUEST_OR_CONFIRM] =
{
[Tst_REQUEST] = "He terminado", // TODO: Need translation!!!
[Tst_CONFIRM] = "Enviar", // TODO: Need translation!!!
};
/***** Begin box *****/ /***** Begin box *****/
Box_BoxBegin (NULL,Txt_Test, Box_BoxBegin (NULL,Txt_Test,
@ -933,11 +933,21 @@ static void Tst_ShowTestExamToFillIt (struct TstExa_Exam *Exam,
/***** End table *****/ /***** End table *****/
HTM_TABLE_End (); HTM_TABLE_End ();
/***** Test exam will be visible by teachers *****/
Tst_PutCheckBoxAllowTeachers (true);
/***** End form *****/ /***** End form *****/
Btn_PutConfirmButton (TxtButton[RequestOrConfirm]); switch (RequestOrConfirm)
{
case Tst_REQUEST:
/* Send button */
Btn_PutConfirmButton ("He terminado"); // TODO: Need translation!!!
break;
case Tst_CONFIRM:
/* Will the test exam be visible by teachers? */
Tst_PutCheckBoxAllowTeachers (true);
/* Send button */
Btn_PutCreateButton ("Enviar"); // TODO: Need translation!!!
break;
}
Frm_EndForm (); Frm_EndForm ();
} }
@ -3779,7 +3789,7 @@ static void Tst_WriteTextAnsSeeing (const struct TstExa_Exam *Exam,
snprintf (StrAns,sizeof (StrAns), snprintf (StrAns,sizeof (StrAns),
"Ans%010u", "Ans%010u",
NumQst); NumQst);
HTM_INPUT_TEXT (StrAns,TstExa_MAX_BYTES_ANSWERS_ONE_QST,Exam->Questions[NumQst].StrAnswers,false, HTM_INPUT_TEXT (StrAns,TstExa_MAX_CHARS_ANSWERS_ONE_QST,Exam->Questions[NumQst].StrAnswers,false,
"size=\"40\""); "size=\"40\"");
} }
@ -4573,10 +4583,6 @@ void Tst_QstDestructor (struct Tst_Question *Question)
bool Tst_AllocateTextChoiceAnswer (struct Tst_Question *Question,unsigned NumOpt) bool Tst_AllocateTextChoiceAnswer (struct Tst_Question *Question,unsigned NumOpt)
{ {
// Tst_FreeTagsList (&Question->Tags); // TODO: Necessary?
// Tst_FreeTextChoiceAnswer (Question,NumOpt);// TODO: Necessary?
if ((Question->Answer.Options[NumOpt].Text = if ((Question->Answer.Options[NumOpt].Text =
(char *) malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL) (char *) malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL)
{ {

View File

@ -157,6 +157,21 @@ static void TstExa_ShowExamsSummaryRow (bool ItsMe,
double TotalScoreOfAllTests); double TotalScoreOfAllTests);
static void TstExa_ShowTagsPresentInAnExam (long ExaCod); static void TstExa_ShowTagsPresentInAnExam (long ExaCod);
/*****************************************************************************/
/******************************** Reset exam *********************************/
/*****************************************************************************/
void TstExa_ResetExam (struct TstExa_Exam *Exam)
{
Exam->ExaCod = -1L;
Exam->TimeUTC[Dat_START_TIME] =
Exam->TimeUTC[Dat_END_TIME ] = (time_t) 0;
Exam->NumQsts =
Exam->NumQstsNotBlank = 0;
Exam->AllowTeachers = false;
Exam->Score = 0.0;
}
/*****************************************************************************/ /*****************************************************************************/
/***************** Create new blank test exam in database ********************/ /***************** Create new blank test exam in database ********************/
/*****************************************************************************/ /*****************************************************************************/
@ -167,14 +182,12 @@ void TstExa_CreateExamInDB (struct TstExa_Exam *Exam)
Exam->ExaCod = Exam->ExaCod =
DB_QueryINSERTandReturnCode ("can not create new test exam", DB_QueryINSERTandReturnCode ("can not create new test exam",
"INSERT INTO tst_exams" "INSERT INTO tst_exams"
" (CrsCod,UsrCod,StartTime,EndTime,NumQsts,AllowTeachers)" " (CrsCod,UsrCod,StartTime,EndTime,NumQsts,AllowTeachers,Score)"
" VALUES" " VALUES"
" (%ld,%ld,NOW(),NOW(),%u,'%c')", " (%ld,%ld,NOW(),NOW(),%u,'N',0)",
Gbl.Hierarchy.Crs.CrsCod, Gbl.Hierarchy.Crs.CrsCod,
Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.UsrCod,
Exam->NumQsts, Exam->NumQsts);
Exam->AllowTeachers ? 'Y' :
'N');
} }
/*****************************************************************************/ /*****************************************************************************/
@ -189,10 +202,13 @@ void TstExa_UpdateExamInDB (const struct TstExa_Exam *Exam)
"UPDATE tst_exams" "UPDATE tst_exams"
" SET EndTime=NOW()," " SET EndTime=NOW(),"
"NumQstsNotBlank=%u," "NumQstsNotBlank=%u,"
"AllowTeachers='%c',"
"Score='%.15lg'" "Score='%.15lg'"
" WHERE ExaCod=%ld" " WHERE ExaCod=%ld"
" AND CrsCod=%ld AND UsrCod=%ld", // Extra checks " AND CrsCod=%ld AND UsrCod=%ld", // Extra checks
Exam->NumQstsNotBlank, Exam->NumQstsNotBlank,
Exam->AllowTeachers ? 'Y' :
'N',
Exam->Score, Exam->Score,
Exam->ExaCod, Exam->ExaCod,
Gbl.Hierarchy.Crs.CrsCod, Gbl.Hierarchy.Crs.CrsCod,
@ -385,9 +401,6 @@ void TstExa_ComputeScoresAndStoreExamQuestions (struct TstExa_Exam *Exam,
if (UpdateQstScore) if (UpdateQstScore)
Tst_UpdateQstScoreInDB (Exam,NumQst); Tst_UpdateQstScoreInDB (Exam,NumQst);
} }
/***** Store test exam in database *****/
TstExa_UpdateExamInDB (Exam);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -780,7 +793,6 @@ static void TstExa_ComputeTextAnsScore (struct TstExa_Exam *Exam,
unsigned NumOpt; unsigned NumOpt;
char TextAnsUsr[TstExa_MAX_BYTES_ANSWERS_ONE_QST + 1]; char TextAnsUsr[TstExa_MAX_BYTES_ANSWERS_ONE_QST + 1];
char TextAnsOK[TstExa_MAX_BYTES_ANSWERS_ONE_QST + 1]; char TextAnsOK[TstExa_MAX_BYTES_ANSWERS_ONE_QST + 1];
bool Correct = false;
/***** Get correct answers for this question from database *****/ /***** Get correct answers for this question from database *****/
TstExa_GetCorrectTextAnswerFromDB (Question); TstExa_GetCorrectTextAnswerFromDB (Question);
@ -797,7 +809,6 @@ static void TstExa_ComputeTextAnsScore (struct TstExa_Exam *Exam,
/* In order to compare student answer to stored answer, /* In order to compare student answer to stored answer,
the text answers are stored avoiding two or more consecurive spaces */ the text answers are stored avoiding two or more consecurive spaces */
Str_ReplaceSeveralSpacesForOne (TextAnsUsr); Str_ReplaceSeveralSpacesForOne (TextAnsUsr);
Str_ConvertToComparable (TextAnsUsr); Str_ConvertToComparable (TextAnsUsr);
for (NumOpt = 0; for (NumOpt = 0;
@ -811,14 +822,8 @@ static void TstExa_ComputeTextAnsScore (struct TstExa_Exam *Exam,
/* Check is user answer is correct */ /* Check is user answer is correct */
if (!strcoll (TextAnsUsr,TextAnsOK)) if (!strcoll (TextAnsUsr,TextAnsOK))
{ Exam->Questions[NumQst].Score = 1.0; // Correct answer
Correct = true;
break;
}
} }
if (Correct)
Exam->Questions[NumQst].Score = 1.0; // Correct answer
} }
} }
@ -849,8 +854,8 @@ static void TstExa_GetCorrectTextAnswerFromDB (struct Tst_Question *Question)
/* Abort on error */ /* Abort on error */
Ale_ShowAlertsAndExit (); Ale_ShowAlertsAndExit ();
/***** Copy answer text (row[1]) and convert it, that is in HTML, to rigorous HTML ******/ /***** Copy answer text (row[0]) and convert it, that is in HTML, to rigorous HTML ******/
Str_Copy (Question->Answer.Options[NumOpt].Text,row[1], Str_Copy (Question->Answer.Options[NumOpt].Text,row[0],
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK); Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
Question->Answer.Options[NumOpt].Text, Question->Answer.Options[NumOpt].Text,
@ -1906,6 +1911,7 @@ static void TstExa_ShowExams (struct UsrData *UsrDat)
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
/* Get test code (row[0]) */ /* Get test code (row[0]) */
TstExa_ResetExam (&Exam);
if ((Exam.ExaCod = Str_ConvertStrCodToLongCod (row[0])) < 0) if ((Exam.ExaCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of test exam."); Lay_ShowErrorAndExit ("Wrong code of test exam.");
@ -2180,6 +2186,7 @@ void TstExa_ShowOneExam (void)
bool ICanViewScore; bool ICanViewScore;
/***** Get the code of the test *****/ /***** Get the code of the test *****/
TstExa_ResetExam (&Exam);
if ((Exam.ExaCod = TstExa_GetParamExaCod ()) == -1L) if ((Exam.ExaCod = TstExa_GetParamExaCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of test is missing."); Lay_ShowErrorAndExit ("Code of test is missing.");

View File

@ -34,7 +34,9 @@
/*****************************************************************************/ /*****************************************************************************/
#define TstExa_MAX_BYTES_INDEXES_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (3 + 1)) #define TstExa_MAX_BYTES_INDEXES_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (3 + 1))
#define TstExa_MAX_BYTES_ANSWERS_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (3 + 1))
#define TstExa_MAX_CHARS_ANSWERS_ONE_QST (128 - 1) // 127
#define TstExa_MAX_BYTES_ANSWERS_ONE_QST ((TstExa_MAX_CHARS_ANSWERS_ONE_QST + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047
#define TstExa_SCORE_MAX 10 // Maximum score of a test (10 in Spain). Must be unsigned! // TODO: Make this configurable by teachers #define TstExa_SCORE_MAX 10 // Maximum score of a test (10 in Spain). Must be unsigned! // TODO: Make this configurable by teachers
@ -64,6 +66,7 @@ struct TstExa_Exam
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
void TstExa_ResetExam (struct TstExa_Exam *Exam);
void TstExa_CreateExamInDB (struct TstExa_Exam *Exam); void TstExa_CreateExamInDB (struct TstExa_Exam *Exam);
void TstExa_UpdateExamInDB (const struct TstExa_Exam *Exam); void TstExa_UpdateExamInDB (const struct TstExa_Exam *Exam);