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:
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 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: 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.255.1: Jun 23, 2020 Changes in listing of test results. (303655 lines)
Version 19.256: Jun 24, 2020 Code refactoring in tests, exams and matches results. (303841 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.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)

View File

@ -66,7 +66,9 @@ extern struct Globals Gbl;
/***************************** 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 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)
{
Print->PrnCod = -1L;
Print->SesCod = -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_END_TIME ] = (time_t) 0;
Print->Sent = false; // After creating an exam print, it's not sent
@ -191,7 +188,6 @@ void ExaPrn_ShowExamPrint (void)
Exa_ResetExams (&Exams);
Exa_ResetExam (&Exam);
ExaSes_ResetSession (&Session);
ExaPrn_ResetPrint (&Print);
/***** Get and check parameters *****/
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
@ -202,7 +198,7 @@ void ExaPrn_ShowExamPrint (void)
/***** Get print data from database *****/
Print.SesCod = Session.SesCod;
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
ExaPrn_GetDataOfPrintByCodAndUsrCod (&Print);
ExaPrn_GetDataOfPrintBySesCodAndUsrCod (&Print);
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);
}
/*****************************************************************************/
/**************** 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 *********/
/*****************************************************************************/
void ExaPrn_GetDataOfPrintByCodAndUsrCod (struct ExaPrn_Print *Print)
void ExaPrn_GetDataOfPrintBySesCodAndUsrCod (struct ExaPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows;
/***** Make database query *****/
if (DB_QuerySELECT (&mysql_res,"can not get data of an exam print",
"SELECT PrnCod," // row[0]
"UNIX_TIMESTAMP(StartTime)," // row[1]
"UNIX_TIMESTAMP(EndTime)," // row[2]
"NumQsts," // row[3]
"NumQstsNotBlank," // row[4]
"Sent," // row[5]
"Score" // row[6]
" FROM exa_prints"
" WHERE SesCod=%ld"
" AND UsrCod=%ld",
Print->SesCod,
Print->UsrCod) == 1)
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 SesCod=%ld"
" 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]) */
Print->PrnCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get date-time (row[1] and row[2] hold UTC date-time) */
Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]);
Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]);
/* Get session code (row[1]) */
Print->SesCod = Str_ConvertStrCodToLongCod (row[1]);
/* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&Print->NumQsts.All) != 1)
/* Get user code (row[2]) */
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;
/* Get number of questions not blank (row[4]) */
if (sscanf (row[4],"%u",&Print->NumQsts.NotBlank) != 1)
/* Get number of questions not blank (row[6]) */
if (sscanf (row[6],"%u",&Print->NumQsts.NotBlank) != 1)
Print->NumQsts.NotBlank = 0;
/* Get if exam has been sent (row[5]) */
Print->Sent = (row[5][0] == 'Y');
/* Get if exam has been sent (row[7]) */
Print->Sent = (row[7][0] == 'Y');
/* Get score (row[6]) */
/* Get score (row[8]) */
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;
Str_SetDecimalPointToLocal (); // Return to local system
}
else
ExaPrn_ResetPrintExceptEvtCodAndUsrCod (Print);
ExaPrn_ResetPrint (Print);
/***** 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_ResetExam (&Exam);
ExaSes_ResetSession (&Session);
ExaPrn_ResetPrint (&Print);
/***** Get session code *****/
Print.SesCod = ExaSes_GetParamSesCod ();
/***** Get print data *****/
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
ExaPrn_GetDataOfPrintByCodAndUsrCod (&Print);
ExaPrn_GetDataOfPrintBySesCodAndUsrCod (&Print);
if (Print.PrnCod <= 0)
Lay_WrongExamExit ();

View File

@ -80,7 +80,8 @@ void ExaPrn_ResetPrint (struct ExaPrn_Print *Print);
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);

View File

