Version19.231

This commit is contained in:
acanas 2020-05-16 02:04:36 +02:00
parent e5187b7994
commit 4ba50fa2b3
15 changed files with 242 additions and 322 deletions

View File

@ -699,7 +699,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActSeeAllExaEvtResEvt] = {1874,-1,TabUnk,ActSeeAllExa ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaRes_ShowAllExaResultsInEvt ,NULL},
[ActSeeOneExaEvtResOth] = {1875,-1,TabUnk,ActSeeAllExa ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaRes_ShowOneExaResult ,NULL},
[ActChgVisResExaEvtUsr] = {1876,-1,TabUnk,ActSeeAllExa ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaEvt_ToggleVisibilResultsEvtUsr,NULL},
[ActChgVisResExaEvtUsr] = {1876,-1,TabUnk,ActSeeAllExa ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaEvt_ToggleVisResultsEvtUsr ,NULL},
[ActFrmNewExa ] = {1877,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_RequestCreatOrEditExam ,NULL},
[ActEdiOneExa ] = {1878,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_RequestCreatOrEditExam ,NULL},
@ -740,7 +740,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActPlyPauMch ] = {1789,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_PlayPauseMatch ,NULL},
[ActFwdMch ] = {1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ForwardMatch ,NULL},
[ActChgNumColMch ] = {1802,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ChangeNumColsMch ,NULL},
[ActChgVisResMchQst ] = {1794,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ToggleVisibilResultsMchQst ,NULL},
[ActChgVisResMchQst ] = {1794,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ToggleVisResultsMchQst ,NULL},
[ActMchCntDwn ] = {1814,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Mch_GetMatchBeingPlayed ,Mch_StartCountdown ,NULL},
[ActRefMchTch ] = {1788,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Mch_GetMatchBeingPlayed ,Mch_RefreshMatchTch ,NULL},
@ -761,7 +761,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActSeeAllMchResMch ] = {1813,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,MchRes_ShowAllMchResultsInMch ,NULL},
[ActSeeOneMchResOth ] = {1800,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,MchRes_ShowOneMchResult ,NULL},
[ActChgVisResMchUsr ] = {1801,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mch_ToggleVisibilResultsMchUsr ,NULL},
[ActChgVisResMchUsr ] = {1801,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mch_ToggleVisResultsMchUsr ,NULL},
[ActFrmNewGam ] = {1652,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestCreatOrEditGame ,NULL},
[ActEdiOneGam ] = {1653,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestCreatOrEditGame ,NULL},

View File

