Version19.256

This commit is contained in:
acanas 2020-06-24 20:10:57 +02:00
parent 0d6621862c
commit 96390926bd
11 changed files with 430 additions and 258 deletions

View File

@ -556,7 +556,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.255.2 (2020-06-24)" #define Log_PLATFORM_VERSION "SWAD 19.256 (2020-06-24)"
#define CSS_FILE "swad19.253.css" #define CSS_FILE "swad19.253.css"
#define JS_FILE "swad19.254.js" #define JS_FILE "swad19.254.js"
/* /*
@ -567,8 +567,9 @@ TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver traba
TODO: No limitar el número de preguntas en un examen a ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT, sino asignar PrintedQuestions dinámicamente con malloc TODO: No limitar el número de preguntas en un examen a ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT, sino asignar PrintedQuestions dinámicamente con malloc
TODO: Que al generar un examen sólo se cojan preguntas válidas. Y si ya está generado, al entrar de nuevo, que se vean en rojo. TODO: Que al generar un examen sólo se cojan preguntas válidas. Y si ya está generado, al entrar de nuevo, que se vean en rojo.
Version 19.255.2: Jun 24, 2020 Changes in listing of test and exam results. (303701 lines) Version 19.256: Jun 24, 2020 Code refactoring in tests, exams and matches results. (303841 lines)
Version 19.255.1: Jun 23, 2020 Changes in listing of test results. (303655 lines) Version 19.255.2: Jun 24, 2020 Changes in listing of tests and exams results. (303701 lines)
Version 19.255.1: Jun 23, 2020 Changes in listing of tests results. (303655 lines)
Version 19.255: Jun 23, 2020 Code refactoring in test results. (303625 lines) Version 19.255: Jun 23, 2020 Code refactoring in test results. (303625 lines)
Version 19.254.2: Jun 23, 2020 Matches results can only be changed to visible when match is at the end. Version 19.254.2: Jun 23, 2020 Matches results can only be changed to visible when match is at the end.
If teacher goes back in match, the results change antumatically to hidden. (303667 lines) If teacher goes back in match, the results change antumatically to hidden. (303667 lines)

View File

@ -66,7 +66,9 @@ extern struct Globals Gbl;
/***************************** Private prototypes ****************************/ /***************************** Private prototypes ****************************/
/*****************************************************************************/ /*****************************************************************************/
static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print); static void ExaPrn_GetDataOfPrint (struct ExaPrn_Print *Print,
MYSQL_RES **mysql_res,
unsigned long NumRows);
static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print,long ExaCod); static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print,long ExaCod);
static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print, static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print,
@ -152,14 +154,9 @@ static void ExaPrn_UpdatePrintInDB (const struct ExaPrn_Print *Print);
void ExaPrn_ResetPrint (struct ExaPrn_Print *Print) void ExaPrn_ResetPrint (struct ExaPrn_Print *Print)
{ {
Print->PrnCod = -1L;
Print->SesCod = -1L; Print->SesCod = -1L;
Print->UsrCod = -1L; Print->UsrCod = -1L;
ExaPrn_ResetPrintExceptEvtCodAndUsrCod (Print);
}
static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print)
{
Print->PrnCod = -1L;
Print->TimeUTC[Dat_START_TIME] = Print->TimeUTC[Dat_START_TIME] =
Print->TimeUTC[Dat_END_TIME ] = (time_t) 0; Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
Print->Sent = false; // After creating an exam print, it's not sent Print->Sent = false; // After creating an exam print, it's not sent
@ -191,7 +188,6 @@ void ExaPrn_ShowExamPrint (void)
Exa_ResetExams (&Exams); Exa_ResetExams (&Exams);
Exa_ResetExam (&Exam); Exa_ResetExam (&Exam);
ExaSes_ResetSession (&Session); ExaSes_ResetSession (&Session);
ExaPrn_ResetPrint (&Print);
/***** Get and check parameters *****/ /***** Get and check parameters *****/
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session); ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
@ -202,7 +198,7 @@ void ExaPrn_ShowExamPrint (void)
/***** Get print data from database *****/ /***** Get print data from database *****/
Print.SesCod = Session.SesCod; Print.SesCod = Session.SesCod;
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
ExaPrn_GetDataOfPrintByCodAndUsrCod (&Print); ExaPrn_GetDataOfPrintBySesCodAndUsrCod (&Print);
if (Print.PrnCod <= 0) // Print does not exists ==> create it if (Print.PrnCod <= 0) // Print does not exists ==> create it
{ {
@ -239,61 +235,113 @@ void ExaPrn_ShowExamPrint (void)
Ale_ShowAlert (Ale_INFO,Txt_You_dont_have_access_to_the_exam); Ale_ShowAlert (Ale_INFO,Txt_You_dont_have_access_to_the_exam);
} }
/*****************************************************************************/
/**************** Get data of an exam print using print code *****************/
/*****************************************************************************/
void ExaPrn_GetDataOfPrintByPrnCod (struct ExaPrn_Print *Print)
{
MYSQL_RES *mysql_res;
unsigned long NumRows;
/***** Make database query *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get data of an exam print",
"SELECT PrnCod," // row[0]
"SesCod," // row[1]
"UsrCod," // row[2]
"UNIX_TIMESTAMP(StartTime)," // row[3]
"UNIX_TIMESTAMP(EndTime)," // row[4]
"NumQsts," // row[5]
"NumQstsNotBlank," // row[6]
"Sent," // row[7]
"Score" // row[8]
" FROM exa_prints"
" WHERE PrnCod=%ld",
Print->PrnCod);
/***** Get data of print *****/
ExaPrn_GetDataOfPrint (Print,&mysql_res,NumRows);
}
/*****************************************************************************/ /*****************************************************************************/
/******** Get data of an exam print using session code and user code *********/ /******** Get data of an exam print using session code and user code *********/
/*****************************************************************************/ /*****************************************************************************/
void ExaPrn_GetDataOfPrintByCodAndUsrCod (struct ExaPrn_Print *Print) void ExaPrn_GetDataOfPrintBySesCodAndUsrCod (struct ExaPrn_Print *Print)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; unsigned long NumRows;
/***** Make database query *****/ /***** Make database query *****/
if (DB_QuerySELECT (&mysql_res,"can not get data of an exam print", NumRows = DB_QuerySELECT (&mysql_res,"can not get data of an exam print",
"SELECT PrnCod," // row[0] "SELECT PrnCod," // row[0]
"UNIX_TIMESTAMP(StartTime)," // row[1] "SesCod," // row[1]
"UNIX_TIMESTAMP(EndTime)," // row[2] "UsrCod," // row[2]
"NumQsts," // row[3] "UNIX_TIMESTAMP(StartTime)," // row[3]
"NumQstsNotBlank," // row[4] "UNIX_TIMESTAMP(EndTime)," // row[4]
"Sent," // row[5] "NumQsts," // row[5]
"Score" // row[6] "NumQstsNotBlank," // row[6]
" FROM exa_prints" "Sent," // row[7]
" WHERE SesCod=%ld" "Score" // row[8]
" AND UsrCod=%ld", " FROM exa_prints"
Print->SesCod, " WHERE SesCod=%ld"
Print->UsrCod) == 1) " AND UsrCod=%ld",
Print->SesCod,
Print->UsrCod);
/***** Get data of print *****/
ExaPrn_GetDataOfPrint (Print,&mysql_res,NumRows);
}
/*****************************************************************************/
/************************* Get assignment data *******************************/
/*****************************************************************************/
static void ExaPrn_GetDataOfPrint (struct ExaPrn_Print *Print,
MYSQL_RES **mysql_res,
unsigned long NumRows)
{
MYSQL_ROW row;
if (NumRows)
{ {
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (*mysql_res);
/* Get print code (row[0]) */ /* Get print code (row[0]) */
Print->PrnCod = Str_ConvertStrCodToLongCod (row[0]); Print->PrnCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get date-time (row[1] and row[2] hold UTC date-time) */ /* Get session code (row[1]) */
Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]); Print->SesCod = Str_ConvertStrCodToLongCod (row[1]);
Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]);
/* Get number of questions (row[3]) */ /* Get user code (row[2]) */
if (sscanf (row[3],"%u",&Print->NumQsts.All) != 1) Print->UsrCod = Str_ConvertStrCodToLongCod (row[2]);
/* Get date-time (row[3] and row[4] hold UTC date-time) */
Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]);
Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]);
/* Get number of questions (row[5]) */
if (sscanf (row[5],"%u",&Print->NumQsts.All) != 1)
Print->NumQsts.All = 0; Print->NumQsts.All = 0;
/* Get number of questions not blank (row[4]) */ /* Get number of questions not blank (row[6]) */
if (sscanf (row[4],"%u",&Print->NumQsts.NotBlank) != 1) if (sscanf (row[6],"%u",&Print->NumQsts.NotBlank) != 1)
Print->NumQsts.NotBlank = 0; Print->NumQsts.NotBlank = 0;
/* Get if exam has been sent (row[5]) */ /* Get if exam has been sent (row[7]) */
Print->Sent = (row[5][0] == 'Y'); Print->Sent = (row[7][0] == 'Y');
/* Get score (row[6]) */ /* Get score (row[8]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot Str_SetDecimalPointToUS (); // To get the decimal point as a dot
if (sscanf (row[6],"%lf",&Print->Score.All) != 1) if (sscanf (row[8],"%lf",&Print->Score.All) != 1)
Print->Score.All = 0.0; Print->Score.All = 0.0;
Str_SetDecimalPointToLocal (); // Return to local system Str_SetDecimalPointToLocal (); // Return to local system
} }
else else
ExaPrn_ResetPrintExceptEvtCodAndUsrCod (Print); ExaPrn_ResetPrint (Print);
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (mysql_res);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -995,14 +1043,13 @@ void ExaPrn_ReceivePrintAnswer (void)
Exa_ResetExams (&Exams); Exa_ResetExams (&Exams);
Exa_ResetExam (&Exam); Exa_ResetExam (&Exam);
ExaSes_ResetSession (&Session); ExaSes_ResetSession (&Session);
ExaPrn_ResetPrint (&Print);
/***** Get session code *****/ /***** Get session code *****/
Print.SesCod = ExaSes_GetParamSesCod (); Print.SesCod = ExaSes_GetParamSesCod ();
/***** Get print data *****/ /***** Get print data *****/
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
ExaPrn_GetDataOfPrintByCodAndUsrCod (&Print); ExaPrn_GetDataOfPrintBySesCodAndUsrCod (&Print);
if (Print.PrnCod <= 0) if (Print.PrnCod <= 0)
Lay_WrongExamExit (); Lay_WrongExamExit ();