@ -746,11 +746,11 @@ static void ExaRes_ShowHeaderResults (Usr_MeOrOther_t MeOrOther)
/***** Third row *****/
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","-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","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 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","{<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","{<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");
@ -820,12 +820,6 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
struct ExaPrn_Score TotalScore;
double Grade;
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 *****/
NumTotalQsts.All =
@ -918,10 +912,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
// must be able to access exams taken in other groups
NumResults =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get sessions results",
"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]
"SELECT exa_prints.PrnCod" // row[0]
" FROM exa_prints,exa_sessions,exa_exams"
" WHERE exa_prints.UsrCod=%ld"
"%s" // Session subquery
@ -960,11 +951,11 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of exam print.");
/* Get session code (row[1]) */
if ((Session.SesCod = Str_ConvertStrCodToLongCod (row[1])) < 0)
Lay_ShowErrorAndExit ("Wrong code of session.");
/* Get print data */
ExaPrn_GetDataOfPrintByPrnCod (&Print);
/* Get data of session and exam */
Session.SesCod = Print.SesCod;
ExaSes_GetDataOfSessionByCod (&Session);
Exam.ExaCod = Session.ExaCod;
Exa_GetDataOfExamByCod (&Exam);
@ -975,18 +966,17 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
if (NumResult)
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;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++)
{
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[2 + StartEndTime]);
UniqueId++;
if (asprintf (&Id,"exa_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"",
Id,Gbl.RowEvenOdd);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime],
Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
true,true,false,0x7);
HTM_TD_End ();
@ -1017,7 +1007,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
}
/* 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)
HTM_Unsigned (Print.NumQsts.All);
else
@ -1052,7 +1042,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End ();
/* 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 (Print.NumQsts.Valid.Correct)
@ -1115,7 +1105,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End ();
/* 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)
{
HTM_Double2Decimals (Print.Score.Valid);
@ -1137,7 +1127,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams,
HTM_TD_End ();
/* 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)
{
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 ();
/* 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)
{
Exams->ExaCod = Session.ExaCod;
@ -1230,18 +1220,18 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TR_Begin (NULL);
/***** 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_Unsigned (NumResults);
HTM_TD_End ();
/***** 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_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->Valid.Total);
else
@ -1249,7 +1239,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End ();
/***** 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;
if (NumTotalQstsInvalid)
HTM_Unsigned (NumTotalQstsInvalid);
@ -1258,7 +1248,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->Valid.Correct);
else
@ -1266,21 +1256,21 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->Valid.Wrong.Negative);
else
HTM_Light0 ();
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)
HTM_Unsigned (NumTotalQsts->Valid.Wrong.Zero);
else
HTM_Light0 ();
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)
HTM_Unsigned (NumTotalQsts->Valid.Wrong.Positive);
else
@ -1288,7 +1278,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->Valid.Blank);
else
@ -1296,14 +1286,14 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
HTM_TD_End ();
/***** 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_Txt ("/");
HTM_Unsigned (NumTotalQsts->Valid.Total);
HTM_TD_End ();
/***** 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 /
(double) NumTotalQsts->Valid.Total :
0.0);
@ -1311,7 +1301,7 @@ static void ExaRes_ShowResultsSummaryRow (unsigned NumResults,
/***** 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_TD_End ();
@ -1361,11 +1351,9 @@ void ExaRes_ShowOneExaResult (void)
}
/***** Get exam print data *****/
ExaPrn_ResetPrint (&Print);
Print.SesCod = Session.SesCod;
Print.UsrCod = UsrDat->UsrCod;
ExaPrn_GetDataOfPrintByCodAndUsrCod (&Print);
ExaPrn_GetDataOfPrintBySesCodAndUsrCod (&Print);
/***** Set log action and print code *****/
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 ******************/
/*****************************************************************************/
void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
struct TstPrn_Print *Print)
void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -4055,7 +4054,7 @@ void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
" AND mch_matches.MchCod=mch_indexes.MchCod"
" AND gam_questions.QstInd=mch_indexes.QstInd"
" ORDER BY gam_questions.QstInd",
MchCod);
Print->MchCod);
for (NumQst = 0, Print->NumQsts.NotBlank = 0;
NumQst < Print->NumQsts.All;
NumQst++)
@ -4076,7 +4075,7 @@ void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
Tst_MAX_BYTES_INDEXES_ONE_QST);
/* 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
{
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 **********************/
/*****************************************************************************/
void Mch_ComputeScore (struct TstPrn_Print *Print)
void Mch_ComputeScore (struct MchPrn_Print *Print)
{
unsigned NumQst;
struct Tst_Question Question;

View File

@ -27,6 +27,7 @@
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_match_print.h"
#include "swad_scope.h"
#include "swad_test.h"
@ -145,10 +146,9 @@ void Mch_GetQstAnsFromDB (long MchCod,long UsrCod,unsigned QstInd,
struct Mch_UsrAnswer *UsrAnswer);
void Mch_ReceiveQuestionAnswer (void);
void Mch_GetMatchQuestionsFromDB (long MchCod,long UsrCod,
struct TstPrn_Print *Print);
void Mch_GetMatchQuestionsFromDB (struct MchPrn_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_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 ****************************/
/*****************************************************************************/
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);
@ -104,46 +106,63 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
long GamCod, // <= 0 ==> any
const char *GamesSelectedCommas);
static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
unsigned NumTotalQsts,
unsigned NumTotalQstsNotBlank,
double TotalScoreOfAllResults,
struct MchPrn_NumQuestions *NumTotalQsts,
double TotalScore,
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,
const struct Mch_Match *Match,
long UsrCod,
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 ************/
/*****************************************************************************/
void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod)
{
struct TstPrn_Print Print;
struct MchPrn_Print Print;
/***** Compute my match result *****/
TstPrn_ResetPrint (&Print);
Mch_GetMatchQuestionsFromDB (MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,&Print);
MchPrn_ResetPrint (&Print);
Print.MchCod = MchCod;
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
Mch_GetMatchQuestionsFromDB (&Print);
Mch_ComputeScore (&Print);
/***** Update my match result in database *****/
MchRes_UpdateMyMatchResult (MchCod,&Print);
MchRes_UpdateMyMatchResult (&Print);
}
/*****************************************************************************/
/******************** 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
if (DB_QueryCOUNT ("can not get if match result exists",
"SELECT COUNT(*) FROM mch_results"
" WHERE MchCod=%ld AND UsrCod=%ld",
MchCod,Gbl.Usrs.Me.UsrDat.UsrCod)) // Match print exists
Print->MchCod,Print->UsrCod)) // Match print exists
/* Update result */
DB_QueryUPDATE ("can not update match result",
"UPDATE mch_results"
@ -155,8 +174,8 @@ static void MchRes_UpdateMyMatchResult (long MchCod,const struct TstPrn_Print *P
Print->NumQsts.All,
Print->NumQsts.NotBlank,
Print->Score,
MchCod,Gbl.Usrs.Me.UsrDat.UsrCod);
else // Match print doesn't exist
Print->MchCod,Print->UsrCod);
else // Match print doesn't exist
/* Create result */
DB_QueryINSERT ("can not create match result",
"INSERT mch_results "
@ -169,7 +188,7 @@ static void MchRes_UpdateMyMatchResult (long MchCod,const struct TstPrn_Print *P
"%u," // NumQsts
"%u," // NumQstsNotBlank
"'%.15lg')", // Score
MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,
Print->MchCod,Print->UsrCod,
Print->NumQsts.All,
Print->NumQsts.NotBlank,
Print->Score);
@ -612,7 +631,7 @@ static void MchRes_ShowResultsBegin (struct Gam_Games *Games,
/***** Begin box *****/
HTM_SECTION_Begin (MchRes_RESULTS_BOX_ID);
Box_BoxBegin ("100%",Title,
Box_BoxBegin (NULL,Title,
NULL,NULL,
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_START_END_TIME[Dat_NUM_START_END_TIME];
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_Average_BR_score_BR_per_question;
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_TH (1,2,"CT",Txt_User[MeOrOther == Usr_ME ? Gbl.Usrs.Me.UsrDat.Sex :
Usr_SEX_UNKNOWN]);
HTM_TH (1,1,"LT",Txt_START_END_TIME[Dat_START_TIME]);
HTM_TH (1,1,"LT",Txt_START_END_TIME[Dat_END_TIME ]);
HTM_TH (1,1,"LT",Txt_Match);
HTM_TH (1,1,"RT",Txt_Questions);
HTM_TH (1,1,"RT",Txt_ANSWERS_non_blank);
HTM_TH (1,1,"RT",Txt_Score);
HTM_TH (1,1,"RT",Txt_Average_BR_score_BR_per_question);
HTM_TH (1,1,"RT",Txt_Grade);
HTM_TH_Empty (1);
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_END_TIME ]);
HTM_TH (3,1,"LT LINE_BOTTOM",Txt_Match);
HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Questions);
HTM_TH (1,2,"CT LINE_LEFT",Txt_Answers);
HTM_TH (1,2,"CT LINE_LEFT",Txt_Score);
HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Grade);
HTM_TH (3,1,"LINE_BOTTOM LINE_LEFT",NULL);
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 ();
}
@ -815,22 +857,22 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
unsigned NumResults;
unsigned NumResult;
static unsigned UniqueId = 0;
Dat_StartEndTime_t StartEndTime;
char *Id;
struct MchPrn_Print Print;
unsigned NumQstsBlank;
struct Mch_Match Match;
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 TotalGrade = 0.0;
time_t TimeUTC[Dat_NUM_START_END_TIME];
struct MchPrn_NumQuestions NumTotalQsts;
double TotalScore;
double TotalGrade;
/***** Reset match *****/
Mch_ResetMatch (&Match);
/***** Reset total number of questions and total score *****/
NumTotalQsts.All =
NumTotalQsts.NotBlank = 0;
TotalScore = 0.0;
TotalGrade = 0.0;
/***** Set user *****/
UsrDat = (MeOrOther == Usr_ME) ? &Gbl.Usrs.Me.UsrDat :
@ -893,12 +935,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/***** Make database query *****/
NumResults =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get matches results",
"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]
"SELECT mch_results.MchCod" // row[0]
" FROM mch_results,mch_matches,gam_games"
" WHERE mch_results.UsrCod=%ld"
"%s" // Match subquery
@ -931,11 +968,16 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
row = mysql_fetch_row (mysql_res);
/* 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.");
Mch_GetDataOfMatchByCod (&Match);
/* Get match result data */
Print.UsrCod = UsrDat->UsrCod;
MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
/* Get data of match and game */
Match.MchCod = Print.MchCod;
Mch_GetDataOfMatchByCod (&Match);
Game.GamCod = Match.GamCod;
Gam_GetDataOfGameByCod (&Game);
@ -946,18 +988,17 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
if (NumResult)
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;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++)
{
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[1 + StartEndTime]);
UniqueId++;
if (asprintf (&Id,"mch_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"",
Id,Gbl.RowEvenOdd);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime],
Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
true,true,false,0x7);
HTM_TD_End ();
@ -969,51 +1010,56 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
HTM_Txt (Match.Title);
HTM_TD_End ();
/* Accumulate questions and score */
if (ICanView.Score)
{
/* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&NumQstsInThisResult) != 1)
NumQstsInThisResult = 0;
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
NumTotalQsts.All += Print.NumQsts.All;
NumTotalQsts.NotBlank += Print.NumQsts.NotBlank;
TotalScore += Print.Score;
}
/* 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)
HTM_Unsigned (NumQstsInThisResult);
HTM_Unsigned (Print.NumQsts.All);
else
Ico_PutIconNotVisible ();
HTM_TD_End ();
/* Write number of questions not blank */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
/* Write number of non-blank answers */
HTM_TD_Begin ("class=\"DAT RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
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
Ico_PutIconNotVisible ();
HTM_TD_End ();
/* 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)
{
HTM_Double2Decimals (ScoreInThisResult);
HTM_Double2Decimals (Print.Score);
HTM_Txt ("/");
HTM_Unsigned (NumQstsInThisResult);
HTM_Unsigned (Print.NumQsts.All);
}
else
Ico_PutIconNotVisible ();
@ -1022,18 +1068,18 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Write average score per question */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanView.Score)
HTM_Double2Decimals (NumQstsInThisResult ? ScoreInThisResult /
(double) NumQstsInThisResult :
0.0);
HTM_Double2Decimals (Print.NumQsts.All ? Print.Score /
(double) Print.NumQsts.All :
0.0);
else
Ico_PutIconNotVisible ();
HTM_TD_End ();
/* 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)
{
Grade = TstPrn_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,Game.MaxGrade);
Grade = TstPrn_ComputeGrade (Print.NumQsts.All,Print.Score,Game.MaxGrade);
TstPrn_ShowGrade (Grade,Game.MaxGrade);
TotalGrade += Grade;
}
@ -1042,7 +1088,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
HTM_TD_End ();
/* 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)
{
Games->GamCod = Match.GamCod;
@ -1071,13 +1117,36 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/***** Write totals for this user *****/
MchRes_ShowMchResultsSummaryRow (NumResults,
NumTotalQsts,NumTotalQstsNotBlank,
TotalScoreOfAllResults,
&NumTotalQsts,
TotalScore,
TotalGrade);
}
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 ();
}
@ -1092,9 +1161,8 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/*****************************************************************************/
static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
unsigned NumTotalQsts,
unsigned NumTotalQstsNotBlank,
double TotalScoreOfAllResults,
struct MchPrn_NumQuestions *NumTotalQsts,
double TotalScore,
double TotalGrade)
{
extern const char *Txt_Matches;
@ -1103,44 +1171,50 @@ static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
HTM_TR_Begin (NULL);
/***** 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_Unsigned (NumResults);
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts);
HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End ();
/***** Write total number of questions not blank *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
/***** Write total number of non-blank answers *****/
HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
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 ();
/***** Write total score *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (TotalScoreOfAllResults);
HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (TotalScore);
HTM_Txt ("/");
HTM_Unsigned (NumTotalQsts);
HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End ();
/***** Write average score per question *****/
HTM_TD_Begin ("class=\"DAT_N LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (NumTotalQsts ? TotalScoreOfAllResults /
(double) NumTotalQsts :
0.0);
HTM_TD_Begin ("class=\"DAT_N RM LINE_TOP LINE_BOTTOM COLOR%u\"",Gbl.RowEvenOdd);
HTM_Double2Decimals (NumTotalQsts->All ? TotalScore /
(double) NumTotalQsts->All :
0.0);
HTM_TD_End ();
/***** 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_TD_End ();
/***** 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 ();
/***** End row *****/
@ -1169,7 +1243,7 @@ void MchRes_ShowOneMchResult (void)
struct UsrData *UsrDat;
Dat_StartEndTime_t StartEndTime;
char *Id;
struct TstPrn_Print Print;
struct MchPrn_Print Print;
bool ShowPhoto;
char PhotoURL[PATH_MAX + 1];
struct MchRes_ICanView ICanView;
@ -1200,8 +1274,9 @@ void MchRes_ShowOneMchResult (void)
}
/***** Get match result data *****/
TstPrn_ResetPrint (&Print);
MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Print);
Print.MchCod = Match.MchCod;
Print.UsrCod = UsrDat->UsrCod;
MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
/***** Check if I can view this match result and score *****/
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
{
/***** Get questions and user's answers of the match result from database *****/
Mch_GetMatchQuestionsFromDB (Match.MchCod,UsrDat->UsrCod,&Print);
Mch_GetMatchQuestionsFromDB (&Print);
/***** Begin box *****/
Box_BoxBegin (NULL,Match.Title,
@ -1358,7 +1433,11 @@ void MchRes_ShowOneMchResult (void)
HTM_TR_End ();
/***** Write answers and solutions *****/
TstPrn_ShowPrintAnswers (UsrDat,&Print,Game.Visibility);
TstPrn_ShowPrintAnswers (UsrDat,
Print.NumQsts.All,
Print.PrintedQuestions,
Print.TimeUTC,
Game.Visibility);
/***** End table *****/
HTM_TABLE_End ();
@ -1374,8 +1453,7 @@ void MchRes_ShowOneMchResult (void)
/************* Get data of a match result using its match code ***************/
/*****************************************************************************/
static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
struct TstPrn_Print *Print)
static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -1395,7 +1473,7 @@ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
" AND mch_results.MchCod=mch_matches.MchCod"
" AND mch_matches.GamCod=gam_games.GamCod"
" AND gam_games.CrsCod=%ld", // Extra check
MchCod,UsrCod,
Print->MchCod,Print->UsrCod,
Gbl.Hierarchy.Crs.CrsCod) == 1)
{
row = mysql_fetch_row (mysql_res);
@ -1421,11 +1499,7 @@ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
Str_SetDecimalPointToLocal (); // Return to local system
}
else
{
Print->NumQsts.All =
Print->NumQsts.NotBlank = 0;
Print->Score = 0.0;
}
MchPrn_ResetPrint (Print);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);