@ -548,10 +548,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 19.230.3 (2020-05-15)"
#define Log_PLATFORM_VERSION "SWAD 19.231 (2020-05-16)"
#define CSS_FILE "swad19.230.1.css"
#define JS_FILE "swad19.230.3.js"
/*
Version 19.231: May 16, 2020 Fixed bugs and code refactoring in exam results. (300956 lines)
Version 19.230.3: May 15, 2020 Update maths in exam prints when user answers. (301037 lines)
Version 19.230.2: May 15, 2020 Changes in layout of exam prints.
Changes in edition of sets of questions. (301026 lines)

View File

@ -2062,35 +2062,6 @@ double Exa_GetNumQstsPerCrsExam (Hie_Level_t Scope)
return NumQstsPerExam;
}
/*****************************************************************************/
/************************* Show test tags in an exam **************************/
/*****************************************************************************/
void Exa_ShowTstTagsPresentInAnExam (long ExaCod)
{
MYSQL_RES *mysql_res;
unsigned long NumTags;
/***** Get all tags of questions in this exam *****/
NumTags = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get tags"
" present in an event result",
"SELECT tst_tags.TagTxt" // row[0]
" FROM"
" (SELECT DISTINCT(tst_question_tags.TagCod)"
" FROM tst_question_tags,exa_set_questions"
" WHERE exa_set_questions.ExaCod=%ld"
" AND exa_set_questions.QstCod=tst_question_tags.QstCod)"
" AS TagsCods,tst_tags"
" WHERE TagsCods.TagCod=tst_tags.TagCod"
" ORDER BY tst_tags.TagTxt",
ExaCod);
Tst_ShowTagList (NumTags,mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/*************** Get maximum score of an exam from database *******************/
/*****************************************************************************/

View File

@ -105,8 +105,6 @@ unsigned Exa_GetNumCoursesWithExams (Hie_Level_t Scope);
unsigned Exa_GetNumExams (Hie_Level_t Scope);
double Exa_GetNumQstsPerCrsExam (Hie_Level_t Scope);
void Exa_ShowTstTagsPresentInAnExam (long ExaCod);
void Exa_GetScoreRange (long ExaCod,double *MinScore,double *MaxScore);
#endif

View File

@ -417,7 +417,7 @@ static void ExaEvt_ListOneOrMoreEvents (struct Exa_Exams *Exams,
/***** Get exam event data from row *****/
ExaEvt_GetEventDataFromRow (mysql_res,&Event);
if (ExaEvt_CheckIfICanListThisEventBasedOnGrps (&Event))
if (ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event.EvtCod))
{
/***** Build anchor string *****/
if (asprintf (&Anchor,"evt_%ld_%ld",Exam->ExaCod,Event.EvtCod) < 0)
@ -804,7 +804,7 @@ static void ExaEvt_ListOneOrMoreEventsResultTch (struct Exa_Exams *Exams,
/****************** Toggle visibility of exam event results ******************/
/*****************************************************************************/
void ExaEvt_ToggleVisibilResultsEvtUsr (void)
void ExaEvt_ToggleVisResultsEvtUsr (void)
{
struct Exa_Exams Exams;
struct Exa_Exam Exam;
@ -1667,10 +1667,10 @@ bool ExaEvt_CheckIfICanAnswerThisEvent (const struct ExaEvt_Event *Event)
if (Event->Hidden || !Event->Open)
return false;
return ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event);
return ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event->EvtCod);
}
bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (const struct ExaEvt_Event *Event)
bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (long EvtCod)
{
switch (Gbl.Usrs.Me.Role.Logged)
{
@ -1689,7 +1689,7 @@ bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (const struct ExaEvt_Event *Even
" FROM exa_groups,crs_grp_usr"
" WHERE crs_grp_usr.UsrCod=%ld"
" AND exa_groups.GrpCod=crs_grp_usr.GrpCod))",
Event->EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0);
EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0);
break;
case Rol_NET:
case Rol_TCH:

View File

@ -57,7 +57,7 @@ void ExaEvt_ListEvents (struct Exa_Exams *Exams,
void ExaEvt_GetDataOfEventByCod (struct ExaEvt_Event *Event);
bool ExaEvt_CheckIfEventIsVisibleAndOpen (long EvtCod);
void ExaEvt_ToggleVisibilResultsEvtUsr (void);
void ExaEvt_ToggleVisResultsEvtUsr (void);
void ExaEvt_RequestRemoveEvent (void);
void ExaEvt_RemoveEvent (void);
@ -86,7 +86,7 @@ unsigned ExaEvt_GetNumEventsInExam (long ExaCod);
unsigned ExaEvt_GetNumOpenEventsInExam (long ExaCod);
bool ExaEvt_CheckIfICanAnswerThisEvent (const struct ExaEvt_Event *Event);
bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (const struct ExaEvt_Event *Event);
bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (long EvtCod);
void ExaEvt_GetQstAnsFromDB (long EvtCod,long UsrCod,unsigned QstInd,
struct ExaEvt_UsrAnswer *UsrAnswer);

View File

@ -53,31 +53,10 @@ extern struct Globals Gbl;
/***************************** Private constants *****************************/
/*****************************************************************************/
#define ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT 100 // Absolute maximum number of questions in an exam print
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
struct ExaPrn_Print
{
long PrnCod; // Exam print code
// long ExaCod; // Exam code
long EvtCod; // Event code associated to this print
long UsrCod; // User who answered the exam print
time_t TimeUTC[Dat_NUM_START_END_TIME];
unsigned NumQsts; // Number of questions
unsigned NumQstsNotBlank; // Number of questions not blank
bool Sent; // This exam print has been sent or not?
// "Sent" means that user has clicked "Send" button after finishing
double Score; // Total score of the exam print
struct TstPrn_PrintedQuestion PrintedQuestions[ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT];
};
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
@ -86,10 +65,8 @@ struct ExaPrn_Print
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print);
static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print);
static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print);
static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print,long ExaCod);
static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print,
struct ExaSet_Set *Set,
@ -98,8 +75,6 @@ static void ExaPrn_GenerateChoiceIndexes (struct TstPrn_PrintedQuestion *Printed
bool Shuffle);
static void ExaPrn_CreatePrintInDB (struct ExaPrn_Print *Print);
static void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print);
static void ExaPrn_ShowExamPrintToFillIt (const char *Title,
struct ExaPrn_Print *Print);
static void ExaPrn_ShowTableWithQstsToFill (struct ExaPrn_Print *Print);
@ -123,7 +98,6 @@ static void ExaPrn_WriteTextAnsToFill (const struct ExaPrn_Print *Print,
static unsigned ExaPrn_GetAnswerFromForm (struct ExaPrn_Print *Print);
// static void ExaPrn_PutParamNumQst (unsigned NumQst);
static unsigned ExaPrn_GetParamQstInd (void);
static void ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (struct ExaPrn_Print *Print);
@ -164,7 +138,7 @@ static void ExaPrn_UpdatePrintInDB (const struct ExaPrn_Print *Print);
/**************************** Reset exam print *******************************/
/*****************************************************************************/
static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print)
void ExaPrn_ResetPrint (struct ExaPrn_Print *Print)
{
Print->EvtCod = -1L;
Print->UsrCod = -1L;
@ -212,7 +186,7 @@ void ExaPrn_ShowExamPrint (void)
ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print);
if (Print.PrnCod > 0) // Print exists and I can access to it
/***** Get questions and answers from database *****/
/***** Get questions and user's answers of exam print from database *****/
ExaPrn_GetPrintQuestionsFromDB (&Print);
else
{
@ -238,7 +212,7 @@ void ExaPrn_ShowExamPrint (void)
/********* Get data of an exam print using event code and user code **********/
/*****************************************************************************/
static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print)
void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -528,7 +502,7 @@ static void ExaPrn_CreatePrintInDB (struct ExaPrn_Print *Print)
/************* Get the questions of an exam print from database **************/
/*****************************************************************************/
static void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print)
void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -953,7 +927,7 @@ void ExaPrn_ReceivePrintAnswer (void)
if (Print.PrnCod <= 0)
Lay_WrongExamExit ();
/***** Get questions and answers from database *****/
/***** Get questions and user's answers of exam print from database *****/
ExaPrn_GetPrintQuestionsFromDB (&Print);
/***** Get answers from form to assess a test *****/