View File

@ -80,7 +80,8 @@ void ExaPrn_ResetPrint (struct ExaPrn_Print *Print);
void ExaPrn_ShowExamPrint (void); void ExaPrn_ShowExamPrint (void);
void ExaPrn_GetDataOfPrintByCodAndUsrCod (struct ExaPrn_Print *Print); void ExaPrn_GetDataOfPrintByPrnCod (struct ExaPrn_Print *Print);
void ExaPrn_GetDataOfPrintBySesCodAndUsrCod (struct ExaPrn_Print *Print);
void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print); void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print);

View File

@ -746,11 +746,11 @@ static void ExaRes_ShowHeaderResults (Usr_MeOrOther_t MeOrOther)
/***** Third row *****/ /***** Third row *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","<em>p<sub>i</sub></em>=1"); HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","{<em>p<sub>i</sub></em>=1}");
HTM_TH (1,1,"RT LINE_BOTTOM","-1&le;<em>p<sub>i</sub></em>&lt;0"); HTM_TH (1,1,"RT LINE_BOTTOM","{-1&le;<em>p<sub>i</sub></em>&lt;0}");
HTM_TH (1,1,"RT LINE_BOTTOM","<em>p<sub>i</sub></em>=0"); HTM_TH (1,1,"RT LINE_BOTTOM","{<em>p<sub>i</sub></em>=0}");
HTM_TH (1,1,"RT LINE_BOTTOM","0&lt;<em>p<sub>i</sub></em>&lt;1"); HTM_TH (1,1,"RT LINE_BOTTOM","{0&lt;<em>p<sub>i</sub></em>&lt;1}");
HTM_TH (1,1,"RT LINE_BOTTOM","<em>p<sub>i</sub></em>=0"); HTM_TH (1,1,"RT LINE_BOTTOM","{<em>p<sub>i</sub></em>=0}");
HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","<em>&Sigma;p<sub>i</sub></em>"); HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","<em>&Sigma;p<sub>i</sub></em>");
HTM_TH (1,1,"RT LINE_BOTTOM","-1&le;<em style=\"text-decoration:overline;\">p</em>&le;1"); HTM_TH (1,1,"RT LINE_BOTTOM","-1&le;<em style=\"text-decoration:overline;\">p</em>&le;1");
@ -820,12 +820,6 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
struct ExaPrn_Score TotalScore; struct ExaPrn_Score TotalScore;
double Grade; double Grade;
double TotalGrade = 0.0; double TotalGrade = 0.0;
time_t TimeUTC[Dat_NUM_START_END_TIME];
/***** Reset print, session and exam *****/
ExaPrn_ResetPrint (&Print);
ExaSes_ResetSession (&Session);
Exa_ResetExam (&Exam);
/***** Reset total number of questions and total score *****/ /***** Reset total number of questions and total score *****/
NumTotalQsts.All = NumTotalQsts.All =
@ -918,10 +912,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
// must be able to access exams taken in other groups // must be able to access exams taken in other groups
NumResults = NumResults =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get sessions results", (unsigned) DB_QuerySELECT (&mysql_res,"can not get sessions results",
"SELECT exa_prints.PrnCod," // row[0] "SELECT exa_prints.PrnCod" // row[0]
"exa_prints.SesCod," // row[1]
"UNIX_TIMESTAMP(exa_prints.StartTime)," // row[2]
"UNIX_TIMESTAMP(exa_prints.EndTime)" // row[3]
" FROM exa_prints,exa_sessions,exa_exams" " FROM exa_prints,exa_sessions,exa_exams"
" WHERE exa_prints.UsrCod=%ld" " WHERE exa_prints.UsrCod=%ld"
"%s" // Session subquery "%s" // Session subquery
@ -960,11 +951,11 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0) if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of exam print."); Lay_ShowErrorAndExit ("Wrong code of exam print.");
/* Get session code (row[1]) */ /* Get print data */
if ((Session.SesCod = Str_ConvertStrCodToLongCod (row[1])) < 0) ExaPrn_GetDataOfPrintByPrnCod (&Print);
Lay_ShowErrorAndExit ("Wrong code of session.");
/* Get data of session and exam */ /* Get data of session and exam */
Session.SesCod = Print.SesCod;
ExaSes_GetDataOfSessionByCod (&Session); ExaSes_GetDataOfSessionByCod (&Session);
Exam.ExaCod = Session.ExaCod; Exam.ExaCod = Session.ExaCod;
Exa_GetDataOfExamByCod (&Exam); Exa_GetDataOfExamByCod (&Exam);
@ -975,18 +966,17 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
if (NumResult) if (NumResult)
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/* Write start/end times (row[2], row[3] hold UTC start/end times) */ /* Write start/end times */
for (StartEndTime = (Dat_StartEndTime_t) 0; for (StartEndTime = (Dat_StartEndTime_t) 0;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++) StartEndTime++)
{ {
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[2 + StartEndTime]);
UniqueId++; UniqueId++;
if (asprintf (&Id,"exa_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0) if (asprintf (&Id,"exa_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
Lay_NotEnoughMemoryExit (); Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"", HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"",
Id,Gbl.RowEvenOdd); Id,Gbl.RowEvenOdd);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime], Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
true,true,false,0x7); true,true,false,0x7);
HTM_TD_End (); HTM_TD_End ();
@ -1017,7 +1007,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
} }
/* Write total number of questions */ /* Write total number of questions */
HTM_TD_Begin ("class=\"DAT LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
HTM_Unsigned (Print.NumQsts.All); HTM_Unsigned (Print.NumQsts.All);
else else
@ -1052,7 +1042,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End (); HTM_TD_End ();
/* Write number of correct questions */ /* Write number of correct questions */
HTM_TD_Begin ("class=\"DAT LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
{ {
if (Print.NumQsts.Valid.Correct) if (Print.NumQsts.Valid.Correct)
@ -1115,7 +1105,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End (); HTM_TD_End ();
/* Write score valid (taking into account only valid questions) */ /* Write score valid (taking into account only valid questions) */
HTM_TD_Begin ("class=\"DAT LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
{ {
HTM_Double2Decimals (Print.Score.Valid); HTM_Double2Decimals (Print.Score.Valid);
@ -1137,7 +1127,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End (); HTM_TD_End ();
/* Write grade over maximum grade (taking into account only valid questions) */ /* Write grade over maximum grade (taking into account only valid questions) */
HTM_TD_Begin ("class=\"DAT LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
{ {
Grade = TstPrn_ComputeGrade (Print.NumQsts.Valid.Total,Print.Score.Valid,Exam.MaxGrade); Grade = TstPrn_ComputeGrade (Print.NumQsts.Valid.Total,Print.Score.Valid,Exam.MaxGrade);
@ -1149,7 +1139,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End (); HTM_TD_End ();
/* Link to show this result */ /* Link to show this result */
HTM_TD_Begin ("class=\"LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Result) if (ICanView.Result)
{ {
Exams->ExaCod = Session.ExaCod; Exams->ExaCod = Session.ExaCod;
@ -1230,18 +1220,18 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/***** Row title *****/ /***** Row title *****/
HTM_TD_Begin ("colspan=\"3\" class=\"DAT_N LINE_TOP LINE_BOTTOM RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("colspan=\"3\" class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_TxtColonNBSP (Txt_Sessions); HTM_TxtColonNBSP (Txt_Sessions);
HTM_Unsigned (NumResults); HTM_Unsigned (NumResults);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of questions *****/ /***** Write total number of questions *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_Unsigned (NumTotalQsts->All); HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of valid questions *****/ /***** Write total number of valid questions *****/
HTM_TD_Begin ("class=\"DAT_GREEN LINE_TOP LINE_BOTTOM RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_GREEN RT LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumTotalQsts->Valid.Total) if (NumTotalQsts->Valid.Total)
HTM_Unsigned (NumTotalQsts->Valid.Total); HTM_Unsigned (NumTotalQsts->Valid.Total);
else else
@ -1249,7 +1239,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of invalid questions *****/ /***** Write total number of invalid questions *****/
HTM_TD_Begin ("class=\"DAT_RED LINE_TOP LINE_BOTTOM RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_RED RT LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
NumTotalQstsInvalid = NumTotalQsts->All - NumTotalQsts->Valid.Total; NumTotalQstsInvalid = NumTotalQsts->All - NumTotalQsts->Valid.Total;
if (NumTotalQstsInvalid) if (NumTotalQstsInvalid)
HTM_Unsigned (NumTotalQstsInvalid); HTM_Unsigned (NumTotalQstsInvalid);
@ -1258,7 +1248,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End (); HTM_TD_End ();
/***** Write number of correct questions *****/ /***** Write number of correct questions *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RT LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (NumTotalQsts->Valid.Correct) if (NumTotalQsts->Valid.Correct)
HTM_Unsigned (NumTotalQsts->Valid.Correct); HTM_Unsigned (NumTotalQsts->Valid.Correct);
else else
@ -1266,21 +1256,21 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End (); HTM_TD_End ();
/***** Write number of wrong questions *****/ /***** Write number of wrong questions *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RT LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumTotalQsts->Valid.Wrong.Negative) if (NumTotalQsts->Valid.Wrong.Negative)
HTM_Unsigned (NumTotalQsts->Valid.Wrong.Negative); HTM_Unsigned (NumTotalQsts->Valid.Wrong.Negative);
else else
HTM_Light0 (); HTM_Light0 ();
HTM_TD_End (); HTM_TD_End ();
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RT LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumTotalQsts->Valid.Wrong.Zero) if (NumTotalQsts->Valid.Wrong.Zero)
HTM_Unsigned (NumTotalQsts->Valid.Wrong.Zero); HTM_Unsigned (NumTotalQsts->Valid.Wrong.Zero);
else else
HTM_Light0 (); HTM_Light0 ();
HTM_TD_End (); HTM_TD_End ();
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RT LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumTotalQsts->Valid.Wrong.Positive) if (NumTotalQsts->Valid.Wrong.Positive)
HTM_Unsigned (NumTotalQsts->Valid.Wrong.Positive); HTM_Unsigned (NumTotalQsts->Valid.Wrong.Positive);
else else
@ -1288,7 +1278,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End (); HTM_TD_End ();
/***** Write number of blank questions *****/ /***** Write number of blank questions *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RT LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumTotalQsts->Valid.Blank) if (NumTotalQsts->Valid.Blank)
HTM_Unsigned (NumTotalQsts->Valid.Blank); HTM_Unsigned (NumTotalQsts->Valid.Blank);
else else
@ -1296,14 +1286,14 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End (); HTM_TD_End ();
/***** Write total valid score *****/ /***** Write total valid score *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (TotalScore->Valid); HTM_Double2Decimals (TotalScore->Valid);
HTM_Txt ("/"); HTM_Txt ("/");
HTM_Unsigned (NumTotalQsts->Valid.Total); HTM_Unsigned (NumTotalQsts->Valid.Total);
HTM_TD_End (); HTM_TD_End ();
/***** Write average valid score per valid question *****/ /***** Write average valid score per valid question *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (NumTotalQsts->Valid.Total ? TotalScore->Valid / HTM_Double2Decimals (NumTotalQsts->Valid.Total ? TotalScore->Valid /
(double) NumTotalQsts->Valid.Total : (double) NumTotalQsts->Valid.Total :
0.0); 0.0);
@ -1311,7 +1301,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
/***** Write total grade *****/ /***** Write total grade *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (TotalGrade); HTM_Double2Decimals (TotalGrade);
HTM_TD_End (); HTM_TD_End ();
@ -1361,11 +1351,9 @@ void ExaRes_ShowOneExaResult (void)
} }
/***** Get exam print data *****/ /***** Get exam print data *****/
ExaPrn_ResetPrint (&Print);
Print.SesCod = Session.SesCod; Print.SesCod = Session.SesCod;
Print.UsrCod = UsrDat->UsrCod; Print.UsrCod = UsrDat->UsrCod;
ExaPrn_GetDataOfPrintByCodAndUsrCod (&Print); ExaPrn_GetDataOfPrintBySesCodAndUsrCod (&Print);
/***** Set log action and print code *****/ /***** Set log action and print code *****/
if (Gbl.Action.Act == ActEndExaPrn) if (Gbl.Action.Act == ActEndExaPrn)

View File

@ -4032,8 +4032,7 @@ static void Mch_RemoveMyAnswerToMatchQuestion (const struct Mch_Match *Match)
/*************** Get the questions of a match from database ******************/ /*************** Get the questions of a match from database ******************/
/*****************************************************************************/ /*****************************************************************************/
void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod, void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print)
struct TstPrn_Print *Print)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -4055,7 +4054,7 @@ void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
" AND mch_matches.MchCod=mch_indexes.MchCod" " AND mch_matches.MchCod=mch_indexes.MchCod"
" AND gam_questions.QstInd=mch_indexes.QstInd" " AND gam_questions.QstInd=mch_indexes.QstInd"
" ORDER BY gam_questions.QstInd", " ORDER BY gam_questions.QstInd",
MchCod); Print->MchCod);
for (NumQst = 0, Print->NumQsts.NotBlank = 0; for (NumQst = 0, Print->NumQsts.NotBlank = 0;
NumQst < Print->NumQsts.All; NumQst < Print->NumQsts.All;
NumQst++) NumQst++)
@ -4076,7 +4075,7 @@ void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
Tst_MAX_BYTES_INDEXES_ONE_QST); Tst_MAX_BYTES_INDEXES_ONE_QST);
/* Get answers selected by user for this question */ /* Get answers selected by user for this question */
Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer); Mch_GetQstAnsFromDB (Print->MchCod,Print->UsrCod,QstInd,&UsrAnswer);
if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
{ {
snprintf (Print->PrintedQuestions[NumQst].StrAnswers,Tst_MAX_BYTES_ANSWERS_ONE_QST + 1, snprintf (Print->PrintedQuestions[NumQst].StrAnswers,Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
@ -4095,7 +4094,7 @@ void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
/******************** Compute match score for a student **********************/ /******************** Compute match score for a student **********************/
/*****************************************************************************/ /*****************************************************************************/
void Mch_ComputeScore (struct TstPrn_Print *Print) void Mch_ComputeScore (struct MchPrn_Print *Print)
{ {
unsigned NumQst; unsigned NumQst;
struct Tst_Question Question; struct Tst_Question Question;

View File

@ -27,6 +27,7 @@
/********************************* Headers ***********************************/ /********************************* Headers ***********************************/
/*****************************************************************************/ /*****************************************************************************/
#include "swad_match_print.h"
#include "swad_scope.h" #include "swad_scope.h"
#include "swad_test.h" #include "swad_test.h"
@ -145,10 +146,9 @@ void Mch_GetQstAnsFromDB (long MchCod,long UsrCod,unsigned QstInd,
struct Mch_UsrAnswer *UsrAnswer); struct Mch_UsrAnswer *UsrAnswer);
void Mch_ReceiveQuestionAnswer (void); void Mch_ReceiveQuestionAnswer (void);
void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod, void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print);
struct TstPrn_Print *Print);
void Mch_ComputeScore (struct TstPrn_Print *Print); void Mch_ComputeScore (struct MchPrn_Print *Print);
unsigned Mch_GetNumUsrsWhoAnsweredQst (long MchCod,unsigned QstInd); unsigned Mch_GetNumUsrsWhoAnsweredQst (long MchCod,unsigned QstInd);
unsigned Mch_GetNumUsrsWhoHaveChosenAns (long MchCod,unsigned QstInd,unsigned AnsInd); unsigned Mch_GetNumUsrsWhoHaveChosenAns (long MchCod,unsigned QstInd,unsigned AnsInd);

56
swad_match_print.h Normal file
View File

@ -0,0 +1,56 @@
// swad_match_print.h: matches prints in games using remote control
#ifndef _SWAD_MCH_PRN
#define _SWAD_MCH_PRN
/*
SWAD (Shared Workspace At a Distance in Spanish),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2020 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_test_print.h"
/*****************************************************************************/
/************************** Public types and constants ***********************/
/*****************************************************************************/
struct MchPrn_NumQuestions
{
unsigned All; // Total number of questions
unsigned NotBlank; // Answered questions
};
struct MchPrn_Print
{
long MchCod; // Match code
long UsrCod; // User who answered the match
time_t TimeUTC[Dat_NUM_START_END_TIME];
struct MchPrn_NumQuestions NumQsts; // Number of questions
double Score; // Total score of the match for this user
struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST];
};
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
#endif

View File

@ -77,7 +77,9 @@ struct MchRes_ICanView
/***************************** Private prototypes ****************************/ /***************************** Private prototypes ****************************/
/*****************************************************************************/ /*****************************************************************************/
static void MchRes_UpdateMyMatchResult (long MchCod,const struct TstPrn_Print *Print); static void MchPrn_ResetPrint (struct MchPrn_Print *Print);
static void MchRes_UpdateMyMatchResult (struct MchPrn_Print *Print);
static void MchRes_PutFormToSelUsrsToViewMchResults (void *Games); static void MchRes_PutFormToSelUsrsToViewMchResults (void *Games);
@ -104,46 +106,63 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
long GamCod, // <= 0 ==> any long GamCod, // <= 0 ==> any
const char *GamesSelectedCommas); const char *GamesSelectedCommas);
static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults, static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
unsigned NumTotalQsts, struct MchPrn_NumQuestions *NumTotalQsts,
unsigned NumTotalQstsNotBlank, double TotalScore,
double TotalScoreOfAllResults,
double TotalGrade); double TotalGrade);
static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
struct TstPrn_Print *Print); static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
static void MchRes_CheckIfICanSeeMatchResult (const struct Gam_Game *Game, static void MchRes_CheckIfICanSeeMatchResult (const struct Gam_Game *Game,
const struct Mch_Match *Match, const struct Mch_Match *Match,
long UsrCod, long UsrCod,
struct MchRes_ICanView *ICanView); struct MchRes_ICanView *ICanView);
/*****************************************************************************/
/**************************** Reset match print ******************************/
/*****************************************************************************/
static void MchPrn_ResetPrint (struct MchPrn_Print *Print)
{
Print->MchCod = -1L;
Print->UsrCod = -1L;
Print->TimeUTC[Dat_START_TIME] =
Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
Print->NumQsts.All =
Print->NumQsts.NotBlank = 0;
Print->Score = 0.0;
}
/*****************************************************************************/ /*****************************************************************************/
/*********** Compute score and create/update my result in a match ************/ /*********** Compute score and create/update my result in a match ************/
/*****************************************************************************/ /*****************************************************************************/
void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod) void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod)
{ {
struct TstPrn_Print Print; struct MchPrn_Print Print;
/***** Compute my match result *****/ /***** Compute my match result *****/
TstPrn_ResetPrint (&Print); MchPrn_ResetPrint (&Print);
Mch_GetMatchQuestionsFromDB (MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,&Print); Print.MchCod = MchCod;
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
Mch_GetMatchQuestionsFromDB (&Print);
Mch_ComputeScore (&Print); Mch_ComputeScore (&Print);
/***** Update my match result in database *****/ /***** Update my match result in database *****/
MchRes_UpdateMyMatchResult (MchCod,&Print); MchRes_UpdateMyMatchResult (&Print);
} }
/*****************************************************************************/ /*****************************************************************************/
/******************** Create/update my result in a match *********************/ /******************** Create/update my result in a match *********************/
/*****************************************************************************/ /*****************************************************************************/
static void MchRes_UpdateMyMatchResult (long MchCod,const struct TstPrn_Print *Print) static void MchRes_UpdateMyMatchResult (struct MchPrn_Print *Print)
{ {
Str_SetDecimalPointToUS (); // To print the floating point as a dot Str_SetDecimalPointToUS (); // To print the floating point as a dot
if (DB_QueryCOUNT ("can not get if match result exists", if (DB_QueryCOUNT ("can not get if match result exists",
"SELECT COUNT(*) FROM mch_results" "SELECT COUNT(*) FROM mch_results"
" WHERE MchCod=%ld AND UsrCod=%ld", " WHERE MchCod=%ld AND UsrCod=%ld",
MchCod,Gbl.Usrs.Me.UsrDat.UsrCod)) // Match print exists Print->MchCod,Print->UsrCod)) // Match print exists
/* Update result */ /* Update result */
DB_QueryUPDATE ("can not update match result", DB_QueryUPDATE ("can not update match result",
"UPDATE mch_results" "UPDATE mch_results"
@ -155,8 +174,8 @@ static void MchRes_UpdateMyMatchResult (long MchCod,const struct TstPrn_Print *P
Print->NumQsts.All, Print->NumQsts.All,
Print->NumQsts.NotBlank, Print->NumQsts.NotBlank,
Print->Score, Print->Score,
MchCod,Gbl.Usrs.Me.UsrDat.UsrCod); Print->MchCod,Print->UsrCod);
else // Match print doesn't exist else // Match print doesn't exist
/* Create result */ /* Create result */
DB_QueryINSERT ("can not create match result", DB_QueryINSERT ("can not create match result",
"INSERT mch_results " "INSERT mch_results "
@ -169,7 +188,7 @@ static void MchRes_UpdateMyMatchResult (long MchCod,const struct TstPrn_Print *P
"%u," // NumQsts "%u," // NumQsts
"%u," // NumQstsNotBlank "%u," // NumQstsNotBlank
"'%.15lg')", // Score "'%.15lg')", // Score
MchCod,Gbl.Usrs.Me.UsrDat.UsrCod, Print->MchCod,Print->UsrCod,
Print->NumQsts.All, Print->NumQsts.All,
Print->NumQsts.NotBlank, Print->NumQsts.NotBlank,
Print->Score); Print->Score);
@ -612,7 +631,7 @@ static void MchRes_ShowResultsBegin (struct Gam_Games *Games,
/***** Begin box *****/ /***** Begin box *****/
HTM_SECTION_Begin (MchRes_RESULTS_BOX_ID); HTM_SECTION_Begin (MchRes_RESULTS_BOX_ID);
Box_BoxBegin ("100%",Title, Box_BoxBegin (NULL,Title,
NULL,NULL, NULL,NULL,
Hlp_ASSESSMENT_Games_results,Box_NOT_CLOSABLE); Hlp_ASSESSMENT_Games_results,Box_NOT_CLOSABLE);
@ -741,24 +760,47 @@ static void MchRes_ShowHeaderMchResults (Usr_MeOrOther_t MeOrOther)
extern const char *Txt_Match; extern const char *Txt_Match;
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
extern const char *Txt_Questions; extern const char *Txt_Questions;
extern const char *Txt_ANSWERS_non_blank; extern const char *Txt_Answers;
extern const char *Txt_Score; extern const char *Txt_Score;
extern const char *Txt_Average_BR_score_BR_per_question;
extern const char *Txt_Grade; extern const char *Txt_Grade;
extern const char *Txt_ANSWERS_non_blank;
extern const char *Txt_ANSWERS_blank;
extern const char *Txt_total;
extern const char *Txt_average;
/***** First row *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
HTM_TH (1,2,"CT",Txt_User[MeOrOther == Usr_ME ? Gbl.Usrs.Me.UsrDat.Sex : HTM_TH (3,2,"CT LINE_BOTTOM",Txt_User[MeOrOther == Usr_ME ? Gbl.Usrs.Me.UsrDat.Sex :
Usr_SEX_UNKNOWN]); Usr_SEX_UNKNOWN]);
HTM_TH (1,1,"LT",Txt_START_END_TIME[Dat_START_TIME]); HTM_TH (3,1,"LT LINE_BOTTOM",Txt_START_END_TIME[Dat_START_TIME]);
HTM_TH (1,1,"LT",Txt_START_END_TIME[Dat_END_TIME ]); HTM_TH (3,1,"LT LINE_BOTTOM",Txt_START_END_TIME[Dat_END_TIME ]);
HTM_TH (1,1,"LT",Txt_Match); HTM_TH (3,1,"LT LINE_BOTTOM",Txt_Match);
HTM_TH (1,1,"RT",Txt_Questions); HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Questions);
HTM_TH (1,1,"RT",Txt_ANSWERS_non_blank); HTM_TH (1,2,"CT LINE_LEFT",Txt_Answers);
HTM_TH (1,1,"RT",Txt_Score); HTM_TH (1,2,"CT LINE_LEFT",Txt_Score);
HTM_TH (1,1,"RT",Txt_Average_BR_score_BR_per_question); HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Grade);
HTM_TH (1,1,"RT",Txt_Grade); HTM_TH (3,1,"LINE_BOTTOM LINE_LEFT",NULL);
HTM_TH_Empty (1);
HTM_TR_End ();
/***** Second row *****/
HTM_TR_Begin (NULL);
HTM_TH (1,1,"RT LINE_LEFT",Txt_ANSWERS_non_blank);
HTM_TH (1,1,"RT",Txt_ANSWERS_blank);
HTM_TH (1,1,"RT LINE_LEFT",Txt_total);
HTM_TH (1,1,"RT",Txt_average);
HTM_TR_End ();
/***** Third row *****/
HTM_TR_Begin (NULL);
HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","{-1&le;<em>p<sub>i</sub></em>&le;1}");
HTM_TH (1,1,"RT LINE_BOTTOM","{<em>p<sub>i</sub></em>=0}");
HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","<em>&Sigma;p<sub>i</sub></em>");
HTM_TH (1,1,"RT LINE_BOTTOM","-1&le;<em style=\"text-decoration:overline;\">p</em>&le;1");
HTM_TR_End (); HTM_TR_End ();
} }
@ -815,22 +857,22 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
unsigned NumResults; unsigned NumResults;
unsigned NumResult; unsigned NumResult;
static unsigned UniqueId = 0; static unsigned UniqueId = 0;
Dat_StartEndTime_t StartEndTime;
char *Id; char *Id;
struct MchPrn_Print Print;
unsigned NumQstsBlank;
struct Mch_Match Match; struct Mch_Match Match;
struct Gam_Game Game; struct Gam_Game Game;
Dat_StartEndTime_t StartEndTime;
unsigned NumQstsInThisResult;
unsigned NumQstsNotBlankInThisResult;
unsigned NumTotalQsts = 0;
unsigned NumTotalQstsNotBlank = 0;
double ScoreInThisResult;
double TotalScoreOfAllResults = 0.0;
double Grade; double Grade;
double TotalGrade = 0.0; struct MchPrn_NumQuestions NumTotalQsts;
time_t TimeUTC[Dat_NUM_START_END_TIME]; double TotalScore;
double TotalGrade;
/***** Reset match *****/ /***** Reset total number of questions and total score *****/
Mch_ResetMatch (&Match); NumTotalQsts.All =
NumTotalQsts.NotBlank = 0;
TotalScore = 0.0;
TotalGrade = 0.0;
/***** Set user *****/ /***** Set user *****/
UsrDat = (MeOrOther == Usr_ME) ? &Gbl.Usrs.Me.UsrDat : UsrDat = (MeOrOther == Usr_ME) ? &Gbl.Usrs.Me.UsrDat :
@ -893,12 +935,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/***** Make database query *****/ /***** Make database query *****/
NumResults = NumResults =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get matches results", (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches results",
"SELECT mch_results.MchCod," // row[0] "SELECT mch_results.MchCod" // row[0]
"UNIX_TIMESTAMP(mch_results.StartTime)," // row[1]
"UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
"mch_results.NumQsts," // row[3]
"mch_results.NumQstsNotBlank," // row[4]
"mch_results.Score" // row[5]
" FROM mch_results,mch_matches,gam_games" " FROM mch_results,mch_matches,gam_games"
" WHERE mch_results.UsrCod=%ld" " WHERE mch_results.UsrCod=%ld"
"%s" // Match subquery "%s" // Match subquery
@ -931,11 +968,16 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
/* Get match code (row[0]) */ /* Get match code (row[0]) */
if ((Match.MchCod = Str_ConvertStrCodToLongCod (row[0])) < 0) MchPrn_ResetPrint (&Print);
if ((Print.MchCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of match."); Lay_ShowErrorAndExit ("Wrong code of match.");
Mch_GetDataOfMatchByCod (&Match);
/* Get match result data */
Print.UsrCod = UsrDat->UsrCod;
MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
/* Get data of match and game */ /* Get data of match and game */
Match.MchCod = Print.MchCod;
Mch_GetDataOfMatchByCod (&Match); Mch_GetDataOfMatchByCod (&Match);
Game.GamCod = Match.GamCod; Game.GamCod = Match.GamCod;
Gam_GetDataOfGameByCod (&Game); Gam_GetDataOfGameByCod (&Game);
@ -946,18 +988,17 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
if (NumResult) if (NumResult)
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/* Write start/end times (row[1], row[2] hold UTC start/end times) */ /* Write start/end times */
for (StartEndTime = (Dat_StartEndTime_t) 0; for (StartEndTime = (Dat_StartEndTime_t) 0;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++) StartEndTime++)
{ {
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[1 + StartEndTime]);
UniqueId++; UniqueId++;
if (asprintf (&Id,"mch_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0) if (asprintf (&Id,"mch_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
Lay_NotEnoughMemoryExit (); Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"", HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"",
Id,Gbl.RowEvenOdd); Id,Gbl.RowEvenOdd);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime], Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
true,true,false,0x7); true,true,false,0x7);
HTM_TD_End (); HTM_TD_End ();
@ -969,51 +1010,56 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
HTM_Txt (Match.Title); HTM_Txt (Match.Title);
HTM_TD_End (); HTM_TD_End ();
/* Accumulate questions and score */
if (ICanView.Score) if (ICanView.Score)
{ {
/* Get number of questions (row[3]) */ NumTotalQsts.All += Print.NumQsts.All;
if (sscanf (row[3],"%u",&NumQstsInThisResult) != 1) NumTotalQsts.NotBlank += Print.NumQsts.NotBlank;
NumQstsInThisResult = 0; TotalScore += Print.Score;
NumTotalQsts += NumQstsInThisResult;
/* Get number of questions not blank (row[4]) */
if (sscanf (row[4],"%u",&NumQstsNotBlankInThisResult) != 1)
NumQstsNotBlankInThisResult = 0;
NumTotalQstsNotBlank += NumQstsNotBlankInThisResult;
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
/* Get score (row[5]) */
if (sscanf (row[5],"%lf",&ScoreInThisResult) != 1)
ScoreInThisResult = 0.0;
TotalScoreOfAllResults += ScoreInThisResult;
Str_SetDecimalPointToLocal (); // Return to local system
} }
/* Write number of questions */ /* Write number of questions */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
HTM_Unsigned (NumQstsInThisResult); HTM_Unsigned (Print.NumQsts.All);
else else
Ico_PutIconNotVisible (); Ico_PutIconNotVisible ();
HTM_TD_End (); HTM_TD_End ();
/* Write number of questions not blank */ /* Write number of non-blank answers */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
HTM_Unsigned (NumQstsNotBlankInThisResult); {
if (Print.NumQsts.NotBlank)
HTM_Unsigned (Print.NumQsts.NotBlank);
else
HTM_Light0 ();
}
else
Ico_PutIconNotVisible ();
HTM_TD_End ();
/* Write number of blank answers */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
NumQstsBlank = Print.NumQsts.All - Print.NumQsts.NotBlank;
if (ICanView.Score)
{
if (NumQstsBlank)
HTM_Unsigned (NumQstsBlank);
else
HTM_Light0 ();
}
else else
Ico_PutIconNotVisible (); Ico_PutIconNotVisible ();
HTM_TD_End (); HTM_TD_End ();
/* Write score */ /* Write score */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
{ {
HTM_Double2Decimals (ScoreInThisResult); HTM_Double2Decimals (Print.Score);
HTM_Txt ("/"); HTM_Txt ("/");
HTM_Unsigned (NumQstsInThisResult); HTM_Unsigned (Print.NumQsts.All);
} }
else else
Ico_PutIconNotVisible (); Ico_PutIconNotVisible ();
@ -1022,18 +1068,18 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Write average score per question */ /* Write average score per question */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
HTM_Double2Decimals (NumQstsInThisResult ? ScoreInThisResult / HTM_Double2Decimals (Print.NumQsts.All ? Print.Score /
(double) NumQstsInThisResult : (double) Print.NumQsts.All :
0.0); 0.0);
else else
Ico_PutIconNotVisible (); Ico_PutIconNotVisible ();
HTM_TD_End (); HTM_TD_End ();
/* Write grade over maximum grade */ /* Write grade over maximum grade */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
{ {
Grade = TstPrn_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,Game.MaxGrade); Grade = TstPrn_ComputeGrade (Print.NumQsts.All,Print.Score,Game.MaxGrade);
TstPrn_ShowGrade (Grade,Game.MaxGrade); TstPrn_ShowGrade (Grade,Game.MaxGrade);
TotalGrade += Grade; TotalGrade += Grade;
} }
@ -1042,7 +1088,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
HTM_TD_End (); HTM_TD_End ();
/* Link to show this result */ /* Link to show this result */
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Result) if (ICanView.Result)
{ {
Games->GamCod = Match.GamCod; Games->GamCod = Match.GamCod;
@ -1071,13 +1117,36 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/***** Write totals for this user *****/ /***** Write totals for this user *****/
MchRes_ShowMchResultsSummaryRow (NumResults, MchRes_ShowMchResultsSummaryRow (NumResults,
NumTotalQsts,NumTotalQstsNotBlank, &NumTotalQsts,
TotalScoreOfAllResults, TotalScore,
TotalGrade); TotalGrade);
} }
else else
{ {
HTM_TD_ColouredEmpty (9); /* Columns for dates and match */
HTM_TD_Begin ("colspan=\"3\" class=\"LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End ();
/* Column for questions */
HTM_TD_Begin ("class=\"LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End ();
/* Columns for answers */
HTM_TD_Begin ("colspan=\"2\" class=\"LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End ();
/* Columns for score */
HTM_TD_Begin ("colspan=\"2\" class=\"LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End ();
/* Column for grade */
HTM_TD_Begin ("class=\"LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End ();
/* Column for link to show the result */
HTM_TD_Begin ("class=\"LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();
} }
@ -1092,9 +1161,8 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/*****************************************************************************/ /*****************************************************************************/
static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults, static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
unsigned NumTotalQsts, struct MchPrn_NumQuestions *NumTotalQsts,
unsigned NumTotalQstsNotBlank, double TotalScore,
double TotalScoreOfAllResults,
double TotalGrade) double TotalGrade)
{ {
extern const char *Txt_Matches; extern const char *Txt_Matches;
@ -1103,44 +1171,50 @@ static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/***** Row title *****/ /***** Row title *****/
HTM_TD_Begin ("colspan=\"3\" class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("colspan=\"3\" class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_TxtColonNBSP (Txt_Matches); HTM_TxtColonNBSP (Txt_Matches);
HTM_Unsigned (NumResults); HTM_Unsigned (NumResults);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of questions *****/ /***** Write total number of questions *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (NumResults) if (NumResults)
HTM_Unsigned (NumTotalQsts); HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of questions not blank *****/ /***** Write total number of non-blank answers *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (NumResults) if (NumResults)
HTM_Unsigned (NumTotalQstsNotBlank); HTM_Unsigned (NumTotalQsts->NotBlank);
HTM_TD_End ();
/***** Write total number of blank answers *****/
HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumResults)
HTM_Unsigned (NumTotalQsts->All - NumTotalQsts->NotBlank);
HTM_TD_End (); HTM_TD_End ();
/***** Write total score *****/ /***** Write total score *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (TotalScoreOfAllResults); HTM_Double2Decimals (TotalScore);
HTM_Txt ("/"); HTM_Txt ("/");
HTM_Unsigned (NumTotalQsts); HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End (); HTM_TD_End ();
/***** Write average score per question *****/ /***** Write average score per question *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (NumTotalQsts ? TotalScoreOfAllResults / HTM_Double2Decimals (NumTotalQsts->All ? TotalScore /
(double) NumTotalQsts : (double) NumTotalQsts->All :
0.0); 0.0);
HTM_TD_End (); HTM_TD_End ();
/***** Write total grade *****/ /***** Write total grade *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (TotalGrade); HTM_Double2Decimals (TotalGrade);
HTM_TD_End (); HTM_TD_End ();
/***** Last cell *****/ /***** Last cell *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TD_End (); HTM_TD_End ();
/***** End row *****/ /***** End row *****/
@ -1169,7 +1243,7 @@ void MchRes_ShowOneMchResult (void)
struct UsrData *UsrDat; struct UsrData *UsrDat;
Dat_StartEndTime_t StartEndTime; Dat_StartEndTime_t StartEndTime;
char *Id; char *Id;
struct TstPrn_Print Print; struct MchPrn_Print Print;
bool ShowPhoto; bool ShowPhoto;
char PhotoURL[PATH_MAX + 1]; char PhotoURL[PATH_MAX + 1];
struct MchRes_ICanView ICanView; struct MchRes_ICanView ICanView;
@ -1200,8 +1274,9 @@ void MchRes_ShowOneMchResult (void)
} }
/***** Get match result data *****/ /***** Get match result data *****/
TstPrn_ResetPrint (&Print); Print.MchCod = Match.MchCod;
MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Print); Print.UsrCod = UsrDat->UsrCod;
MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
/***** Check if I can view this match result and score *****/ /***** Check if I can view this match result and score *****/
MchRes_CheckIfICanSeeMatchResult (&Game,&Match,UsrDat->UsrCod,&ICanView); MchRes_CheckIfICanSeeMatchResult (&Game,&Match,UsrDat->UsrCod,&ICanView);
@ -1209,7 +1284,7 @@ void MchRes_ShowOneMchResult (void)
if (ICanView.Result) // I am allowed to view this match result if (ICanView.Result) // I am allowed to view this match result
{ {
/***** Get questions and user's answers of the match result from database *****/ /***** Get questions and user's answers of the match result from database *****/
Mch_GetMatchQuestionsFromDB (Match.MchCod,UsrDat->UsrCod,&Print); Mch_GetMatchQuestionsFromDB (&Print);
/***** Begin box *****/ /***** Begin box *****/
Box_BoxBegin (NULL,Match.Title, Box_BoxBegin (NULL,Match.Title,
@ -1358,7 +1433,11 @@ void MchRes_ShowOneMchResult (void)
HTM_TR_End (); HTM_TR_End ();
/***** Write answers and solutions *****/ /***** Write answers and solutions *****/
TstPrn_ShowPrintAnswers (UsrDat,&Print,Game.Visibility); TstPrn_ShowPrintAnswers (UsrDat,
Print.NumQsts.All,
Print.PrintedQuestions,
Print.TimeUTC,
Game.Visibility);
/***** End table *****/ /***** End table *****/
HTM_TABLE_End (); HTM_TABLE_End ();
@ -1374,8 +1453,7 @@ void MchRes_ShowOneMchResult (void)
/************* Get data of a match result using its match code ***************/ /************* Get data of a match result using its match code ***************/
/*****************************************************************************/ /*****************************************************************************/
static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod, static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
struct TstPrn_Print *Print)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -1395,7 +1473,7 @@ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
" AND mch_results.MchCod=mch_matches.MchCod" " AND mch_results.MchCod=mch_matches.MchCod"
" AND mch_matches.GamCod=gam_games.GamCod" " AND mch_matches.GamCod=gam_games.GamCod"
" AND gam_games.CrsCod=%ld", // Extra check " AND gam_games.CrsCod=%ld", // Extra check
MchCod,UsrCod, Print->MchCod,Print->UsrCod,
Gbl.Hierarchy.Crs.CrsCod) == 1) Gbl.Hierarchy.Crs.CrsCod) == 1)
{ {
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
@ -1421,11 +1499,7 @@ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
Str_SetDecimalPointToLocal (); // Return to local system Str_SetDecimalPointToLocal (); // Return to local system
} }
else else
{ MchPrn_ResetPrint (Print);
Print->NumQsts.All =
Print->NumQsts.NotBlank = 0;
Print->Score = 0.0;
}
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);

View File

@ -27,8 +27,6 @@
/********************************* Headers ***********************************/ /********************************* Headers ***********************************/
/*****************************************************************************/ /*****************************************************************************/
#include "swad_test_print.h"
/*****************************************************************************/ /*****************************************************************************/
/************************** Public types and constants ***********************/ /************************** Public types and constants ***********************/
/*****************************************************************************/ /*****************************************************************************/

View File

@ -106,8 +106,9 @@ static void TstPrn_WriteTxtAnsToFill (const struct TstPrn_PrintedQuestion *Print
static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers); static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers);
static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat, static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
struct TstPrn_Print *Print, struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST],
unsigned NumQst, unsigned NumQst,
time_t TimeUTC[Dat_NUM_START_END_TIME],
struct Tst_Question *Question, struct Tst_Question *Question,
bool QuestionExists, bool QuestionExists,
unsigned Visibility); unsigned Visibility);
@ -170,7 +171,7 @@ static void TstPrn_StoreOneQstOfPrintInDB (const struct TstPrn_Print *Print,
static void TstPrn_PutFormToSelectUsrsToViewUsrsPrints (__attribute__((unused)) void *Args); static void TstPrn_PutFormToSelectUsrsToViewUsrsPrints (__attribute__((unused)) void *Args);
static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args); static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args);
static void TstPrn_ShowHeaderPrints (void); static void TstPrn_ShowHeaderPrints (Usr_MeOrOther_t MeOrOther);
static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat); static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat);
static void TstPrn_ShowPrintsSummaryRow (bool ItsMe, static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
unsigned NumPrints, unsigned NumPrints,
@ -184,7 +185,7 @@ static void TstRes_CheckIfICanSeePrintResult (const struct TstPrn_Print *Print,
static void TstPrn_ShowTagsPresentInAPrint (long ResCod); static void TstPrn_ShowTagsPresentInAPrint (long ResCod);
/*****************************************************************************/ /*****************************************************************************/
/******************************** Reset exam *********************************/ /***************************** Reset test print ******************************/
/*****************************************************************************/ /*****************************************************************************/
void TstPrn_ResetPrint (struct TstPrn_Print *Print) void TstPrn_ResetPrint (struct TstPrn_Print *Print)
@ -616,8 +617,10 @@ void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
QuestionExists = Tst_GetQstDataFromDB (&Question); QuestionExists = Tst_GetQstDataFromDB (&Question);
/***** Write question and answers *****/ /***** Write question and answers *****/
TstPrn_WriteQstAndAnsExam (&Gbl.Usrs.Me.UsrDat,Print, TstPrn_WriteQstAndAnsExam (&Gbl.Usrs.Me.UsrDat,
NumQst,&Question,QuestionExists, Print->PrintedQuestions,NumQst,
Print->TimeUTC,
&Question,QuestionExists,
TstCfg_GetConfigVisibility ()); TstCfg_GetConfigVisibility ());
/***** Store test exam question in database *****/ /***** Store test exam question in database *****/
@ -645,8 +648,9 @@ void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
/*****************************************************************************/ /*****************************************************************************/
static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat, static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
struct TstPrn_Print *Print, struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST],
unsigned NumQst, unsigned NumQst,
time_t TimeUTC[Dat_NUM_START_END_TIME],
struct Tst_Question *Question, struct Tst_Question *Question,
bool QuestionExists, bool QuestionExists,
unsigned Visibility) unsigned Visibility)
@ -688,7 +692,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/***** If this question has been edited later than test time /***** If this question has been edited later than test time
==> don't show question ****/ ==> don't show question ****/
if (QuestionExists) if (QuestionExists)
QuestionUneditedAfterExam = (Question->EditTime < Print->TimeUTC[Dat_START_TIME]); QuestionUneditedAfterExam = (Question->EditTime < TimeUTC[Dat_START_TIME]);
else else
QuestionUneditedAfterExam = false; QuestionUneditedAfterExam = false;
@ -718,8 +722,8 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
"TEST_MED_SHOW"); "TEST_MED_SHOW");
/* Answers */ /* Answers */
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],Question); TstPrn_ComputeAnswerScore (&PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,&Print->PrintedQuestions[NumQst],Question, TstPrn_WriteAnswersExam (UsrDat,&PrintedQuestions[NumQst],Question,
ICanView,"TEST_TXT","TEST_TXT_LIGHT"); ICanView,"TEST_TXT","TEST_TXT_LIGHT");
} }
else else
@ -734,11 +738,11 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
HTM_DIV_Begin ("class=\"DAT_SMALL LM\""); HTM_DIV_Begin ("class=\"DAT_SMALL LM\"");
HTM_TxtColonNBSP (Txt_Score); HTM_TxtColonNBSP (Txt_Score);
HTM_SPAN_Begin ("class=\"%s\"", HTM_SPAN_Begin ("class=\"%s\"",
Print->PrintedQuestions[NumQst].StrAnswers[0] ? PrintedQuestions[NumQst].StrAnswers[0] ?
(Print->PrintedQuestions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect (PrintedQuestions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect
"ANS_BAD") : // Wrong "ANS_BAD") :// Wrong
"ANS_0"); // Blank answer "ANS_0"); // Blank answer
HTM_Double2Decimals (Print->PrintedQuestions[NumQst].Score); HTM_Double2Decimals (PrintedQuestions[NumQst].Score);
HTM_SPAN_End (); HTM_SPAN_End ();
HTM_DIV_End (); HTM_DIV_End ();
} }
@ -1926,7 +1930,7 @@ void TstPrn_ShowMyPrints (void)
Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,2); Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,2);
/***** Header of the table with the list of users *****/ /***** Header of the table with the list of users *****/
TstPrn_ShowHeaderPrints (); TstPrn_ShowHeaderPrints (Usr_ME);
/***** List my test exams *****/ /***** List my test exams *****/
TstCfg_GetConfigFromDB (); // To get visibility TstCfg_GetConfigFromDB (); // To get visibility
@ -1966,7 +1970,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,5); Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,5);
/***** Header of the table with the list of users *****/ /***** Header of the table with the list of users *****/
TstPrn_ShowHeaderPrints (); TstPrn_ShowHeaderPrints (Usr_OTHER);
/***** List the test exams of the selected users *****/ /***** List the test exams of the selected users *****/
Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
@ -1992,7 +1996,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
/************************ Show header of my test exams ***********************/ /************************ Show header of my test exams ***********************/
/*****************************************************************************/ /*****************************************************************************/
static void TstPrn_ShowHeaderPrints (void) static void TstPrn_ShowHeaderPrints (Usr_MeOrOther_t MeOrOther)
{ {
extern const char *Txt_User[Usr_NUM_SEXS]; extern const char *Txt_User[Usr_NUM_SEXS];
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
@ -2008,7 +2012,8 @@ static void TstPrn_ShowHeaderPrints (void)
/***** First row *****/ /***** First row *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
HTM_TH (3,2,"CT LINE_BOTTOM",Txt_User[Usr_SEX_UNKNOWN]); HTM_TH (3,2,"CT LINE_BOTTOM",Txt_User[MeOrOther == Usr_ME ? Gbl.Usrs.Me.UsrDat.Sex :
Usr_SEX_UNKNOWN]);
HTM_TH (3,1,"LT LINE_BOTTOM",Txt_START_END_TIME[Dat_START_TIME]); HTM_TH (3,1,"LT LINE_BOTTOM",Txt_START_END_TIME[Dat_START_TIME]);
HTM_TH (3,1,"LT LINE_BOTTOM",Txt_START_END_TIME[Dat_END_TIME ]); HTM_TH (3,1,"LT LINE_BOTTOM",Txt_START_END_TIME[Dat_END_TIME ]);
HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Questions); HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Questions);
@ -2032,8 +2037,8 @@ static void TstPrn_ShowHeaderPrints (void)
/***** Third row *****/ /***** Third row *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","-1&le;<em>p<sub>i</sub></em>&le;1"); HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","{-1&le;<em>p<sub>i</sub></em>&le;1}");
HTM_TH (1,1,"RT LINE_BOTTOM","<em>p<sub>i</sub></em>=0"); HTM_TH (1,1,"RT LINE_BOTTOM","{<em>p<sub>i</sub></em>=0}");
HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","<em>&Sigma;p<sub>i</sub></em>"); HTM_TH (1,1,"RT LINE_BOTTOM LINE_LEFT","<em>&Sigma;p<sub>i</sub></em>");
HTM_TH (1,1,"RT LINE_BOTTOM","-1&le;<em style=\"text-decoration:overline;\">p</em>&le;1"); HTM_TH (1,1,"RT LINE_BOTTOM","-1&le;<em style=\"text-decoration:overline;\">p</em>&le;1");
@ -2063,9 +2068,6 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
struct TstRes_ICanView ICanView; struct TstRes_ICanView ICanView;
char *ClassDat; char *ClassDat;
/***** Reset print *****/
TstPrn_ResetPrint (&Print);
/***** Reset total number of questions and total score *****/ /***** Reset total number of questions and total score *****/
NumTotalQsts.All = NumTotalQsts.All =
NumTotalQsts.NotBlank = 0; NumTotalQsts.NotBlank = 0;
@ -2104,7 +2106,6 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
/* Get print code (row[0]) */ /* Get print code (row[0]) */
TstPrn_ResetPrint (&Print);
if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0) if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of test exam."); Lay_ShowErrorAndExit ("Wrong code of test exam.");
@ -2145,17 +2146,15 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
} }
/* Write number of questions */ /* Write number of questions */
HTM_TD_Begin ("class=\"%s LINE_LEFT RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"%s RT LINE_LEFT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanView.Result) if (ICanView.Result)
{
HTM_Unsigned (Print.NumQsts.All); HTM_Unsigned (Print.NumQsts.All);
}
else else
Ico_PutIconNotVisible (); Ico_PutIconNotVisible ();
HTM_TD_End (); HTM_TD_End ();
/* Write number of non-blank answers */ /* Write number of non-blank answers */
HTM_TD_Begin ("class=\"%s LINE_LEFT RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"%s RT LINE_LEFT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanView.Result) if (ICanView.Result)
{ {
if (Print.NumQsts.NotBlank) if (Print.NumQsts.NotBlank)
@ -2182,7 +2181,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
HTM_TD_End (); HTM_TD_End ();
/* Write score */ /* Write score */
HTM_TD_Begin ("class=\"%s LINE_LEFT RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"%s RT LINE_LEFT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
{ {
HTM_Double2Decimals (Print.Score); HTM_Double2Decimals (Print.Score);
@ -2204,7 +2203,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
HTM_TD_End (); HTM_TD_End ();
/* Write grade */ /* Write grade */
HTM_TD_Begin ("class=\"%s LINE_LEFT RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"%s RT LINE_LEFT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanView.Score) if (ICanView.Score)
TstPrn_ComputeAndShowGrade (Print.NumQsts.All,Print.Score,Tst_SCORE_MAX); TstPrn_ComputeAndShowGrade (Print.NumQsts.All,Print.Score,Tst_SCORE_MAX);
else else
@ -2212,7 +2211,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
HTM_TD_End (); HTM_TD_End ();
/* Link to show this test exam */ /* Link to show this test exam */
HTM_TD_Begin ("class=\"LINE_LEFT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Result) if (ICanView.Result)
{ {
Frm_StartForm (Gbl.Action.Act == ActSeeMyTstResCrs ? ActSeeOneTstResMe : Frm_StartForm (Gbl.Action.Act == ActSeeMyTstResCrs ? ActSeeOneTstResMe :
@ -2326,31 +2325,31 @@ static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/***** Row title *****/ /***** Row title *****/
HTM_TD_Begin ("colspan=\"2\" class=\"DAT_N LINE_TOP LINE_BOTTOM RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("colspan=\"2\" class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_TxtColonNBSP (Txt_Visible_tests); HTM_TxtColonNBSP (Txt_Visible_tests);
HTM_Unsigned (NumPrints); HTM_Unsigned (NumPrints);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of questions *****/ /***** Write total number of questions *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (NumPrints) if (NumPrints)
HTM_Unsigned (NumTotalQsts->All); HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of non-blank answers *****/ /***** Write total number of non-blank answers *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (NumPrints) if (NumPrints)
HTM_Unsigned (NumTotalQsts->NotBlank); HTM_Unsigned (NumTotalQsts->NotBlank);
HTM_TD_End (); HTM_TD_End ();
/***** Write total number of blank answers *****/ /***** Write total number of blank answers *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (NumPrints) if (NumPrints)
HTM_Unsigned (NumTotalQsts->All - NumTotalQsts->NotBlank); HTM_Unsigned (NumTotalQsts->All - NumTotalQsts->NotBlank);
HTM_TD_End (); HTM_TD_End ();
/***** Write total score *****/ /***** Write total score *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewTotalScore) if (ICanViewTotalScore)
{ {
HTM_Double2Decimals (TotalScore); HTM_Double2Decimals (TotalScore);
@ -2360,14 +2359,14 @@ static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
HTM_TD_End (); HTM_TD_End ();
/***** Write average score per question *****/ /***** Write average score per question *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewTotalScore) if (ICanViewTotalScore)
HTM_Double2Decimals (NumTotalQsts->All ? TotalScore / (double) NumTotalQsts->All : HTM_Double2Decimals (NumTotalQsts->All ? TotalScore / (double) NumTotalQsts->All :
0.0); 0.0);
HTM_TD_End (); HTM_TD_End ();
/***** Write grade over Tst_SCORE_MAX *****/ /***** Write grade over Tst_SCORE_MAX *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP LINE_BOTTOM LINE_LEFT RM COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewTotalScore) if (ICanViewTotalScore)
TstPrn_ComputeAndShowGrade (NumTotalQsts->All,TotalScore,Tst_SCORE_MAX); TstPrn_ComputeAndShowGrade (NumTotalQsts->All,TotalScore,Tst_SCORE_MAX);
HTM_TD_End (); HTM_TD_End ();
@ -2568,7 +2567,10 @@ void TstPrn_ShowOnePrint (void)
HTM_TR_End (); HTM_TR_End ();
/***** Write answers and solutions *****/ /***** Write answers and solutions *****/
TstPrn_ShowPrintAnswers (&Gbl.Usrs.Other.UsrDat,&Print, TstPrn_ShowPrintAnswers (&Gbl.Usrs.Other.UsrDat,
Print.NumQsts.All,
Print.PrintedQuestions,
Print.TimeUTC,
TstCfg_GetConfigVisibility ()); TstCfg_GetConfigVisibility ());
/***** End table *****/ /***** End table *****/
@ -2659,7 +2661,9 @@ static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
/*****************************************************************************/ /*****************************************************************************/
void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat, void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
struct TstPrn_Print *Print, unsigned NumQsts,
struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST],
time_t TimeUTC[Dat_NUM_START_END_TIME],
unsigned Visibility) unsigned Visibility)
{ {
unsigned NumQst; unsigned NumQst;
@ -2667,22 +2671,24 @@ void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
bool QuestionExists; bool QuestionExists;
for (NumQst = 0; for (NumQst = 0;
NumQst < Print->NumQsts.All; NumQst < NumQsts;
NumQst++) NumQst++)
{ {
Gbl.RowEvenOdd = NumQst % 2; Gbl.RowEvenOdd = NumQst % 2;
/***** Create test question *****/ /***** Create test question *****/
Tst_QstConstructor (&Question); Tst_QstConstructor (&Question);
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; Question.QstCod = PrintedQuestions[NumQst].QstCod;
/***** Get question data *****/ /***** Get question data *****/
QuestionExists = Tst_GetQstDataFromDB (&Question); QuestionExists = Tst_GetQstDataFromDB (&Question);
/***** Write questions and answers *****/ /***** Write questions and answers *****/
TstPrn_WriteQstAndAnsExam (UsrDat,Print, TstPrn_WriteQstAndAnsExam (UsrDat,
NumQst,&Question,QuestionExists, PrintedQuestions,NumQst,
Visibility); TimeUTC,
&Question,QuestionExists,
Visibility);
/***** Destroy test question *****/ /***** Destroy test question *****/
Tst_QstDestructor (&Question); Tst_QstDestructor (&Question);

View File

@ -146,7 +146,9 @@ long TstPrn_GetParamPrnCod (void);
void TstPrn_ShowOnePrint (void); void TstPrn_ShowOnePrint (void);
void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat, void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
struct TstPrn_Print *Print, unsigned NumQsts,
struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST],
time_t TimeUTC[Dat_NUM_START_END_TIME],
unsigned Visibility); unsigned Visibility);
void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print); void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print);