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:
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 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: 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: Los exámenes de test que no se han confirmado
deben aparecer en la base de datos con un código especial,
no contando en la nota y no mostrándose la fecha de finalización.
El botón de confirmar envío de examen debería ser verde.
// TODO: Integrar pull requests con traducciones del alemán del usuario eruedin en GitHub
// TODO: Comprobar si la puntuación de cada pregunta de un examen se recalcula al mostrarlo o se saca de la base de datos
y qué pasa cuando se edita una pregunta
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)
5 changes necessary in database:
ALTER TABLE tst_exams RENAME INDEX TstCod TO ExaCod;

View File

@ -1030,8 +1030,8 @@ void MchRes_ShowOneMchResult (void)
}
/***** Get match result data *****/
MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,
&Exam);
TstExa_ResetExam (&Exam);
MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Exam);
/***** Check if I can view this match result *****/
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,
struct TstExa_Exam *Exam)
struct TstExa_Exam *Exam)
{
MYSQL_RES *mysql_res;
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
{
/***** Get questions *****/
TstExa_ResetExam (&Exam);
Tst_GetQuestionsForNewTestFromDB (&Test,&Exam);
if (Exam.NumQsts)
{
@ -540,6 +541,7 @@ void Tst_RequestAssessTest (void)
/***** Get basic parameters of the exam *****/
/* Get test exam code from form */
TstExa_ResetExam (&Exam);
if ((Exam.ExaCod = TstExa_GetParamExaCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong test exam.");
@ -559,11 +561,12 @@ void Tst_RequestAssessTest (void)
/***** Update test exam in database *****/
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 *****/
/* 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 */
Tst_ShowTestExamToFillIt (&Exam,NumTst,Tst_CONFIRM);
@ -600,6 +603,7 @@ void Tst_AssessTest (void)
/***** Get basic parameters of the exam *****/
/* Get test exam code from form */
TstExa_ResetExam (&Exam);
if ((Exam.ExaCod = TstExa_GetParamExaCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong test exam.");
@ -617,9 +621,13 @@ void Tst_AssessTest (void)
/***** Get answers from form to assess a test *****/
Tst_GetAnswersFromForm (&Exam);
/***** Get if test exam will be visible by teachers *****/
Exam.AllowTeachers = Par_GetParToBool ("AllowTchs");
/***** Update test exam in database *****/
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 *****/
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,
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_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 *****/
Box_BoxBegin (NULL,Txt_Test,
@ -933,11 +933,21 @@ static void Tst_ShowTestExamToFillIt (struct TstExa_Exam *Exam,
/***** End table *****/
HTM_TABLE_End ();
/***** Test exam will be visible by teachers *****/
Tst_PutCheckBoxAllowTeachers (true);
/***** 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 ();
}
@ -3779,7 +3789,7 @@ static void Tst_WriteTextAnsSeeing (const struct TstExa_Exam *Exam,
snprintf (StrAns,sizeof (StrAns),
"Ans%010u",
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\"");
}
@ -4573,10 +4583,6 @@ void Tst_QstDestructor (struct Tst_Question *Question)
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 =
(char *) malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL)
{

View File

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