View File

@ -31,12 +31,34 @@
/************************* Public types and constants ************************/
/*****************************************************************************/
#define ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT 100 // Absolute maximum number of questions in an exam print
struct ExaPrn_Print
{
long PrnCod; // Exam print code
long EvtCod; // Event code associated to this print
long UsrCod; // User who answered the exam print
time_t TimeUTC[Dat_NUM_START_END_TIME];
unsigned NumQsts; // Number of questions
unsigned NumQstsNotBlank; // Number of questions not blank
bool Sent; // This exam print has been sent or not?
// "Sent" means that user has clicked "Send" button after finishing
double Score; // Total score of the exam print
struct TstPrn_PrintedQuestion PrintedQuestions[ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT];
};
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
void ExaPrn_ResetPrint (struct ExaPrn_Print *Print);
void ExaPrn_ShowExamPrint (void);
void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print);
void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print);
void ExaPrn_ReceivePrintAnswer (void);
void ExaPrn_ComputeAnswerScore (struct TstPrn_PrintedQuestion *PrintedQuestion,

View File

@ -37,13 +37,16 @@
#include "swad_date.h"
#include "swad_exam.h"
#include "swad_exam_event.h"
#include "swad_exam_print.h"
#include "swad_exam_result.h"
#include "swad_exam_set.h"
#include "swad_exam_type.h"
#include "swad_form.h"
#include "swad_global.h"
#include "swad_HTML.h"
#include "swad_ID.h"
#include "swad_photo.h"
#include "swad_test_print.h"
#include "swad_test_visibility.h"
#include "swad_user.h"
@ -102,14 +105,21 @@ static void ExaRes_ShowEvtResultsSummaryRow (unsigned NumResults,
unsigned NumTotalQstsNotBlank,
double TotalScoreOfAllResults,
double TotalGrade);
static void ExaRes_GetEventResultDataByEvtCod (long EvtCod,long UsrCod,
struct TstPrn_Print *Print);
static bool ExaRes_CheckIfICanSeeEventResult (struct ExaEvt_Event *Event,long UsrCod);
static bool ExaRes_CheckIfICanSeePrintResult (struct ExaEvt_Event *Event,long UsrCod);
static bool ExaRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility);
static void ExaRes_ShowExamAnswers (struct UsrData *UsrDat,
struct ExaPrn_Print *Print,
unsigned Visibility);
static void ExaRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
struct ExaPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility);
/*****************************************************************************/
/*************************** Show my events results *************************/
/*************************** Show my events results **************************/
/*****************************************************************************/
void ExaRes_ShowMyExaResultsInCrs (void)
@ -865,7 +875,7 @@ static void ExaRes_ShowEvtResults (struct Exa_Exams *Exams,
Visibility = TstVis_GetVisibilityFromStr (row[7]);
/* Show event result? */
ICanViewResult = ExaRes_CheckIfICanSeeEventResult (&Event,UsrDat->UsrCod);
ICanViewResult = ExaRes_CheckIfICanSeePrintResult (&Event,UsrDat->UsrCod);
ICanViewScore = ExaRes_CheckIfICanViewScore (ICanViewResult,Visibility);
if (NumResult)
@ -1084,7 +1094,6 @@ void ExaRes_ShowOneExaResult (void)
extern const char *Txt_non_blank_QUESTIONS;
extern const char *Txt_Score;
extern const char *Txt_Grade;
extern const char *Txt_Tags;
struct Exa_Exams Exams;
struct Exa_Exam Exam;
struct ExaEvt_Event Event;
@ -1092,7 +1101,7 @@ void ExaRes_ShowOneExaResult (void)
struct UsrData *UsrDat;
Dat_StartEndTime_t StartEndTime;
char *Id;
struct TstPrn_Print Print;
struct ExaPrn_Print Print;
bool ShowPhoto;
char PhotoURL[PATH_MAX + 1];
bool ICanViewResult;
@ -1122,14 +1131,16 @@ void ExaRes_ShowOneExaResult (void)
}
/***** Get event result data *****/
TstPrn_ResetPrint (&Print);
ExaRes_GetEventResultDataByEvtCod (Event.EvtCod,UsrDat->UsrCod,&Print);
ExaPrn_ResetPrint (&Print);
Print.EvtCod = Event.EvtCod;
Print.UsrCod = UsrDat->UsrCod;
ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print);
/***** Check if I can view this event result *****/
/***** Check if I can view this print result *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
ICanViewResult = ExaRes_CheckIfICanSeeEventResult (&Event,UsrDat->UsrCod);
ICanViewResult = ExaRes_CheckIfICanSeePrintResult (&Event,UsrDat->UsrCod);
if (ICanViewResult)
ICanViewScore = TstVis_IsVisibleTotalScore (Exam.Visibility);
else
@ -1152,9 +1163,8 @@ void ExaRes_ShowOneExaResult (void)
if (ICanViewResult) // I am allowed to view this event result
{
/***** Get questions and user's answers of the event result from database *****/
ExaRes_GetExamResultQuestionsFromDB (Event.EvtCod,UsrDat->UsrCod,
&Print);
/***** Get questions and user's answers of exam print from database *****/
ExaPrn_GetPrintQuestionsFromDB (&Print);
/***** Begin box *****/
Box_BoxBegin (NULL,Event.Title,
@ -1269,21 +1279,8 @@ void ExaRes_ShowOneExaResult (void)
HTM_TR_End ();
/* Tags present in this result */
HTM_TR_Begin (NULL);
HTM_TD_Begin ("class=\"DAT_N RT\"");
HTM_TxtF ("%s:",Txt_Tags);
HTM_TD_End ();
HTM_TD_Begin ("class=\"DAT LT\"");
Exa_ShowTstTagsPresentInAnExam (Event.ExaCod);
HTM_TD_End ();
HTM_TR_End ();
/***** Write answers and solutions *****/
TstPrn_ShowExamAnswers (UsrDat,&Print,Exam.Visibility);
ExaRes_ShowExamAnswers (UsrDat,&Print,Exam.Visibility);
/***** End table *****/
HTM_TABLE_End ();
@ -1308,134 +1305,11 @@ void ExaRes_ShowOneExaResult (void)
Lay_NoPermissionExit ();
}
/*****************************************************************************/
/************ Get the questions of a event result from database **************/
/*****************************************************************************/
void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod,
struct TstPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumQst;
long LongNum;
unsigned QstInd;
struct ExaEvt_UsrAnswer UsrAnswer;
/***** Get questions and answers of a event result *****/
Print->NumQsts = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get questions and answers"
" of a event result",
"SELECT exa_set_questions.QstCod," // row[0]
"exa_set_questions.QstInd," // row[1]
"exa_print_questions.Indexes" // row[2]
" FROM exa_events,exa_set_questions,exa_print_questions"
" WHERE exa_events.EvtCod=%ld"
" AND exa_events.EvtCod=exa_print_questions.EvtCod"
" AND exa_set_questions.QstInd=exa_print_questions.QstInd"
" ORDER BY exa_set_questions.QstInd",
EvtCod);
for (NumQst = 0, Print->NumQstsNotBlank = 0;
NumQst < Print->NumQsts;
NumQst++)
{
row = mysql_fetch_row (mysql_res);
/* Get question code (row[0]) */
if ((Print->PrintedQuestions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index (row[1]) */
if ((LongNum = Str_ConvertStrCodToLongCod (row[1])) < 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
QstInd = (unsigned) LongNum;
/* Get indexes for this question (row[2]) */
Str_Copy (Print->PrintedQuestions[NumQst].StrIndexes,row[2],
Tst_MAX_BYTES_INDEXES_ONE_QST);
/* Get answers selected by user for this question */
ExaEvt_GetQstAnsFromDB (EvtCod,UsrCod,QstInd,&UsrAnswer);
if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
{
snprintf (Print->PrintedQuestions[NumQst].StrAnswers,Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
"%d",UsrAnswer.AnsInd);
Print->NumQstsNotBlank++;
}
else // UsrAnswer.AnsInd < 0 ==> no answer selected
Print->PrintedQuestions[NumQst].StrAnswers[0] = '\0'; // Empty answer
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/************* Get data of a event result using its event code ***************/
/*****************************************************************************/
static void ExaRes_GetEventResultDataByEvtCod (long EvtCod,long UsrCod,
struct TstPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
Dat_StartEndTime_t StartEndTime;
/***** Make database query *****/
if (DB_QuerySELECT (&mysql_res,"can not get data"
" of a event result of a user",
"SELECT UNIX_TIMESTAMP(exa_prints.StartTime)," // row[1]
"UNIX_TIMESTAMP(exa_prints.EndTime)," // row[2]
"exa_prints.NumQsts," // row[3]
"exa_prints.NumQstsNotBlank," // row[4]
"exa_prints.Score" // row[5]
" FROM exa_prints,exa_events,exa_exams"
" WHERE exa_prints.EvtCod=%ld"
" AND exa_prints.UsrCod=%ld"
" AND exa_prints.EvtCod=exa_events.EvtCod"
" AND exa_events.ExaCod=exa_exams.ExaCod"
" AND exa_exams.CrsCod=%ld", // Extra check
EvtCod,UsrCod,
Gbl.Hierarchy.Crs.CrsCod) == 1)
{
row = mysql_fetch_row (mysql_res);
/* Get start time (row[0] and row[1] hold UTC date-times) */
for (StartEndTime = (Dat_StartEndTime_t) 0;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++)
Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
/* Get number of questions (row[2]) */
if (sscanf (row[2],"%u",&Print->NumQsts) != 1)
Print->NumQsts = 0;
/* Get number of questions not blank (row[3]) */
if (sscanf (row[3],"%u",&Print->NumQstsNotBlank) != 1)
Print->NumQstsNotBlank = 0;
/* Get score (row[4]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
if (sscanf (row[4],"%lf",&Print->Score) != 1)
Print->Score = 0.0;
Str_SetDecimalPointToLocal (); // Return to local system
}
else
{
Print->NumQsts = 0;
Print->NumQstsNotBlank = 0;
Print->Score = 0.0;
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/********************** Get if I can see event result ************************/
/*****************************************************************************/
static bool ExaRes_CheckIfICanSeeEventResult (struct ExaEvt_Event *Event,long UsrCod)
static bool ExaRes_CheckIfICanSeePrintResult (struct ExaEvt_Event *Event,long UsrCod)
{
bool ItsMe;
@ -1444,7 +1318,7 @@ static bool ExaRes_CheckIfICanSeeEventResult (struct ExaEvt_Event *Event,long Us
case Rol_STD:
ItsMe = Usr_ItsMe (UsrCod);
if (ItsMe && Event->ShowUsrResults)
return ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event);
return ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event->EvtCod);
return false;
case Rol_NET:
case Rol_TCH:
@ -1482,3 +1356,98 @@ static bool ExaRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility
return false;
}
}
/*****************************************************************************/
/************** Show user's and correct answers of a test exam ***************/
/*****************************************************************************/
static void ExaRes_ShowExamAnswers (struct UsrData *UsrDat,
struct ExaPrn_Print *Print,
unsigned Visibility)
{
unsigned NumQst;
struct Tst_Question Question;
for (NumQst = 0;
NumQst < Print->NumQsts;
NumQst++)
{
Gbl.RowEvenOdd = NumQst % 2;
/***** Create test question *****/
Tst_QstConstructor (&Question);
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod;
/***** Get question data *****/
ExaSet_GetQstDataFromDB (&Question);
/***** Write questions and answers *****/
ExaRes_WriteQstAndAnsExam (UsrDat,Print,NumQst,&Question,Visibility);
/***** Destroy test question *****/
Tst_QstDestructor (&Question);
}
}
/*****************************************************************************/
/********** Write a row of a test, with one question and its answer **********/
/*****************************************************************************/
static void ExaRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
struct ExaPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility)
{
extern const char *Txt_Score;
bool IsVisibleQstAndAnsTxt = TstVis_IsVisibleQstAndAnsTxt (Visibility);
/***** Begin row *****/
HTM_TR_Begin (NULL);
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (NumQst + 1);
Tst_WriteAnswerType (Question->Answer.Type);
HTM_TD_End ();
/***** Stem, media and answers *****/
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
/* Stem */
Tst_WriteQstStem (Question->Stem,"TEST_EXA",IsVisibleQstAndAnsTxt);
/* Media */
if (IsVisibleQstAndAnsTxt)
Med_ShowMedia (&Question->Media,
"TEST_MED_SHOW_CONT",
"TEST_MED_SHOW");
/* Answers */
ExaPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,&Print->PrintedQuestions[NumQst],Question,Visibility);
/* Write score retrieved from database */
if (TstVis_IsVisibleEachQstScore (Visibility))
{
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);
HTM_SPAN_End ();
HTM_DIV_End ();
}
/* Question feedback */
if (TstVis_IsVisibleFeedbackTxt (Visibility))
Tst_WriteQstFeedback (Question->Feedback,"TEST_EXA_LIGHT");
HTM_TD_End ();
/***** End row *****/
HTM_TR_End ();
}

View File

@ -50,7 +50,5 @@ void ExaRes_ShowAllExaResultsInExa (void);
void ExaRes_ShowAllExaResultsInEvt (void);
void ExaRes_ShowOneExaResult (void);
void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod,
struct TstPrn_Print *Print);
#endif