View File

@ -27,8 +27,6 @@
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_test_print.h"
/*****************************************************************************/
/************************** 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_WriteQstAndAnsExam (struct UsrData *UsrDat,
struct TstPrn_Print *Print,
struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST],
unsigned NumQst,
time_t TimeUTC[Dat_NUM_START_END_TIME],
struct Tst_Question *Question,
bool QuestionExists,
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_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_ShowPrintsSummaryRow (bool ItsMe,
unsigned NumPrints,
@ -184,7 +185,7 @@ static void TstRes_CheckIfICanSeePrintResult (const struct TstPrn_Print *Print,
static void TstPrn_ShowTagsPresentInAPrint (long ResCod);
/*****************************************************************************/
/******************************** Reset exam *********************************/
/***************************** Reset test print ******************************/
/*****************************************************************************/
void TstPrn_ResetPrint (struct TstPrn_Print *Print)
@ -616,8 +617,10 @@ void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
QuestionExists = Tst_GetQstDataFromDB (&Question);
/***** Write question and answers *****/
TstPrn_WriteQstAndAnsExam (&Gbl.Usrs.Me.UsrDat,Print,
NumQst,&Question,QuestionExists,
TstPrn_WriteQstAndAnsExam (&Gbl.Usrs.Me.UsrDat,
Print->PrintedQuestions,NumQst,
Print->TimeUTC,
&Question,QuestionExists,
TstCfg_GetConfigVisibility ());
/***** Store test exam question in database *****/
@ -645,8 +648,9 @@ void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
/*****************************************************************************/
static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
struct TstPrn_Print *Print,
struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST],
unsigned NumQst,
time_t TimeUTC[Dat_NUM_START_END_TIME],
struct Tst_Question *Question,
bool QuestionExists,
unsigned Visibility)
@ -688,7 +692,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/***** If this question has been edited later than test time
==> don't show question ****/
if (QuestionExists)
QuestionUneditedAfterExam = (Question->EditTime < Print->TimeUTC[Dat_START_TIME]);
QuestionUneditedAfterExam = (Question->EditTime < TimeUTC[Dat_START_TIME]);
else
QuestionUneditedAfterExam = false;
@ -718,8 +722,8 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
"TEST_MED_SHOW");
/* Answers */
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,&Print->PrintedQuestions[NumQst],Question,
TstPrn_ComputeAnswerScore (&PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,&PrintedQuestions[NumQst],Question,
ICanView,"TEST_TXT","TEST_TXT_LIGHT");
}
else
@ -734,11 +738,11 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
HTM_DIV_Begin ("class=\"DAT_SMALL LM\"");
HTM_TxtColonNBSP (Txt_Score);
HTM_SPAN_Begin ("class=\"%s\"",
Print->PrintedQuestions[NumQst].StrAnswers[0] ?
(Print->PrintedQuestions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect
"ANS_BAD") : // Wrong
"ANS_0"); // Blank answer
HTM_Double2Decimals (Print->PrintedQuestions[NumQst].Score);
PrintedQuestions[NumQst].StrAnswers[0] ?
(PrintedQuestions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect
"ANS_BAD") :// Wrong
"ANS_0"); // Blank answer
HTM_Double2Decimals (PrintedQuestions[NumQst].Score);
HTM_SPAN_End ();
HTM_DIV_End ();
}
@ -1926,7 +1930,7 @@ void TstPrn_ShowMyPrints (void)
Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,2);
/***** Header of the table with the list of users *****/
TstPrn_ShowHeaderPrints ();
TstPrn_ShowHeaderPrints (Usr_ME);
/***** List my test exams *****/
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);
/***** Header of the table with the list of users *****/
TstPrn_ShowHeaderPrints ();
TstPrn_ShowHeaderPrints (Usr_OTHER);
/***** List the test exams of the selected users *****/
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 ***********************/
/*****************************************************************************/
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_START_END_TIME[Dat_NUM_START_END_TIME];
@ -2008,7 +2012,8 @@ static void TstPrn_ShowHeaderPrints (void)
/***** First row *****/
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_END_TIME ]);
HTM_TH (3,1,"RT LINE_BOTTOM LINE_LEFT",Txt_Questions);
@ -2032,8 +2037,8 @@ static void TstPrn_ShowHeaderPrints (void)
/***** 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","{-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");
@ -2063,9 +2068,6 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
struct TstRes_ICanView ICanView;
char *ClassDat;
/***** Reset print *****/
TstPrn_ResetPrint (&Print);
/***** Reset total number of questions and total score *****/
NumTotalQsts.All =
NumTotalQsts.NotBlank = 0;
@ -2104,7 +2106,6 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
row = mysql_fetch_row (mysql_res);
/* Get print code (row[0]) */
TstPrn_ResetPrint (&Print);
if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of test exam.");
@ -2145,17 +2146,15 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
}
/* 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)
{
HTM_Unsigned (Print.NumQsts.All);
}
else
Ico_PutIconNotVisible ();
HTM_TD_End ();
/* 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 (Print.NumQsts.NotBlank)
@ -2182,7 +2181,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
HTM_TD_End ();
/* 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)
{
HTM_Double2Decimals (Print.Score);
@ -2204,7 +2203,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
HTM_TD_End ();
/* 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)
TstPrn_ComputeAndShowGrade (Print.NumQsts.All,Print.Score,Tst_SCORE_MAX);
else
@ -2212,7 +2211,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
HTM_TD_End ();
/* 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)
{
Frm_StartForm (Gbl.Action.Act == ActSeeMyTstResCrs ? ActSeeOneTstResMe :
@ -2326,31 +2325,31 @@ static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
HTM_TR_Begin (NULL);
/***** 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_Unsigned (NumPrints);
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->All);
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->NotBlank);
HTM_TD_End ();
/***** 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)
HTM_Unsigned (NumTotalQsts->All - NumTotalQsts->NotBlank);
HTM_TD_End ();
/***** 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)
{
HTM_Double2Decimals (TotalScore);
@ -2360,14 +2359,14 @@ static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
HTM_TD_End ();
/***** 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)
HTM_Double2Decimals (NumTotalQsts->All ? TotalScore / (double) NumTotalQsts->All :
0.0);
HTM_TD_End ();
/***** 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)
TstPrn_ComputeAndShowGrade (NumTotalQsts->All,TotalScore,Tst_SCORE_MAX);
HTM_TD_End ();
@ -2568,7 +2567,10 @@ void TstPrn_ShowOnePrint (void)
HTM_TR_End ();
/***** 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 ());
/***** End table *****/
@ -2659,7 +2661,9 @@ static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
/*****************************************************************************/
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 NumQst;
@ -2667,22 +2671,24 @@ void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
bool QuestionExists;
for (NumQst = 0;
NumQst < Print->NumQsts.All;
NumQst < NumQsts;
NumQst++)
{
Gbl.RowEvenOdd = NumQst % 2;
/***** Create test question *****/
Tst_QstConstructor (&Question);
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod;
Question.QstCod = PrintedQuestions[NumQst].QstCod;
/***** Get question data *****/
QuestionExists = Tst_GetQstDataFromDB (&Question);
/***** Write questions and answers *****/
TstPrn_WriteQstAndAnsExam (UsrDat,Print,
NumQst,&Question,QuestionExists,
Visibility);
TstPrn_WriteQstAndAnsExam (UsrDat,
PrintedQuestions,NumQst,
TimeUTC,
&Question,QuestionExists,
Visibility);
/***** Destroy test question *****/
Tst_QstDestructor (&Question);

View File

@ -146,7 +146,9 @@ long TstPrn_GetParamPrnCod (void);
void TstPrn_ShowOnePrint (void);
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);
void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print);