View File

@ -885,7 +885,7 @@ static void Mch_ListOneOrMoreMatchesResultTch (struct Gam_Games *Games,
/******************** Toggle visibility of match results *********************/
/*****************************************************************************/
void Mch_ToggleVisibilResultsMchUsr (void)
void Mch_ToggleVisResultsMchUsr (void)
{
struct Gam_Games Games;
struct Gam_Game Game;
@ -1974,7 +1974,7 @@ void Mch_ChangeNumColsMch (void)
/********* Toggle the display of results in a match (by a teacher) ***********/
/*****************************************************************************/
void Mch_ToggleVisibilResultsMchQst (void)
void Mch_ToggleVisResultsMchQst (void)
{
struct Mch_Match Match;

View File

@ -92,7 +92,7 @@ void Mch_ListMatches (struct Gam_Games *Games,
bool PutFormNewMatch);
void Mch_GetDataOfMatchByCod (struct Mch_Match *Match);
void Mch_ToggleVisibilResultsMchUsr (void);
void Mch_ToggleVisResultsMchUsr (void);
void Mch_RequestRemoveMatch (void);
void Mch_RemoveMatch (void);
@ -117,7 +117,7 @@ void Mch_RemoveGroupsOfType (long GrpTypCod);
void Mch_PlayPauseMatch (void);
void Mch_ChangeNumColsMch (void);
void Mch_ToggleVisibilResultsMchQst (void);
void Mch_ToggleVisResultsMchQst (void);
void Mch_BackMatch (void);
void Mch_ForwardMatch (void);

View File

@ -1279,7 +1279,7 @@ void MchRes_ShowOneMchResult (void)
/***** End table *****/
HTM_TABLE_End ();
/***** Write total mark of match result *****/
/***** Write total grade of match result *****/
if (ICanViewScore)
{
HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\"");

View File

@ -92,6 +92,8 @@ static void TstPrn_GetCorrectAndComputeChoAnsScore (struct TstPrn_PrintedQuestio
static void TstPrn_GetCorrectAndComputeTxtAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question);
//-----------------------------------------------------------------------------
static void TstPrn_GetCorrectIntAnswerFromDB (struct Tst_Question *Question);
static void TstPrn_GetCorrectFltAnswerFromDB (struct Tst_Question *Question);
static void TstPrn_GetCorrectTF_AnswerFromDB (struct Tst_Question *Question);
@ -100,36 +102,29 @@ static void TstPrn_GetCorrectTxtAnswerFromDB (struct Tst_Question *Question);
//-----------------------------------------------------------------------------
static void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteIntAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteFloatAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteTFAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteChoiceAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteTextAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteFltAnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteTF_AnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteChoAnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility);
static void TstPrn_WriteTxtAnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility);
//-----------------------------------------------------------------------------
static void TstPrn_WriteHeadUserCorrect (struct UsrData *UsrDat);
static void TstPrn_StoreOneQstOfPrintInDB (const struct TstPrn_Print *Print,
@ -297,7 +292,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/***** Begin row *****/
HTM_TR_Begin (NULL);
/***** Number of question and answer type (row[1]) *****/
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (NumQst + 1);
if (QuestionUneditedAfterExam)
@ -321,7 +316,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/* Answers */
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,Print,NumQst,Question,Visibility);
TstPrn_WriteAnswersExam (UsrDat,&Print->PrintedQuestions[NumQst],Question,Visibility);
}
else
Ale_ShowAlert (Ale_WARNING,Txt_Question_modified);
@ -894,34 +889,26 @@ void TstPrn_ShowGrade (double Grade,double MaxGrade)
/************* Write answers of a question when assessing a test *************/
/*****************************************************************************/
static void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility)
void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility)
{
/***** Write answer depending on type *****/
switch (Question->Answer.Type)
{
case Tst_ANS_INT:
TstPrn_WriteIntAnsExam (UsrDat,Print,NumQst,Question,Visibility);
break;
case Tst_ANS_FLOAT:
TstPrn_WriteFloatAnsExam (UsrDat,Print,NumQst,Question,Visibility);
break;
case Tst_ANS_TRUE_FALSE:
TstPrn_WriteTFAnsExam (UsrDat,Print,NumQst,Question,Visibility);
break;
case Tst_ANS_UNIQUE_CHOICE:
case Tst_ANS_MULTIPLE_CHOICE:
TstPrn_WriteChoiceAnsExam (UsrDat,Print,NumQst,Question,Visibility);
break;
case Tst_ANS_TEXT:
TstPrn_WriteTextAnsExam (UsrDat,Print,NumQst,Question,Visibility);
break;
default:
break;
}
void (*TstPrn_WriteAnsExam[Tst_NUM_ANS_TYPES]) (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility) =
{
[Tst_ANS_INT ] = TstPrn_WriteIntAnsExam,
[Tst_ANS_FLOAT ] = TstPrn_WriteFltAnsExam,
[Tst_ANS_TRUE_FALSE ] = TstPrn_WriteTF_AnsExam,
[Tst_ANS_UNIQUE_CHOICE ] = TstPrn_WriteChoAnsExam,
[Tst_ANS_MULTIPLE_CHOICE] = TstPrn_WriteChoAnsExam,
[Tst_ANS_TEXT ] = TstPrn_WriteTxtAnsExam,
};
/***** Get correct answer and compute answer score depending on type *****/
TstPrn_WriteAnsExam[Question->Answer.Type] (UsrDat,PrintedQuestion,Question,Visibility);
}
/*****************************************************************************/
@ -929,8 +916,7 @@ static void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
/*****************************************************************************/
static void TstPrn_WriteIntAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility)
{
@ -948,9 +934,9 @@ static void TstPrn_WriteIntAnsExam (struct UsrData *UsrDat,
HTM_TR_Begin (NULL);
/***** Write the user answer *****/
if (Print->PrintedQuestions[NumQst].StrAnswers[0]) // If user has answered the question
if (PrintedQuestion->StrAnswers[0]) // If user has answered the question
{
if (sscanf (Print->PrintedQuestions[NumQst].StrAnswers,"%ld",&IntAnswerUsr) == 1)
if (sscanf (PrintedQuestion->StrAnswers,"%ld",&IntAnswerUsr) == 1)
{
HTM_TD_Begin ("class=\"%s CM\"",
TstVis_IsVisibleCorrectAns (Visibility) ?
@ -988,11 +974,10 @@ static void TstPrn_WriteIntAnsExam (struct UsrData *UsrDat,
/******************** Write float answer in an test exam *********************/
/*****************************************************************************/
static void TstPrn_WriteFloatAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question,
unsigned Visibility)
static void TstPrn_WriteFltAnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility)
{
double FloatAnsUsr = 0.0;
@ -1009,9 +994,9 @@ static void TstPrn_WriteFloatAnsExam (struct UsrData *UsrDat,
HTM_TR_Begin (NULL);
/***** Write the user answer *****/
if (Print->PrintedQuestions[NumQst].StrAnswers[0]) // If user has answered the question
if (PrintedQuestion->StrAnswers[0]) // If user has answered the question
{
FloatAnsUsr = Str_GetDoubleFromStr (Print->PrintedQuestions[NumQst].StrAnswers);
FloatAnsUsr = Str_GetDoubleFromStr (PrintedQuestion->StrAnswers);
// A bad formatted floating point answer will interpreted as 0.0
HTM_TD_Begin ("class=\"%s CM\"",
TstVis_IsVisibleCorrectAns (Visibility) ?
@ -1049,11 +1034,10 @@ static void TstPrn_WriteFloatAnsExam (struct UsrData *UsrDat,
/***************** Write false / true answer in a test exam ******************/
/*****************************************************************************/
static void TstPrn_WriteTFAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
const struct Tst_Question *Question,
unsigned Visibility)
static void TstPrn_WriteTF_AnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility)
{
char AnsTFUsr;
@ -1061,7 +1045,7 @@ static void TstPrn_WriteTFAnsExam (struct UsrData *UsrDat,
Tst_CheckIfNumberOfAnswersIsOne (Question);
/***** Get answer true or false *****/
AnsTFUsr = Print->PrintedQuestions[NumQst].StrAnswers[0];
AnsTFUsr = PrintedQuestion->StrAnswers[0];
/***** Header with the title of each column *****/
HTM_TABLE_BeginPadding (2);
@ -1098,11 +1082,10 @@ static void TstPrn_WriteTFAnsExam (struct UsrData *UsrDat,
/********** Write single or multiple choice answer in a test exam ************/
/*****************************************************************************/
static void TstPrn_WriteChoiceAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility)
static void TstPrn_WriteChoAnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility)
{
extern const char *Txt_TST_Answer_given_by_the_user;
extern const char *Txt_TST_Answer_given_by_the_teachers;
@ -1116,10 +1099,10 @@ static void TstPrn_WriteChoiceAnsExam (struct UsrData *UsrDat,
} Ans;
/***** Get indexes for this question from string *****/
TstPrn_GetIndexesFromStr (Print->PrintedQuestions[NumQst].StrIndexes,Indexes);
TstPrn_GetIndexesFromStr (PrintedQuestion->StrIndexes,Indexes);
/***** Get the user's answers for this question from string *****/
TstPrn_GetAnswersFromStr (Print->PrintedQuestions[NumQst].StrAnswers,UsrAnswers);
TstPrn_GetAnswersFromStr (PrintedQuestion->StrAnswers,UsrAnswers);
/***** Begin table *****/
HTM_TABLE_BeginPadding (2);
@ -1227,11 +1210,10 @@ static void TstPrn_WriteChoiceAnsExam (struct UsrData *UsrDat,
/***************** Write text answer when assessing a test *******************/
/*****************************************************************************/
static void TstPrn_WriteTextAnsExam (struct UsrData *UsrDat,
const struct TstPrn_Print *Print,
unsigned NumQst,
struct Tst_Question *Question,
unsigned Visibility)
static void TstPrn_WriteTxtAnsExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility)
{
unsigned NumOpt;
char TextAnsUsr[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1];
@ -1266,10 +1248,10 @@ static void TstPrn_WriteTextAnsExam (struct UsrData *UsrDat,
HTM_TR_Begin (NULL);
/***** Write the user answer *****/
if (Print->PrintedQuestions[NumQst].StrAnswers[0]) // If user has answered the question
if (PrintedQuestion->StrAnswers[0]) // If user has answered the question
{
/* Filter the user answer */
Str_Copy (TextAnsUsr,Print->PrintedQuestions[NumQst].StrAnswers,
Str_Copy (TextAnsUsr,PrintedQuestion->StrAnswers,
Tst_MAX_BYTES_ANSWERS_ONE_QST);
/* In order to compare student answer to stored answer,
@ -1299,7 +1281,7 @@ static void TstPrn_WriteTextAnsExam (struct UsrData *UsrDat,
(Correct ? "ANS_OK" :
"ANS_BAD") :
"ANS_0");
HTM_Txt (Print->PrintedQuestions[NumQst].StrAnswers);
HTM_Txt (PrintedQuestion->StrAnswers);
}
else // If user has omitted the answer
HTM_TD_Begin (NULL);
@ -2102,7 +2084,7 @@ void TstPrn_ShowOneExam (void)
/***** End table *****/
HTM_TABLE_End ();
/***** Write total mark of test *****/
/***** Write total grade of test *****/
if (ICanViewScore)
{
HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\"");

View File

@ -100,6 +100,11 @@ void TstPrn_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade);
double TstPrn_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade);
void TstPrn_ShowGrade (double Grade,double MaxGrade);
void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
const struct Tst_Question *Question,
unsigned Visibility);
void TstPrn_SelUsrsToViewUsrsExams (void);
void TstPrn_SelDatesToSeeMyExams (void);
void TstPrn_ShowMyExams (void);