diff --git a/Makefile b/Makefile index ec0d8e6c..ed1762bd 100644 --- a/Makefile +++ b/Makefile @@ -58,8 +58,8 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \ swad_scope.o swad_search.o swad_session.o swad_setting.o \ swad_statistic.o swad_string.o swad_survey.o swad_syllabus.o \ swad_system_config.o \ - swad_tab.o swad_test.o swad_test_config.o swad_test_exam.o \ - swad_test_import.o swad_test_visibility.o swad_theme.o swad_timeline.o \ + swad_tab.o swad_test.o swad_test_config.o swad_test_import.o \ + swad_test_print.o swad_test_visibility.o swad_theme.o swad_timeline.o \ swad_timetable.o \ swad_user.o \ swad_xml.o \ diff --git a/css/swad19.193.1.css b/css/swad19.217.css similarity index 99% rename from css/swad19.193.1.css rename to css/swad19.217.css index cbe33181..79ae7b10 100644 --- a/css/swad19.193.1.css +++ b/css/swad19.217.css @@ -2654,9 +2654,9 @@ table.CELLS_PAD_10 > tbody > tr > td {padding:10px;} text-align:center; vertical-align:middle; } -.TEST_EXA {color:#202020; font-size:12pt;} +.TEST_EXA {color:#202020; font-size:12pt;} .TEST_EXA_LIGHT {color:#a0a0a0; font-size:12pt;} -.TEST_EDI {color:#202020; font-size:12pt;} +.TEST_EDI {color:#202020; font-size:12pt;} .TEST_EDI_LIGHT {color:#a0a0a0; font-size:12pt;} .TEST_TAG_LIST @@ -2744,6 +2744,21 @@ table.CELLS_PAD_10 > tbody > tr > td {padding:10px;} } /*********************************** Exams ***********************************/ +.EXA_SET_TITLE + { + text-align:left; + vertical-align:top; + color:black; + font-size:16pt; + } +.EXA_SET_NUM_QSTS + { + text-align:right; + vertical-align:top; + color:#404040; + font-size:12pt; + } + .EXA_BG { background-image:url("/swad/icon/bg.jpg"); diff --git a/swad_API.c b/swad_API.c index a99289bf..2faf6a0b 100644 --- a/swad_API.c +++ b/swad_API.c @@ -3955,7 +3955,7 @@ int swad__sendNotice (struct soap *soap, /****************** Return test configuration in a course ********************/ /*****************************************************************************/ -#define TstRes_MAX_BYTES_FEEDBACK_TYPE 32 +#define TstPrn_MAX_BYTES_FEEDBACK_TYPE 32 int swad__getTestConfig (struct soap *soap, char *wsKey,int courseCode, // input @@ -4010,7 +4010,7 @@ int swad__getTestConfig (struct soap *soap, getTestConfigOut->visibility = TstVis_MIN_VISIBILITY; /* TODO: Remove these lines in 2021 */ - getTestConfigOut->feedback = (char *) soap_malloc (soap,TstRes_MAX_BYTES_FEEDBACK_TYPE + 1); + getTestConfigOut->feedback = (char *) soap_malloc (soap,TstPrn_MAX_BYTES_FEEDBACK_TYPE + 1); getTestConfigOut->feedback[0] = '\0'; /***** Get test configuration *****/ @@ -4028,23 +4028,23 @@ int swad__getTestConfig (struct soap *soap, if (!TstVis_IsVisibleTotalScore (TstCfg_GetConfigVisibility ())) Str_Copy (getTestConfigOut->feedback, "nothing", - TstRes_MAX_BYTES_FEEDBACK_TYPE); + TstPrn_MAX_BYTES_FEEDBACK_TYPE); else if (!TstVis_IsVisibleEachQstScore (TstCfg_GetConfigVisibility ())) Str_Copy (getTestConfigOut->feedback, "totalResult", - TstRes_MAX_BYTES_FEEDBACK_TYPE); + TstPrn_MAX_BYTES_FEEDBACK_TYPE); else if (!TstVis_IsVisibleCorrectAns (TstCfg_GetConfigVisibility ())) Str_Copy (getTestConfigOut->feedback, "eachResult", - TstRes_MAX_BYTES_FEEDBACK_TYPE); + TstPrn_MAX_BYTES_FEEDBACK_TYPE); else if (!TstVis_IsVisibleFeedbackTxt (TstCfg_GetConfigVisibility ())) Str_Copy (getTestConfigOut->feedback, "eachGoodBad", - TstRes_MAX_BYTES_FEEDBACK_TYPE); + TstPrn_MAX_BYTES_FEEDBACK_TYPE); else Str_Copy (getTestConfigOut->feedback, "fullFeedback", - TstRes_MAX_BYTES_FEEDBACK_TYPE); + TstPrn_MAX_BYTES_FEEDBACK_TYPE); /***** Get number of tests *****/ if (TstCfg_GetConfigPluggable () == TstCfg_PLUGGABLE_YES && diff --git a/swad_account.c b/swad_account.c index 5dd146e4..20439af5 100644 --- a/swad_account.c +++ b/swad_account.c @@ -50,7 +50,7 @@ #include "swad_profile.h" #include "swad_project.h" #include "swad_report.h" -#include "swad_test_exam.h" +#include "swad_test_print.h" #include "swad_timeline.h" /*****************************************************************************/ @@ -1082,7 +1082,7 @@ void Acc_CompletelyEliminateAccount (struct UsrData *UsrDat, UsrDat->FullName); /***** Remove test results made by user in all courses *****/ - TstRes_RemoveExamsMadeByUsrInAllCrss (UsrDat->UsrCod); + TstPrn_RemoveExamsMadeByUsrInAllCrss (UsrDat->UsrCod); /***** Remove user's notifications *****/ Ntf_RemoveUsrNtfs (UsrDat->UsrCod); diff --git a/swad_action.c b/swad_action.c index bb4b9c8b..a85b31b8 100644 --- a/swad_action.c +++ b/swad_action.c @@ -670,12 +670,12 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActRenTag ] = { 143,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RenameTag ,NULL}, [ActRcvCfgTst ] = { 454,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstCfg_ReceiveConfigTst ,NULL}, - [ActReqSeeMyTstRes ] = {1083,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,TstRes_SelDatesToSeeMyExams ,NULL}, - [ActSeeMyTstRes ] = {1084,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstRes_ShowMyExams ,NULL}, - [ActSeeOneTstResMe ] = {1085,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstRes_ShowOneExam ,NULL}, - [ActReqSeeUsrTstRes ] = {1080,-1,TabUnk,ActReqTst ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,TstRes_SelUsrsToViewUsrsExams ,NULL}, - [ActSeeUsrTstRes ] = {1081,-1,TabUnk,ActReqTst ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstRes_GetUsrsAndShowExams ,NULL}, - [ActSeeOneTstResOth ] = {1082,-1,TabUnk,ActReqTst ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstRes_ShowOneExam ,NULL}, + [ActReqSeeMyTstRes ] = {1083,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,TstPrn_SelDatesToSeeMyExams ,NULL}, + [ActSeeMyTstRes ] = {1084,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstPrn_ShowMyExams ,NULL}, + [ActSeeOneTstResMe ] = {1085,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstPrn_ShowOneExam ,NULL}, + [ActReqSeeUsrTstRes ] = {1080,-1,TabUnk,ActReqTst ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,TstPrn_SelUsrsToViewUsrsExams ,NULL}, + [ActSeeUsrTstRes ] = {1081,-1,TabUnk,ActReqTst ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstPrn_GetUsrsAndShowExams ,NULL}, + [ActSeeOneTstResOth ] = {1082,-1,TabUnk,ActReqTst ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstPrn_ShowOneExam ,NULL}, [ActSeeExa ] = {1849,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_SeeOneExam ,NULL}, diff --git a/swad_changelog.h b/swad_changelog.h index b82d98ff..d6d6304f 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -548,11 +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.216.1 (2020-05-07)" -#define CSS_FILE "swad19.193.1.css" +#define Log_PLATFORM_VERSION "SWAD 19.217 (2020-05-07)" +#define CSS_FILE "swad19.217.css" #define JS_FILE "swad19.193.1.js" /* - Version 19.217: May 07, 2020 Generate and show questions of each set in an exam print. (? lines) + Version 19.217: May 07, 2020 Generate and show questions of each set in an exam print. Not finished. (302124 lines) Version 19.216.1: May 07, 2020 Fixed bug in edition of exam questions, reported by Antonio Cañas Martínez. Changes in some texts. (301957 lines) Version 19.216: May 07, 2020 New module exam_print to generate new exam prints. (301949 lines) diff --git a/swad_course.c b/swad_course.c index 2d5eba50..29f61afc 100644 --- a/swad_course.c +++ b/swad_course.c @@ -40,6 +40,7 @@ #include "swad_figure_cache.h" #include "swad_form.h" #include "swad_forum.h" +#include "swad_game.h" #include "swad_global.h" #include "swad_help.h" #include "swad_HTML.h" @@ -49,7 +50,7 @@ #include "swad_project.h" #include "swad_search.h" #include "swad_survey.h" -#include "swad_test_exam.h" +#include "swad_test.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -1988,7 +1989,7 @@ static void Crs_EmptyCourseCompletely (long CrsCod) Svy_RemoveSurveys (Hie_CRS,CrsCod); /***** Remove all test exams made in the course *****/ - TstRes_RemoveCrsExams (CrsCod); + TstPrn_RemoveCrsExams (CrsCod); /***** Remove all tests questions in the course *****/ Tst_RemoveCrsTests (CrsCod); diff --git a/swad_database.c b/swad_database.c index 4df25a9e..676502c6 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1768,7 +1768,7 @@ mysql> DESCRIBE mch_indexes; DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_indexes (" "MchCod INT NOT NULL," "QstInd INT NOT NULL," - "Indexes TEXT NOT NULL," // TstRes_MAX_BYTES_INDEXES_ONE_QST + "Indexes TEXT NOT NULL," // TstPrn_MAX_BYTES_INDEXES_ONE_QST "UNIQUE INDEX(MchCod,QstInd))"); /***** Table mch_results *****/ @@ -3189,8 +3189,8 @@ mysql> DESCRIBE tst_exam_questions; "QstCod INT NOT NULL," "QstInd INT NOT NULL," "Score DOUBLE PRECISION NOT NULL DEFAULT 0," - "Indexes TEXT NOT NULL," // TstRes_MAX_BYTES_INDEXES_ONE_QST - "Answers TEXT NOT NULL," // TstRes_MAX_BYTES_ANSWERS_ONE_QST + "Indexes TEXT NOT NULL," // TstPrn_MAX_BYTES_INDEXES_ONE_QST + "Answers TEXT NOT NULL," // TstPrn_MAX_BYTES_ANSWERS_ONE_QST "UNIQUE INDEX(ExaCod,QstCod))"); /***** Table tst_exams *****/ diff --git a/swad_enrolment.c b/swad_enrolment.c index 51d3d4fc..0aa1ca20 100644 --- a/swad_enrolment.c +++ b/swad_enrolment.c @@ -47,7 +47,7 @@ #include "swad_parameter.h" #include "swad_photo.h" #include "swad_role.h" -#include "swad_test_exam.h" +#include "swad_test_print.h" #include "swad_user.h" /*****************************************************************************/ @@ -4128,7 +4128,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat, Brw_RemoveSomeInfoAboutCrsUsrFilesFromDB (UsrDat->UsrCod,Crs->CrsCod); /***** Remove test results made by user in course *****/ - TstRes_RemoveExamsMadeByUsrInCrs (UsrDat->UsrCod,Crs->CrsCod); + TstPrn_RemoveExamsMadeByUsrInCrs (UsrDat->UsrCod,Crs->CrsCod); /***** Set all the notifications for this user in this course as removed, except notifications about new messages *****/ diff --git a/swad_exam_event.c b/swad_exam_event.c index 4b4dba5f..b4abe274 100644 --- a/swad_exam_event.c +++ b/swad_exam_event.c @@ -239,7 +239,7 @@ static void ExaEvt_GetNumParticipants (struct ExaEvt_Event *Event); static void ExaEvt_RemoveMyAnswerToEventQuestion (const struct ExaEvt_Event *Event); -static void ExaEvt_ComputeScore (struct TstRes_Result *Result); +static void ExaEvt_ComputeScore (struct TstPrn_Print *Print); static unsigned ExaEvt_GetNumUsrsWhoHaveAnswerEvt (long EvtCod); @@ -1934,7 +1934,7 @@ static void ExaEvt_ReorderAnswer (long EvtCod,unsigned QstInd, long LongNum; unsigned AnsInd; char StrOneAnswer[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrAnswersOneQst[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char StrAnswersOneQst[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; ***** Initialize list of answers to empty string ***** StrAnswersOneQst[0] = '\0'; @@ -1967,9 +1967,9 @@ static void ExaEvt_ReorderAnswer (long EvtCod,unsigned QstInd, * Concatenate answer index to list of answers * if (NumAns) Str_Concat (StrAnswersOneQst,",", - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); Str_Concat (StrAnswersOneQst,StrOneAnswer, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); } ***** Free structure that stores the query result ***** @@ -1993,7 +1993,7 @@ void ExaEvt_GetIndexes (long EvtCod,unsigned QstInd, { MYSQL_RES *mysql_res; MYSQL_ROW row; - char StrIndexesOneQst[TstRes_MAX_BYTES_INDEXES_ONE_QST + 1]; + char StrIndexesOneQst[TstPrn_MAX_BYTES_INDEXES_ONE_QST + 1]; /***** Get indexes for a question from database *****/ if (!DB_QuerySELECT (&mysql_res,"can not get data of a question", @@ -2006,14 +2006,14 @@ void ExaEvt_GetIndexes (long EvtCod,unsigned QstInd, /* Get indexes (row[0]) */ Str_Copy (StrIndexesOneQst,row[0], - TstRes_MAX_BYTES_INDEXES_ONE_QST); + TstPrn_MAX_BYTES_INDEXES_ONE_QST); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); /***** Get indexes from string *****/ Par_ReplaceCommaBySeparatorMultiple (StrIndexesOneQst); - TstRes_GetIndexesFromStr (StrIndexesOneQst,Indexes); + TstPrn_GetIndexesFromStr (StrIndexesOneQst,Indexes); } /*****************************************************************************/ @@ -4212,7 +4212,7 @@ void ExaEvt_ReceiveQuestionAnswer (void) unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; struct ExaEvt_UsrAnswer PreviousUsrAnswer; struct ExaEvt_UsrAnswer UsrAnswer; - struct TstRes_Result Result; + struct TstPrn_Print Print; /***** Reset event *****/ ExaEvt_ResetEvent (&Event); @@ -4271,8 +4271,8 @@ void ExaEvt_ReceiveQuestionAnswer (void) /***** Update student's exam event result *****/ ExaRes_GetExamResultQuestionsFromDB (Event.EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod, - &Result); - ExaEvt_ComputeScore (&Result); + &Print); + ExaEvt_ComputeScore (&Print); Str_SetDecimalPointToUS (); // To print the floating point as a dot if (DB_QueryCOUNT ("can not get if exam event result exists", @@ -4287,9 +4287,9 @@ void ExaEvt_ReceiveQuestionAnswer (void) "NumQstsNotBlank=%u," "Score='%.15lg'" " WHERE EvtCod=%ld AND UsrCod=%ld", - Result.NumQsts, - Result.NumQstsNotBlank, - Result.Score, + Print.NumQsts, + Print.NumQstsNotBlank, + Print.Score, Event.EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod); else // Result doesn't exist /* Create result */ @@ -4305,9 +4305,9 @@ void ExaEvt_ReceiveQuestionAnswer (void) "%u," // NumQstsNotBlank "'%.15lg')", // Score Event.EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod, - Result.NumQsts, - Result.NumQstsNotBlank, - Result.Score); + Print.NumQsts, + Print.NumQstsNotBlank, + Print.Score); Str_SetDecimalPointToLocal (); // Return to local system } @@ -4333,25 +4333,25 @@ static void ExaEvt_RemoveMyAnswerToEventQuestion (const struct ExaEvt_Event *Eve /******************** Compute exam event score for a student **********************/ /*****************************************************************************/ -static void ExaEvt_ComputeScore (struct TstRes_Result *Result) +static void ExaEvt_ComputeScore (struct TstPrn_Print *Print) { unsigned NumQst; struct Tst_Question Question; - for (NumQst = 0, Result->Score = 0.0; - NumQst < Result->NumQsts; + for (NumQst = 0, Print->Score = 0.0; + NumQst < Print->NumQsts; NumQst++) { /***** Create test question *****/ Tst_QstConstructor (&Question); - Question.QstCod = Result->Questions[NumQst].QstCod; + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; Question.Answer.Type = Tst_ANS_UNIQUE_CHOICE; /***** Compute score for this answer ******/ - TstRes_ComputeChoiceAnsScore (Result,NumQst,&Question); + TstPrn_ComputeChoiceAnsScore (Print,NumQst,&Question); /***** Update total score *****/ - Result->Score += Result->Questions[NumQst].Score; + Print->Score += Print->PrintedQuestions[NumQst].Score; /***** Destroy test question *****/ Tst_QstDestructor (&Question); diff --git a/swad_exam_print.c b/swad_exam_print.c index b3afc505..14b13a60 100644 --- a/swad_exam_print.c +++ b/swad_exam_print.c @@ -51,13 +51,22 @@ 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 { - unsigned foo; + long PrnCod; // Exam print code + 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]; }; /*****************************************************************************/ @@ -72,11 +81,33 @@ struct ExaPrn_Print /***************************** Private prototypes ****************************/ /*****************************************************************************/ -static void ExaPrn_PrintConstructor (struct ExaPrn_Print *Print); -static void ExaPrn_PrintDestructor (struct ExaPrn_Print *Print); +static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print); +static void ExaPrn_ResetPrintExceptPrnCod (struct ExaPrn_Print *Print); static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, struct ExaPrn_Print *Print); +static void ExaPrn_ShowQuestionsFromSet (struct ExaPrn_Print *Print, + struct ExaSet_Set *Set); + +/*****************************************************************************/ +/**************************** Reset exam print *******************************/ +/*****************************************************************************/ + +static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print) + { + Print->PrnCod = -1L; + ExaPrn_ResetPrintExceptPrnCod (Print); + } + +static void ExaPrn_ResetPrintExceptPrnCod (struct ExaPrn_Print *Print) + { + Print->TimeUTC[Dat_START_TIME] = + Print->TimeUTC[Dat_END_TIME ] = (time_t) 0; + Print->NumQsts = + Print->NumQstsNotBlank = 0; + Print->Sent = false; // After creating an exam print, it's not sent + Print->Score = 0.0; + } /*****************************************************************************/ /******************* Generate print of an exam in an event *******************/ @@ -94,13 +125,11 @@ void ExaPrn_ShowNewExamPrint (void) Exa_ResetExams (&Exams); Exa_ResetExam (&Exam); ExaEvt_ResetEvent (&Event); + ExaPrn_ResetPrint (&Print); /***** Get and check parameters *****/ ExaEvt_GetAndCheckParameters (&Exams,&Exam,&Event); - /***** Create print *****/ - ExaPrn_PrintConstructor (&Print); - /***** Begin box *****/ Box_BoxBegin (NULL,Exam.Title, NULL,NULL, @@ -118,35 +147,12 @@ void ExaPrn_ShowNewExamPrint (void) /***** End table *****/ HTM_TABLE_End (); - - /***** Destroy print *****/ - ExaPrn_PrintDestructor (&Print); - } - -/*****************************************************************************/ -/***************************** Print constructor *****************************/ -/*****************************************************************************/ - -static void ExaPrn_PrintConstructor (struct ExaPrn_Print *Print) - { - Print->foo = 1; - } - -/*****************************************************************************/ -/****************************** Print destructor *****************************/ -/*****************************************************************************/ - -static void ExaPrn_PrintDestructor (struct ExaPrn_Print *Print) - { - Print->foo = 1; } /*****************************************************************************/ /*********** Get questions for a new exam print from the database ************/ /*****************************************************************************/ -#define ExaPrn_MAX_BYTES_QUERY_PRINT (16 * 1024 - 1) - static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, struct ExaPrn_Print *Print) { @@ -158,8 +164,6 @@ static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, unsigned NumSet; struct ExaSet_Set Set; - Print->foo = 1; - /***** Get data of set of questions from database *****/ NumSets = (unsigned) DB_QuerySELECT (&mysql_res,"can not get sets of questions", @@ -178,8 +182,6 @@ static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, NumSet < NumSets; NumSet++) { - Gbl.RowEvenOdd = NumSet % 2; - /***** Create set of questions *****/ ExaSet_ResetSet (&Set); @@ -200,26 +202,130 @@ static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, Str_Copy (Set.Title,row[2], ExaSet_MAX_BYTES_TITLE); - /***** Begin row for this set *****/ + /***** Title for this set *****/ + /* Begin title for this set */ HTM_TR_Begin (NULL); + HTM_TD_Begin ("colspan=\"2\""); + HTM_TABLE_BeginWide (); - /***** Title *****/ - HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + /* Title */ + HTM_TD_Begin ("class=\"EXA_SET_TITLE\""); HTM_Txt (Set.Title); HTM_TD_End (); - /***** Number of questions to appear in exam print *****/ - HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd); + /* Number of questions to appear in exam print */ + HTM_TD_Begin ("class=\"EXA_SET_NUM_QSTS\""); HTM_Unsigned (Set.NumQstsToPrint); HTM_NBSP (); HTM_Txt (Set.NumQstsToPrint == 1 ? Txt_question : Txt_questions); HTM_TD_End (); - /***** End first row *****/ + /* End title for this set */ + HTM_TABLE_End (); + HTM_TD_End (); HTM_TR_End (); + + /***** Questions in this set *****/ + ExaPrn_ShowQuestionsFromSet (Print,&Set); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } + +/*****************************************************************************/ +/************************ Show questions from a set **************************/ +/*****************************************************************************/ + +static void ExaPrn_ShowQuestionsFromSet (struct ExaPrn_Print *Print, + struct ExaSet_Set *Set) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumQsts; + unsigned NumQst; + long QstCod; + Tst_AnswerType_t AnswerType; + bool Shuffle; + + /***** Get questions from database *****/ + NumQsts = (unsigned) + DB_QuerySELECT (&mysql_res,"can not get questions from set", + "SELECT tst_questions.QstCod," // row[0] + "tst_questions.AnsType," // row[1] + "tst_questions.Shuffle" // row[2] + " FROM exa_questions,tst_questions" + " WHERE exa_questions.setCod=%ld" + " AND exa_questions.QstCod=tst_questions.QstCod" + " ORDER BY RAND(NOW())" + " LIMIT %u", + Set->SetCod, + Set->NumQstsToPrint); + + /***** Questions in this set *****/ + for (NumQst = 0; + NumQst < NumQsts; + NumQst++) + { + Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd; + + /***** Get question data *****/ + row = mysql_fetch_row (mysql_res); + /* + row[0] QstCod + row[1] AnsType + row[2] Shuffle + */ + + /* Get question code (row[0]) */ + QstCod = Str_ConvertStrCodToLongCod (row[0]); + + /* Get answer type (row[1]) */ + AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); + + /* Get shuffle (row[2]) */ + Shuffle = (row[2][0] == 'Y'); + + /* Set indexes of answers */ + switch (AnswerType) + { + case Tst_ANS_INT: + case Tst_ANS_FLOAT: + case Tst_ANS_TRUE_FALSE: + case Tst_ANS_TEXT: + Print->PrintedQuestions[NumQst].StrIndexes[0] = '\0'; + break; + case Tst_ANS_UNIQUE_CHOICE: + case Tst_ANS_MULTIPLE_CHOICE: + /* If answer type is unique or multiple option, + generate indexes of answers depending on shuffle */ + Tst_GenerateChoiceIndexesDependingOnShuffle (&Print->PrintedQuestions[NumQst],Shuffle); + break; + default: + break; + } + + /* Reset user's answers. + Initially user has not answered the question ==> initially all the answers will be blank. + If the user does not confirm the submission of their exam ==> + ==> the exam may be half filled ==> the answers displayed will be those selected by the user. */ + Print->PrintedQuestions[NumQst].StrAnswers[0] = '\0'; + + /* Begin row for this question */ + HTM_TR_Begin (NULL); + + /* Title */ + HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + HTM_TxtF ("Pregunta %ld",QstCod); + HTM_TD_End (); + + /* Number of questions to appear in exam print */ + HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + HTM_Txt ("Enunciado y respuestas"); + HTM_TD_End (); + + /* End title for this question */ + HTM_TR_End (); + } + } diff --git a/swad_exam_result.c b/swad_exam_result.c index 951e84f2..0def0284 100644 --- a/swad_exam_result.c +++ b/swad_exam_result.c @@ -103,7 +103,7 @@ static void ExaRes_ShowEvtResultsSummaryRow (unsigned NumResults, double TotalScoreOfAllResults, double TotalGrade); static void ExaRes_GetEventResultDataByEvtCod (long EvtCod,long UsrCod, - struct TstRes_Result *Result); + struct TstPrn_Print *Print); static bool ExaRes_CheckIfICanSeeEventResult (struct ExaEvt_Event *Event,long UsrCod); static bool ExaRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility); @@ -958,8 +958,8 @@ static void ExaRes_ShowEvtResults (struct Exa_Exams *Exams, HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); if (ICanViewScore) { - Grade = TstRes_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade); - TstRes_ShowGrade (Grade,MaxGrade); + Grade = TstPrn_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade); + TstPrn_ShowGrade (Grade,MaxGrade); TotalGrade += Grade; } else @@ -1092,7 +1092,7 @@ void ExaRes_ShowOneExaResult (void) struct UsrData *UsrDat; Dat_StartEndTime_t StartEndTime; char *Id; - struct TstRes_Result Result; + struct TstPrn_Print Print; bool ShowPhoto; char PhotoURL[PATH_MAX + 1]; bool ICanViewResult; @@ -1122,8 +1122,8 @@ void ExaRes_ShowOneExaResult (void) } /***** Get event result data *****/ - TstRes_ResetResult (&Result); - ExaRes_GetEventResultDataByEvtCod (Event.EvtCod,UsrDat->UsrCod,&Result); + TstPrn_ResetResult (&Print); + ExaRes_GetEventResultDataByEvtCod (Event.EvtCod,UsrDat->UsrCod,&Print); /***** Check if I can view this event result *****/ switch (Gbl.Usrs.Me.Role.Logged) @@ -1154,7 +1154,7 @@ void ExaRes_ShowOneExaResult (void) { /***** Get questions and user's answers of the event result from database *****/ ExaRes_GetExamResultQuestionsFromDB (Event.EvtCod,UsrDat->UsrCod, - &Result); + &Print); /***** Begin box *****/ Box_BoxBegin (NULL,Event.Title, @@ -1230,8 +1230,8 @@ void ExaRes_ShowOneExaResult (void) HTM_TD_Begin ("class=\"DAT LT\""); HTM_TxtF ("%u (%u %s)", - Result.NumQsts, - Result.NumQstsNotBlank,Txt_non_blank_QUESTIONS); + Print.NumQsts, + Print.NumQstsNotBlank,Txt_non_blank_QUESTIONS); HTM_TD_End (); HTM_TR_End (); @@ -1245,7 +1245,7 @@ void ExaRes_ShowOneExaResult (void) HTM_TD_Begin ("class=\"DAT LT\""); if (ICanViewScore) - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); else Ico_PutIconNotVisible (); HTM_TD_End (); @@ -1261,7 +1261,7 @@ void ExaRes_ShowOneExaResult (void) HTM_TD_Begin ("class=\"DAT LT\""); if (ICanViewScore) - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, Exam.MaxGrade); else Ico_PutIconNotVisible (); @@ -1283,7 +1283,7 @@ void ExaRes_ShowOneExaResult (void) HTM_TR_End (); /***** Write answers and solutions *****/ - TstRes_ShowExamAnswers (UsrDat,&Result,Exam.Visibility); + TstPrn_ShowExamAnswers (UsrDat,&Print,Exam.Visibility); /***** End table *****/ HTM_TABLE_End (); @@ -1293,10 +1293,10 @@ void ExaRes_ShowOneExaResult (void) { HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\""); HTM_TxtColonNBSP (Txt_Score); - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); HTM_BR (); HTM_TxtColonNBSP (Txt_Grade); - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, Exam.MaxGrade); HTM_DIV_End (); } @@ -1313,7 +1313,7 @@ void ExaRes_ShowOneExaResult (void) /*****************************************************************************/ void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod, - struct TstRes_Result *Result) + struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1323,27 +1323,27 @@ void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod, struct ExaEvt_UsrAnswer UsrAnswer; /***** Get questions and answers of a event result *****/ - Result->NumQsts = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get questions and answers" - " of a event result", - "SELECT exa_questions.QstCod," // row[0] - "exa_questions.QstInd," // row[1] - "exa_indexes.Indexes" // row[2] - " FROM exa_events,exa_questions,exa_indexes" - " WHERE exa_events.EvtCod=%ld" - " AND exa_events.ExaCod=exa_questions.ExaCod" - " AND exa_events.EvtCod=exa_indexes.EvtCod" - " AND exa_questions.QstInd=exa_indexes.QstInd" - " ORDER BY exa_questions.QstInd", - EvtCod); - for (NumQst = 0, Result->NumQstsNotBlank = 0; - NumQst < Result->NumQsts; + Print->NumQsts = (unsigned) + DB_QuerySELECT (&mysql_res,"can not get questions and answers" + " of a event result", + "SELECT exa_questions.QstCod," // row[0] + "exa_questions.QstInd," // row[1] + "exa_indexes.Indexes" // row[2] + " FROM exa_events,exa_questions,exa_indexes" + " WHERE exa_events.EvtCod=%ld" + " AND exa_events.ExaCod=exa_questions.ExaCod" + " AND exa_events.EvtCod=exa_indexes.EvtCod" + " AND exa_questions.QstInd=exa_indexes.QstInd" + " ORDER BY exa_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 ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + if ((Print->PrintedQuestions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); /* Get question index (row[1]) */ @@ -1352,24 +1352,24 @@ void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod, QstInd = (unsigned) LongNum; /* Get indexes for this question (row[2]) */ - Str_Copy (Result->Questions[NumQst].StrIndexes,row[2], - TstRes_MAX_BYTES_INDEXES_ONE_QST); + Str_Copy (Print->PrintedQuestions[NumQst].StrIndexes,row[2], + TstPrn_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 (Result->Questions[NumQst].StrAnswers,TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1, + snprintf (Print->PrintedQuestions[NumQst].StrAnswers,TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1, "%d",UsrAnswer.AnsInd); - Result->NumQstsNotBlank++; + Print->NumQstsNotBlank++; } else // UsrAnswer.AnsInd < 0 ==> no answer selected - Result->Questions[NumQst].StrAnswers[0] = '\0'; // Empty answer + Print->PrintedQuestions[NumQst].StrAnswers[0] = '\0'; // Empty answer /* Replace each comma by a separator of multiple parameters */ /* In database commas are used as separators instead of special chars */ - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes); - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers); + Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrIndexes); + Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrAnswers); } /***** Free structure that stores the query result *****/ @@ -1381,7 +1381,7 @@ void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod, /*****************************************************************************/ static void ExaRes_GetEventResultDataByEvtCod (long EvtCod,long UsrCod, - struct TstRes_Result *Result) + struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1410,27 +1410,27 @@ static void ExaRes_GetEventResultDataByEvtCod (long EvtCod,long UsrCod, for (StartEndTime = (Dat_StartEndTime_t) 0; StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); StartEndTime++) - Result->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]); + Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]); /* Get number of questions (row[2]) */ - if (sscanf (row[2],"%u",&Result->NumQsts) != 1) - Result->NumQsts = 0; + if (sscanf (row[2],"%u",&Print->NumQsts) != 1) + Print->NumQsts = 0; /* Get number of questions not blank (row[3]) */ - if (sscanf (row[3],"%u",&Result->NumQstsNotBlank) != 1) - Result->NumQstsNotBlank = 0; + 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",&Result->Score) != 1) - Result->Score = 0.0; + if (sscanf (row[4],"%lf",&Print->Score) != 1) + Print->Score = 0.0; Str_SetDecimalPointToLocal (); // Return to local system } else { - Result->NumQsts = 0; - Result->NumQstsNotBlank = 0; - Result->Score = 0.0; + Print->NumQsts = 0; + Print->NumQstsNotBlank = 0; + Print->Score = 0.0; } /***** Free structure that stores the query result *****/ diff --git a/swad_exam_result.h b/swad_exam_result.h index 03dfb4a6..b3536414 100644 --- a/swad_exam_result.h +++ b/swad_exam_result.h @@ -27,7 +27,7 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -#include "swad_test_exam.h" +#include "swad_test_print.h" /*****************************************************************************/ /************************** Public types and constants ***********************/ @@ -51,6 +51,6 @@ void ExaRes_ShowAllExaResultsInEvt (void); void ExaRes_ShowOneExaResult (void); void ExaRes_GetExamResultQuestionsFromDB (long EvtCod,long UsrCod, - struct TstRes_Result *Result); + struct TstPrn_Print *Print); #endif diff --git a/swad_match.c b/swad_match.c index d2862870..ae72e90c 100644 --- a/swad_match.c +++ b/swad_match.c @@ -229,7 +229,7 @@ static void Mch_GetNumPlayers (struct Mch_Match *Match); static void Mch_RemoveMyAnswerToMatchQuestion (const struct Mch_Match *Match); -static void Mch_ComputeScore (struct TstRes_Result *Result); +static void Mch_ComputeScore (struct TstPrn_Print *Print); static unsigned Mch_GetNumUsrsWhoHaveAnswerMch (long MchCod); @@ -1612,7 +1612,7 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd, long LongNum; unsigned AnsInd; char StrOneAnswer[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrAnswersOneQst[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char StrAnswersOneQst[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; /***** Initialize list of answers to empty string *****/ StrAnswersOneQst[0] = '\0'; @@ -1645,9 +1645,9 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd, /* Concatenate answer index to list of answers */ if (NumAns) Str_Concat (StrAnswersOneQst,",", - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); Str_Concat (StrAnswersOneQst,StrOneAnswer, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); } /***** Free structure that stores the query result *****/ @@ -1671,7 +1671,7 @@ void Mch_GetIndexes (long MchCod,unsigned QstInd, { MYSQL_RES *mysql_res; MYSQL_ROW row; - char StrIndexesOneQst[TstRes_MAX_BYTES_INDEXES_ONE_QST + 1]; + char StrIndexesOneQst[TstPrn_MAX_BYTES_INDEXES_ONE_QST + 1]; /***** Get indexes for a question from database *****/ if (!DB_QuerySELECT (&mysql_res,"can not get data of a question", @@ -1684,14 +1684,14 @@ void Mch_GetIndexes (long MchCod,unsigned QstInd, /* Get indexes (row[0]) */ Str_Copy (StrIndexesOneQst,row[0], - TstRes_MAX_BYTES_INDEXES_ONE_QST); + TstPrn_MAX_BYTES_INDEXES_ONE_QST); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); /***** Get indexes from string *****/ Par_ReplaceCommaBySeparatorMultiple (StrIndexesOneQst); - TstRes_GetIndexesFromStr (StrIndexesOneQst,Indexes); + TstPrn_GetIndexesFromStr (StrIndexesOneQst,Indexes); } /*****************************************************************************/ @@ -3881,7 +3881,7 @@ void Mch_ReceiveQuestionAnswer (void) unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; struct Mch_UsrAnswer PreviousUsrAnswer; struct Mch_UsrAnswer UsrAnswer; - struct TstRes_Result Result; + struct TstPrn_Print Print; /***** Reset match *****/ Mch_ResetMatch (&Match); @@ -3940,14 +3940,14 @@ void Mch_ReceiveQuestionAnswer (void) /***** Update student's match result *****/ MchRes_GetMatchResultQuestionsFromDB (Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod, - &Result); - Mch_ComputeScore (&Result); + &Print); + Mch_ComputeScore (&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", - Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod)) // Result exists + Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod)) // Match print exists /* Update result */ DB_QueryUPDATE ("can not update match result", "UPDATE mch_results" @@ -3956,11 +3956,11 @@ void Mch_ReceiveQuestionAnswer (void) "NumQstsNotBlank=%u," "Score='%.15lg'" " WHERE MchCod=%ld AND UsrCod=%ld", - Result.NumQsts, - Result.NumQstsNotBlank, - Result.Score, + Print.NumQsts, + Print.NumQstsNotBlank, + Print.Score, Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod); - else // Result doesn't exist + else // Match print doesn't exist /* Create result */ DB_QueryINSERT ("can not create match result", "INSERT mch_results " @@ -3974,9 +3974,9 @@ void Mch_ReceiveQuestionAnswer (void) "%u," // NumQstsNotBlank "'%.15lg')", // Score Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod, - Result.NumQsts, - Result.NumQstsNotBlank, - Result.Score); + Print.NumQsts, + Print.NumQstsNotBlank, + Print.Score); Str_SetDecimalPointToLocal (); // Return to local system } @@ -4002,25 +4002,25 @@ static void Mch_RemoveMyAnswerToMatchQuestion (const struct Mch_Match *Match) /******************** Compute match score for a student **********************/ /*****************************************************************************/ -static void Mch_ComputeScore (struct TstRes_Result *Result) +static void Mch_ComputeScore (struct TstPrn_Print *Print) { unsigned NumQst; struct Tst_Question Question; - for (NumQst = 0, Result->Score = 0.0; - NumQst < Result->NumQsts; + for (NumQst = 0, Print->Score = 0.0; + NumQst < Print->NumQsts; NumQst++) { /***** Create test question *****/ Tst_QstConstructor (&Question); - Question.QstCod = Result->Questions[NumQst].QstCod; + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; Question.Answer.Type = Tst_ANS_UNIQUE_CHOICE; /***** Compute score for this answer ******/ - TstRes_ComputeChoiceAnsScore (Result,NumQst,&Question); + TstPrn_ComputeChoiceAnsScore (Print,NumQst,&Question); /***** Update total score *****/ - Result->Score += Result->Questions[NumQst].Score; + Print->Score += Print->PrintedQuestions[NumQst].Score; /***** Destroy test question *****/ Tst_QstDestructor (&Question); diff --git a/swad_match_result.c b/swad_match_result.c index 3762b5e4..e30723e0 100644 --- a/swad_match_result.c +++ b/swad_match_result.c @@ -101,7 +101,7 @@ static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults, double TotalScoreOfAllResults, double TotalGrade); static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod, - struct TstRes_Result *Result); + struct TstPrn_Print *Print); static bool MchRes_CheckIfICanSeeMatchResult (struct Mch_Match *Match,long UsrCod); static bool MchRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility); @@ -947,8 +947,8 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games, HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); if (ICanViewScore) { - Grade = TstRes_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade); - TstRes_ShowGrade (Grade,MaxGrade); + Grade = TstPrn_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade); + TstPrn_ShowGrade (Grade,MaxGrade); TotalGrade += Grade; } else @@ -1081,7 +1081,7 @@ void MchRes_ShowOneMchResult (void) struct UsrData *UsrDat; Dat_StartEndTime_t StartEndTime; char *Id; - struct TstRes_Result Result; + struct TstPrn_Print Print; bool ShowPhoto; char PhotoURL[PATH_MAX + 1]; bool ICanViewResult; @@ -1113,8 +1113,8 @@ void MchRes_ShowOneMchResult (void) } /***** Get match result data *****/ - TstRes_ResetResult (&Result); - MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Result); + TstPrn_ResetResult (&Print); + MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Print); /***** Check if I can view this match result *****/ switch (Gbl.Usrs.Me.Role.Logged) @@ -1145,7 +1145,7 @@ void MchRes_ShowOneMchResult (void) { /***** Get questions and user's answers of the match result from database *****/ MchRes_GetMatchResultQuestionsFromDB (Match.MchCod,UsrDat->UsrCod, - &Result); + &Print); /***** Begin box *****/ Box_BoxBegin (NULL,Match.Title, @@ -1203,7 +1203,7 @@ void MchRes_ShowOneMchResult (void) if (asprintf (&Id,"match_%u",(unsigned) StartEndTime) < 0) Lay_NotEnoughMemoryExit (); HTM_TD_Begin ("id=\"%s\" class=\"DAT LT\"",Id); - Dat_WriteLocalDateHMSFromUTC (Id,Result.TimeUTC[StartEndTime], + Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime], Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,true,true,0x7); HTM_TD_End (); @@ -1221,8 +1221,8 @@ void MchRes_ShowOneMchResult (void) HTM_TD_Begin ("class=\"DAT LT\""); HTM_TxtF ("%u (%u %s)", - Result.NumQsts, - Result.NumQstsNotBlank,Txt_non_blank_QUESTIONS); + Print.NumQsts, + Print.NumQstsNotBlank,Txt_non_blank_QUESTIONS); HTM_TD_End (); HTM_TR_End (); @@ -1236,7 +1236,7 @@ void MchRes_ShowOneMchResult (void) HTM_TD_Begin ("class=\"DAT LT\""); if (ICanViewScore) - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); else Ico_PutIconNotVisible (); HTM_TD_End (); @@ -1252,7 +1252,7 @@ void MchRes_ShowOneMchResult (void) HTM_TD_Begin ("class=\"DAT LT\""); if (ICanViewScore) - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, Game.MaxGrade); else Ico_PutIconNotVisible (); @@ -1274,7 +1274,7 @@ void MchRes_ShowOneMchResult (void) HTM_TR_End (); /***** Write answers and solutions *****/ - TstRes_ShowExamAnswers (UsrDat,&Result,Game.Visibility); + TstPrn_ShowExamAnswers (UsrDat,&Print,Game.Visibility); /***** End table *****/ HTM_TABLE_End (); @@ -1284,10 +1284,10 @@ void MchRes_ShowOneMchResult (void) { HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\""); HTM_TxtColonNBSP (Txt_Score); - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); HTM_BR (); HTM_TxtColonNBSP (Txt_Grade); - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, Game.MaxGrade); HTM_DIV_End (); } @@ -1304,7 +1304,7 @@ void MchRes_ShowOneMchResult (void) /*****************************************************************************/ void MchRes_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod, - struct TstRes_Result *Result) + struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1314,27 +1314,27 @@ void MchRes_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod, struct Mch_UsrAnswer UsrAnswer; /***** Get questions and answers of a match result *****/ - Result->NumQsts = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get questions and answers" - " of a match result", - "SELECT gam_questions.QstCod," // row[0] - "gam_questions.QstInd," // row[1] - "mch_indexes.Indexes" // row[2] - " FROM mch_matches,gam_questions,mch_indexes" - " WHERE mch_matches.MchCod=%ld" - " AND mch_matches.GamCod=gam_questions.GamCod" - " AND mch_matches.MchCod=mch_indexes.MchCod" - " AND gam_questions.QstInd=mch_indexes.QstInd" - " ORDER BY gam_questions.QstInd", - MchCod); - for (NumQst = 0, Result->NumQstsNotBlank = 0; - NumQst < Result->NumQsts; + Print->NumQsts = (unsigned) + DB_QuerySELECT (&mysql_res,"can not get questions and answers" + " of a match result", + "SELECT gam_questions.QstCod," // row[0] + "gam_questions.QstInd," // row[1] + "mch_indexes.Indexes" // row[2] + " FROM mch_matches,gam_questions,mch_indexes" + " WHERE mch_matches.MchCod=%ld" + " AND mch_matches.GamCod=gam_questions.GamCod" + " AND mch_matches.MchCod=mch_indexes.MchCod" + " AND gam_questions.QstInd=mch_indexes.QstInd" + " ORDER BY gam_questions.QstInd", + MchCod); + for (NumQst = 0, Print->NumQstsNotBlank = 0; + NumQst < Print->NumQsts; NumQst++) { row = mysql_fetch_row (mysql_res); /* Get question code (row[0]) */ - if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + if ((Print->PrintedQuestions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); /* Get question index (row[1]) */ @@ -1343,24 +1343,24 @@ void MchRes_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod, QstInd = (unsigned) LongNum; /* Get indexes for this question (row[2]) */ - Str_Copy (Result->Questions[NumQst].StrIndexes,row[2], - TstRes_MAX_BYTES_INDEXES_ONE_QST); + Str_Copy (Print->PrintedQuestions[NumQst].StrIndexes,row[2], + TstPrn_MAX_BYTES_INDEXES_ONE_QST); /* Get answers selected by user for this question */ Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer); if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected { - snprintf (Result->Questions[NumQst].StrAnswers,TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1, + snprintf (Print->PrintedQuestions[NumQst].StrAnswers,TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1, "%d",UsrAnswer.AnsInd); - Result->NumQstsNotBlank++; + Print->NumQstsNotBlank++; } else // UsrAnswer.AnsInd < 0 ==> no answer selected - Result->Questions[NumQst].StrAnswers[0] = '\0'; // Empty answer + Print->PrintedQuestions[NumQst].StrAnswers[0] = '\0'; // Empty answer /* Replace each comma by a separator of multiple parameters */ /* In database commas are used as separators instead of special chars */ - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes); - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers); + Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrIndexes); + Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrAnswers); } /***** Free structure that stores the query result *****/ @@ -1372,7 +1372,7 @@ void MchRes_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod, /*****************************************************************************/ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod, - struct TstRes_Result *Result) + struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1401,27 +1401,27 @@ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod, for (StartEndTime = (Dat_StartEndTime_t) 0; StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); StartEndTime++) - Result->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]); + Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]); /* Get number of questions (row[2]) */ - if (sscanf (row[2],"%u",&Result->NumQsts) != 1) - Result->NumQsts = 0; + if (sscanf (row[2],"%u",&Print->NumQsts) != 1) + Print->NumQsts = 0; /* Get number of questions not blank (row[3]) */ - if (sscanf (row[3],"%u",&Result->NumQstsNotBlank) != 1) - Result->NumQstsNotBlank = 0; + 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",&Result->Score) != 1) - Result->Score = 0.0; + if (sscanf (row[4],"%lf",&Print->Score) != 1) + Print->Score = 0.0; Str_SetDecimalPointToLocal (); // Return to local system } else { - Result->NumQsts = 0; - Result->NumQstsNotBlank = 0; - Result->Score = 0.0; + Print->NumQsts = 0; + Print->NumQstsNotBlank = 0; + Print->Score = 0.0; } /***** Free structure that stores the query result *****/ diff --git a/swad_match_result.h b/swad_match_result.h index 4e773737..9f4f8acb 100644 --- a/swad_match_result.h +++ b/swad_match_result.h @@ -27,7 +27,7 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -#include "swad_test_exam.h" +#include "swad_test_print.h" /*****************************************************************************/ /************************** Public types and constants ***********************/ @@ -51,6 +51,6 @@ void MchRes_ShowAllMchResultsInMch (void); void MchRes_ShowOneMchResult (void); void MchRes_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod, - struct TstRes_Result *Result); + struct TstPrn_Print *Print); #endif diff --git a/swad_test.c b/swad_test.c index 5a76f7d7..8ea5a03c 100644 --- a/swad_test.c +++ b/swad_test.c @@ -52,9 +52,9 @@ #include "swad_parameter.h" #include "swad_theme.h" #include "swad_test.h" -#include "swad_test_exam.h" #include "swad_test_config.h" #include "swad_test_import.h" +#include "swad_test_print.h" #include "swad_test_visibility.h" #include "swad_user.h" #include "swad_xml.h" @@ -133,15 +133,15 @@ static void Tst_ShowFormRequestTest (struct Tst_Test *Test); static void Tst_PutCheckBoxAllowTeachers (bool AllowTeachers); -static void Tst_GetAnswersFromForm (struct TstRes_Result *Result); +static void Tst_GetAnswersFromForm (struct TstPrn_Print *Print); static bool Tst_CheckIfNextTstAllowed (void); static unsigned Tst_GetNumExamsGeneratedByMe (void); -static void Tst_ShowTestExamToFillIt (struct TstRes_Result *Result, +static void Tst_ShowTestExamToFillIt (struct TstPrn_Print *Print, unsigned NumExamsGeneratedByMe, Tst_RequestOrConfirm_t RequestOrConfirm); -static void Tst_WriteQstAndAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteQstAndAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question); @@ -177,10 +177,7 @@ static void Tst_PutInputFieldNumQst (const char *Field,const char *Label, static void Tst_ShowFormAnswerTypes (const struct Tst_AnswerTypes *AnswerTypes); static void Tst_GetQuestions (struct Tst_Test *Test,MYSQL_RES **mysql_res); static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, - struct TstRes_Result *Result); -static void Tst_GenerateChoiceIndexesDependingOnShuffle (struct TstRes_Result *Result, - unsigned NumQst, - bool Shuffle); + struct TstPrn_Print *Print); static void Tst_ListOneQstToEdit (struct Tst_Test *Test); static void Tst_ListOneOrMoreQuestionsForEdition (struct Tst_Test *Test, @@ -196,28 +193,28 @@ static void Tst_ListOneOrMoreQuestionsForSelectionForGame (struct Gam_Games *Gam static void Tst_WriteQuestionRowForSelection (unsigned NumQst, struct Tst_Question *Question); -static void Tst_WriteAnswersSeeing (const struct TstRes_Result *Result, +static void Tst_WriteAnswersSeeing (const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question); static void Tst_WriteIntAnsListing (const struct Tst_Question *Question); -static void Tst_WriteIntAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteIntAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst); static void Tst_WriteFloatAnsEdit (const struct Tst_Question *Question); -static void Tst_WriteFloatAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteFloatAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst); static void Tst_WriteTFAnsListing (const struct Tst_Question *Question); -static void Tst_WriteTFAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteTFAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst); static void Tst_WriteChoiceAnsListing (const struct Tst_Question *Question); -static void Tst_WriteChoiceAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question); -static void Tst_WriteTextAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteTextAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst); static void Tst_WriteParamQstCod (unsigned NumQst,long QstCod); @@ -446,7 +443,7 @@ void Tst_ShowNewTest (void) { extern const char *Txt_No_questions_found_matching_your_search_criteria; struct Tst_Test Test; - struct TstRes_Result Exam; + struct TstPrn_Print Print; unsigned NumExamsGeneratedByMe; /***** Create test *****/ @@ -461,21 +458,21 @@ void Tst_ShowNewTest (void) if (Tst_GetParamsTst (&Test,Tst_SHOW_TEST_TO_ANSWER)) // Get parameters from form { /***** Get questions *****/ - TstRes_ResetResult (&Exam); - Tst_GetQuestionsForNewTestFromDB (&Test,&Exam); - if (Exam.NumQsts) + TstPrn_ResetResult (&Print); + Tst_GetQuestionsForNewTestFromDB (&Test,&Print); + if (Print.NumQsts) { /***** Increase number of exams generated (answered or not) by me *****/ Tst_IncreaseMyNumAccessTst (); NumExamsGeneratedByMe = Tst_GetNumExamsGeneratedByMe (); /***** Create new test exam in database *****/ - TstRes_CreateExamInDB (&Exam); - TstRes_ComputeScoresAndStoreExamQuestions (&Exam, + TstPrn_CreateExamInDB (&Print); + TstPrn_ComputeScoresAndStoreExamQuestions (&Print, false); // Don't update question score /***** Show test exam to be answered *****/ - Tst_ShowTestExamToFillIt (&Exam,NumExamsGeneratedByMe,Tst_REQUEST); + Tst_ShowTestExamToFillIt (&Print,NumExamsGeneratedByMe,Tst_REQUEST); /***** Update date-time of my next allowed access to test *****/ if (Gbl.Usrs.Me.Role.Logged == Rol_STD) @@ -523,47 +520,48 @@ static void Tst_PutCheckBoxAllowTeachers (bool AllowTeachers) void Tst_ReceiveTestDraft (void) { extern const char *Txt_The_test_X_has_already_been_assessed_previously; + extern const char *Txt_Please_review_your_answers_before_submitting_the_exam; unsigned NumTst; - struct TstRes_Result Result; + struct TstPrn_Print Print; /***** Read test configuration from database *****/ TstCfg_GetConfigFromDB (); /***** Get basic parameters of the exam *****/ /* Get test exam code from form */ - TstRes_ResetResult (&Result); - if ((Result.ResCod = TstRes_GetParamExaCod ()) <= 0) + TstPrn_ResetResult (&Print); + if ((Print.PrnCod = TstPrn_GetParamExaCod ()) <= 0) Lay_ShowErrorAndExit ("Wrong test exam."); /* Get number of this test from form */ NumTst = Tst_GetParamNumTst (); /***** Get test exam from database *****/ - TstRes_GetExamDataByExaCod (&Result); + TstPrn_GetExamDataByExaCod (&Print); /****** Get test status in database for this session-course-num.test *****/ - if (Result.Sent) + if (Print.Sent) Ale_ShowAlert (Ale_WARNING,Txt_The_test_X_has_already_been_assessed_previously, NumTst); - else // Exam not yet sent + else // Print not yet sent { /***** Get test exam questions from database *****/ - TstRes_GetExamQuestionsFromDB (&Result); + TstPrn_GetExamQuestionsFromDB (&Print); /***** Get answers from form to assess a test *****/ - Tst_GetAnswersFromForm (&Result); + Tst_GetAnswersFromForm (&Print); /***** Update test exam in database *****/ - TstRes_ComputeScoresAndStoreExamQuestions (&Result, + TstPrn_ComputeScoresAndStoreExamQuestions (&Print, false); // Don't update question score - TstRes_UpdateExamInDB (&Result); + TstPrn_UpdateExamInDB (&Print); /***** Show question and button to send the test *****/ /* Start alert */ - Ale_ShowAlert (Ale_WARNING,"Por favor, revise sus respuestas antes de enviar el examen:"); // TODO: Need translation!!! + Ale_ShowAlert (Ale_WARNING,Txt_Please_review_your_answers_before_submitting_the_exam); /* Show the same test exam to be answered */ - Tst_ShowTestExamToFillIt (&Result,NumTst,Tst_CONFIRM); + Tst_ShowTestExamToFillIt (&Print,NumTst,Tst_CONFIRM); } } @@ -580,43 +578,43 @@ void Tst_AssessTest (void) extern const char *Txt_Grade; extern const char *Txt_The_test_X_has_already_been_assessed_previously; unsigned NumTst; - struct TstRes_Result Result; + struct TstPrn_Print Print; /***** Read test configuration from database *****/ TstCfg_GetConfigFromDB (); /***** Get basic parameters of the exam *****/ /* Get test exam code from form */ - TstRes_ResetResult (&Result); - if ((Result.ResCod = TstRes_GetParamExaCod ()) <= 0) + TstPrn_ResetResult (&Print); + if ((Print.PrnCod = TstPrn_GetParamExaCod ()) <= 0) Lay_ShowErrorAndExit ("Wrong test exam."); /* Get number of this test from form */ NumTst = Tst_GetParamNumTst (); /***** Get test exam from database *****/ - TstRes_GetExamDataByExaCod (&Result); + TstPrn_GetExamDataByExaCod (&Print); /****** Get test status in database for this session-course-num.test *****/ - if (Result.Sent) + if (Print.Sent) Ale_ShowAlert (Ale_WARNING,Txt_The_test_X_has_already_been_assessed_previously, NumTst); - else // Exam not yet sent + else // Print not yet sent { /***** Get test exam questions from database *****/ - TstRes_GetExamQuestionsFromDB (&Result); + TstPrn_GetExamQuestionsFromDB (&Print); /***** Get answers from form to assess a test *****/ - Tst_GetAnswersFromForm (&Result); + Tst_GetAnswersFromForm (&Print); /***** Get if test exam will be visible by teachers *****/ - Result.Sent = true; // The exam has been finished and sent by student - Result.AllowTeachers = Par_GetParToBool ("AllowTchs"); + Print.Sent = true; // The exam has been finished and sent by student + Print.AllowTeachers = Par_GetParToBool ("AllowTchs"); /***** Update test exam in database *****/ - TstRes_ComputeScoresAndStoreExamQuestions (&Result, + TstPrn_ComputeScoresAndStoreExamQuestions (&Print, Gbl.Usrs.Me.Role.Logged == Rol_STD); // Update question score? - TstRes_UpdateExamInDB (&Result); + TstPrn_UpdateExamInDB (&Print); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Test_result, @@ -636,19 +634,19 @@ void Tst_AssessTest (void) } /***** Write answers and solutions *****/ - TstRes_ShowExamAfterAssess (&Result); + TstPrn_ShowExamAfterAssess (&Print); /***** Write total score and grade *****/ if (TstVis_IsVisibleTotalScore (TstCfg_GetConfigVisibility ())) { HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\""); HTM_TxtColonNBSP (Txt_Score); - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); HTM_BR (); HTM_TxtColonNBSP (Txt_Grade); - TstRes_ComputeAndShowGrade (Result.NumQsts, - Result.Score, - TstRes_SCORE_MAX); + TstPrn_ComputeAndShowGrade (Print.NumQsts, + Print.Score, + TstPrn_SCORE_MAX); HTM_DIV_End (); } @@ -661,22 +659,22 @@ void Tst_AssessTest (void) /*********** Get questions and answers from form to assess a test ************/ /*****************************************************************************/ -static void Tst_GetAnswersFromForm (struct TstRes_Result *Result) +static void Tst_GetAnswersFromForm (struct TstPrn_Print *Print) { unsigned NumQst; char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" /***** Loop for every question getting user's answers *****/ for (NumQst = 0; - NumQst < Result->NumQsts; + NumQst < Print->NumQsts; NumQst++) { /* Get answers selected by user for this question */ snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - Par_GetParMultiToText (StrAns,Result->Questions[NumQst].StrAnswers, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); /* If answer type == T/F ==> " ", "T", "F"; if choice ==> "0", "2",... */ + Par_GetParMultiToText (StrAns,Print->PrintedQuestions[NumQst].StrAnswers, + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); /* If answer type == T/F ==> " ", "T", "F"; if choice ==> "0", "2",... */ } } @@ -788,7 +786,7 @@ static unsigned Tst_GetNumExamsGeneratedByMe (void) /************************ Show a test exam to be answered ********************/ /*****************************************************************************/ -static void Tst_ShowTestExamToFillIt (struct TstRes_Result *Result, +static void Tst_ShowTestExamToFillIt (struct TstPrn_Print *Print, unsigned NumExamsGeneratedByMe, Tst_RequestOrConfirm_t RequestOrConfirm) { @@ -813,11 +811,11 @@ static void Tst_ShowTestExamToFillIt (struct TstRes_Result *Result, Gbl.Hierarchy.Deg.DegCod, Gbl.Hierarchy.Crs.CrsCod); - if (Result->NumQsts) + if (Print->NumQsts) { /***** Begin form *****/ Frm_StartForm (Action[RequestOrConfirm]); - TstRes_PutParamExaCod (Result->ResCod); + TstPrn_PutParamExaCod (Print->PrnCod); Par_PutHiddenParamUnsigned (NULL,"NumTst",NumExamsGeneratedByMe); /***** Begin table *****/ @@ -825,21 +823,21 @@ static void Tst_ShowTestExamToFillIt (struct TstRes_Result *Result, /***** Write one row for each question *****/ for (NumQst = 0; - NumQst < Result->NumQsts; + NumQst < Print->NumQsts; NumQst++) { Gbl.RowEvenOdd = NumQst % 2; /* Create test question */ Tst_QstConstructor (&Question); - Question.QstCod = Result->Questions[NumQst].QstCod; + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; /* Show question */ if (!Tst_GetQstDataFromDB (&Question)) // Question exists Lay_ShowErrorAndExit ("Wrong question."); /* Write question and answers */ - Tst_WriteQstAndAnsSeeing (Result,NumQst,&Question); + Tst_WriteQstAndAnsSeeing (Print,NumQst,&Question); /* Destroy test question */ Tst_QstDestructor (&Question); @@ -903,7 +901,7 @@ void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res) /********** Write a row of a test, with one question and its answer **********/ /*****************************************************************************/ -static void Tst_WriteQstAndAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteQstAndAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question) { @@ -931,7 +929,7 @@ static void Tst_WriteQstAndAnsSeeing (const struct TstRes_Result *Result, "TEST_MED_SHOW"); /* Answers */ - Tst_WriteAnswersSeeing (Result,NumQst,Question); + Tst_WriteAnswersSeeing (Print,NumQst,Question); HTM_TD_End (); @@ -2512,7 +2510,7 @@ static void Tst_GetQuestions (struct Tst_Test *Test,MYSQL_RES **mysql_res) /*****************************************************************************/ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, - struct TstRes_Result *Result) + struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -2625,14 +2623,14 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, Lay_ShowAlert (Lay_INFO,Query); */ /* Make the query */ - Result->NumQsts = + Print->NumQsts = Test->NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get questions", "%s", Query); /***** Get questions and answers from database *****/ for (NumQst = 0; - NumQst < Result->NumQsts; + NumQst < Print->NumQsts; NumQst++) { /* Get question row */ @@ -2644,7 +2642,7 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, */ /* Get question code (row[0]) */ - if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + if ((Print->PrintedQuestions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); /* Get answer type (row[1]) */ @@ -2660,13 +2658,13 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, case Tst_ANS_FLOAT: case Tst_ANS_TRUE_FALSE: case Tst_ANS_TEXT: - Result->Questions[NumQst].StrIndexes[0] = '\0'; + Print->PrintedQuestions[NumQst].StrIndexes[0] = '\0'; break; case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE: /* If answer type is unique or multiple option, generate indexes of answers depending on shuffle */ - Tst_GenerateChoiceIndexesDependingOnShuffle (Result,NumQst,Shuffle); + Tst_GenerateChoiceIndexesDependingOnShuffle (&Print->PrintedQuestions[NumQst],Shuffle); break; default: break; @@ -2676,20 +2674,19 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test, Initially user has not answered the question ==> initially all the answers will be blank. If the user does not confirm the submission of their exam ==> ==> the exam may be half filled ==> the answers displayed will be those selected by the user. */ - Result->Questions[NumQst].StrAnswers[0] = '\0'; + Print->PrintedQuestions[NumQst].StrAnswers[0] = '\0'; } /***** Get if test exam will be visible by teachers *****/ - Result->AllowTeachers = Par_GetParToBool ("AllowTchs"); + Print->AllowTeachers = Par_GetParToBool ("AllowTchs"); } /*****************************************************************************/ /********* Get single or multiple choice answer when seeing a test ***********/ /*****************************************************************************/ -static void Tst_GenerateChoiceIndexesDependingOnShuffle (struct TstRes_Result *Result, - unsigned NumQst, - bool Shuffle) +void Tst_GenerateChoiceIndexesDependingOnShuffle (struct TstPrn_PrintedQuestion *PrintedQuestion, + bool Shuffle) { extern const char *Par_SEPARATOR_PARAM_MULTIPLE; struct Tst_Question Question; @@ -2702,7 +2699,7 @@ static void Tst_GenerateChoiceIndexesDependingOnShuffle (struct TstRes_Result *R /***** Create test question *****/ Tst_QstConstructor (&Question); - Question.QstCod = Result->Questions[NumQst].QstCod; + Question.QstCod = PrintedQuestion->QstCod; /***** Get answers of question from database *****/ Tst_GetAnswersQst (&Question,&mysql_res,Shuffle); @@ -2739,8 +2736,8 @@ static void Tst_GenerateChoiceIndexesDependingOnShuffle (struct TstRes_Result *R snprintf (StrInd,sizeof (StrInd),"%u",Index); else snprintf (StrInd,sizeof (StrInd),"%s%u",Par_SEPARATOR_PARAM_MULTIPLE,Index); - Str_Concat (Result->Questions[NumQst].StrIndexes,StrInd, - TstRes_MAX_BYTES_INDEXES_ONE_QST); + Str_Concat (PrintedQuestion->StrIndexes,StrInd, + TstPrn_MAX_BYTES_INDEXES_ONE_QST); } /***** Free structure that stores the query result *****/ @@ -3360,7 +3357,7 @@ void Tst_WriteAnswersListing (const struct Tst_Question *Question) /************** Write answers of a question when seeing a test ***************/ /*****************************************************************************/ -static void Tst_WriteAnswersSeeing (const struct TstRes_Result *Result, +static void Tst_WriteAnswersSeeing (const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question) { @@ -3368,20 +3365,20 @@ static void Tst_WriteAnswersSeeing (const struct TstRes_Result *Result, switch (Question->Answer.Type) { case Tst_ANS_INT: - Tst_WriteIntAnsSeeing (Result,NumQst); + Tst_WriteIntAnsSeeing (Print,NumQst); break; case Tst_ANS_FLOAT: - Tst_WriteFloatAnsSeeing (Result,NumQst); + Tst_WriteFloatAnsSeeing (Print,NumQst); break; case Tst_ANS_TRUE_FALSE: - Tst_WriteTFAnsSeeing (Result,NumQst); + Tst_WriteTFAnsSeeing (Print,NumQst); break; case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE: - Tst_WriteChoiceAnsSeeing (Result,NumQst,Question); + Tst_WriteChoiceAnsSeeing (Print,NumQst,Question); break; case Tst_ANS_TEXT: - Tst_WriteTextAnsSeeing (Result,NumQst); + Tst_WriteTextAnsSeeing (Print,NumQst); break; default: break; @@ -3417,7 +3414,7 @@ static void Tst_WriteIntAnsListing (const struct Tst_Question *Question) /****************** Write integer answer when seeing a test ******************/ /*****************************************************************************/ -static void Tst_WriteIntAnsSeeing (const struct TstRes_Result *Exam, +static void Tst_WriteIntAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst) { char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" @@ -3426,7 +3423,7 @@ static void Tst_WriteIntAnsSeeing (const struct TstRes_Result *Exam, snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - HTM_INPUT_TEXT (StrAns,11,Exam->Questions[NumQst].StrAnswers, + HTM_INPUT_TEXT (StrAns,11,Print->PrintedQuestions[NumQst].StrAnswers, HTM_DONT_SUBMIT_ON_CHANGE, "size=\"11\""); } @@ -3450,7 +3447,7 @@ static void Tst_WriteFloatAnsEdit (const struct Tst_Question *Question) /****************** Write float answer when seeing a test ********************/ /*****************************************************************************/ -static void Tst_WriteFloatAnsSeeing (const struct TstRes_Result *Exam, +static void Tst_WriteFloatAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst) { char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" @@ -3459,7 +3456,7 @@ static void Tst_WriteFloatAnsSeeing (const struct TstRes_Result *Exam, snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,Exam->Questions[NumQst].StrAnswers, + HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,Print->PrintedQuestions[NumQst].StrAnswers, HTM_DONT_SUBMIT_ON_CHANGE, "size=\"11\""); } @@ -3482,7 +3479,7 @@ static void Tst_WriteTFAnsListing (const struct Tst_Question *Question) /************** Write false / true answer when seeing a test ****************/ /*****************************************************************************/ -static void Tst_WriteTFAnsSeeing (const struct TstRes_Result *Exam, +static void Tst_WriteTFAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst) { extern const char *Txt_TF_QST[2]; @@ -3493,9 +3490,9 @@ static void Tst_WriteTFAnsSeeing (const struct TstRes_Result *Exam, ==> the exam may be half filled ==> the answers displayed will be those selected by the user. */ HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, "name=\"Ans%010u\"",NumQst); - HTM_OPTION (HTM_Type_STRING,"" ,Exam->Questions[NumQst].StrAnswers[0] == '\0',false," "); - HTM_OPTION (HTM_Type_STRING,"T",Exam->Questions[NumQst].StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]); - HTM_OPTION (HTM_Type_STRING,"F",Exam->Questions[NumQst].StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]); + HTM_OPTION (HTM_Type_STRING,"" ,Print->PrintedQuestions[NumQst].StrAnswers[0] == '\0',false," "); + HTM_OPTION (HTM_Type_STRING,"T",Print->PrintedQuestions[NumQst].StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]); + HTM_OPTION (HTM_Type_STRING,"F",Print->PrintedQuestions[NumQst].StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]); HTM_SELECT_End (); } @@ -3615,7 +3612,7 @@ static void Tst_WriteChoiceAnsListing (const struct Tst_Question *Question) /******** Write single or multiple choice answer when seeing a test **********/ /*****************************************************************************/ -static void Tst_WriteChoiceAnsSeeing (const struct TstRes_Result *Exam, +static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question) { @@ -3625,10 +3622,10 @@ static void Tst_WriteChoiceAnsSeeing (const struct TstRes_Result *Exam, char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" /***** Get indexes for this question from string *****/ - TstRes_GetIndexesFromStr (Exam->Questions[NumQst].StrIndexes,Indexes); + TstPrn_GetIndexesFromStr (Print->PrintedQuestions[NumQst].StrIndexes,Indexes); /***** Get the user's answers for this question from string *****/ - TstRes_GetAnswersFromStr (Exam->Questions[NumQst].StrAnswers,UsrAnswers); + TstPrn_GetAnswersFromStr (Print->PrintedQuestions[NumQst].StrAnswers,UsrAnswers); /***** Begin table *****/ HTM_TABLE_BeginPadding (2); @@ -3756,7 +3753,7 @@ void Tst_GetChoiceAns (struct Tst_Question *Question,MYSQL_RES *mysql_res) /******************** Write text answer when seeing a test *******************/ /*****************************************************************************/ -static void Tst_WriteTextAnsSeeing (const struct TstRes_Result *Result, +static void Tst_WriteTextAnsSeeing (const struct TstPrn_Print *Print, unsigned NumQst) { char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" @@ -3765,7 +3762,7 @@ static void Tst_WriteTextAnsSeeing (const struct TstRes_Result *Result, snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - HTM_INPUT_TEXT (StrAns,TstRes_MAX_CHARS_ANSWERS_ONE_QST,Result->Questions[NumQst].StrAnswers, + HTM_INPUT_TEXT (StrAns,TstPrn_MAX_CHARS_ANSWERS_ONE_QST,Print->PrintedQuestions[NumQst].StrAnswers, HTM_DONT_SUBMIT_ON_CHANGE, "size=\"40\""); } @@ -5052,7 +5049,7 @@ static void Tst_GetQstFromForm (struct Tst_Question *Question) char TagStr[6 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char AnsStr[6 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char FbStr[5 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrMultiAns[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char StrMultiAns[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; char TF[1 + 1]; // (T)rue or (F)alse const char *Ptr; unsigned NumCorrectAns; @@ -5204,7 +5201,7 @@ static void Tst_GetQstFromForm (struct Tst_Question *Question) } else if (Question->Answer.Type == Tst_ANS_MULTIPLE_CHOICE) { - Par_GetParMultiToText ("AnsMulti",StrMultiAns,TstRes_MAX_BYTES_ANSWERS_ONE_QST); + Par_GetParMultiToText ("AnsMulti",StrMultiAns,TstPrn_MAX_BYTES_ANSWERS_ONE_QST); Ptr = StrMultiAns; while (*Ptr) { diff --git a/swad_test.h b/swad_test.h index 1838dd38..cdacf62d 100644 --- a/swad_test.h +++ b/swad_test.h @@ -31,48 +31,22 @@ #include "swad_game.h" #include "swad_media.h" #include "swad_test_config.h" +#include "swad_test_print.h" +#include "swad_test_type.h" /*****************************************************************************/ /***************************** Public constants ******************************/ /*****************************************************************************/ -#define Tst_MAX_TAGS_PER_QUESTION 5 - -#define Tst_MAX_CHARS_TAG (128 - 1) // 127 -#define Tst_MAX_BYTES_TAG ((Tst_MAX_CHARS_TAG + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 - #define Tst_MAX_CHARS_ANSWER_OR_FEEDBACK (1024 - 1) // 1023 #define Tst_MAX_BYTES_ANSWER_OR_FEEDBACK ((Tst_MAX_CHARS_ANSWER_OR_FEEDBACK + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 16383 #define Tst_MAX_BYTES_ANSWER_TYPE 32 -#define Tst_MAX_OPTIONS_PER_QUESTION 10 - /*****************************************************************************/ /******************************* Public types ********************************/ /*****************************************************************************/ -struct Tst_Tags - { - unsigned Num; - bool All; - char *List; - char Txt[Tst_MAX_TAGS_PER_QUESTION][Tst_MAX_BYTES_TAG + 1]; - }; - -#define Tst_NUM_ANS_TYPES 6 -#define Tst_MAX_BYTES_LIST_ANSWER_TYPES (Tst_NUM_ANS_TYPES * (Cns_MAX_DECIMAL_DIGITS_UINT + 1)) -typedef enum - { - Tst_ANS_INT = 0, - Tst_ANS_FLOAT = 1, - Tst_ANS_TRUE_FALSE = 2, - Tst_ANS_UNIQUE_CHOICE = 3, - Tst_ANS_MULTIPLE_CHOICE = 4, - Tst_ANS_TEXT = 5, - Tst_ANS_ALL = 6, // All/any type of answer - } Tst_AnswerType_t; - struct Tst_AnswerTypes { bool All; @@ -90,35 +64,6 @@ typedef enum } Tst_QuestionsOrder_t; #define Tst_DEFAULT_ORDER Tst_ORDER_STEM -struct Tst_Question - { - long QstCod; - struct Tst_Tags Tags; - time_t EditTime; - char *Stem; - char *Feedback; - struct Media Media; - struct - { - Tst_AnswerType_t Type; - unsigned NumOptions; - bool Shuffle; - char TF; - struct - { - bool Correct; - char *Text; - char *Feedback; - struct Media Media; - } Options[Tst_MAX_OPTIONS_PER_QUESTION]; - long Integer; - double FloatingPoint[2]; - } Answer; - unsigned long NumHits; - unsigned long NumHitsNotBlank; - double Score; - }; - struct Tst_Test { struct Tst_Tags Tags; // Selected tags @@ -176,6 +121,10 @@ void Tst_RequestSelectTestsForGame (struct Gam_Games *Games); void Tst_ListQuestionsToEdit (void); void Tst_ListQuestionsToSelectForSet (struct Exa_Exams *Exams); void Tst_ListQuestionsToSelectForGame (struct Gam_Games *Games); + +void Tst_GenerateChoiceIndexesDependingOnShuffle (struct TstPrn_PrintedQuestion *PrintedQuestion, + bool Shuffle); + void Tst_WriteParamEditQst (const struct Tst_Test *Test); unsigned Tst_GetNumAnswersQst (long QstCod); diff --git a/swad_test_exam.c b/swad_test_print.c similarity index 78% rename from swad_test_exam.c rename to swad_test_print.c index ef0d3ea8..65afc250 100644 --- a/swad_test_exam.c +++ b/swad_test_print.c @@ -1,4 +1,4 @@ -// swad_test_exam.c: test exams made by users +// swad_test_print.c: test exam prints made by users /* SWAD (Shared Workspace At a Distance), @@ -40,7 +40,7 @@ #include "swad_ID.h" #include "swad_photo.h" #include "swad_test.h" -#include "swad_test_exam.h" +#include "swad_test_print.h" #include "swad_test_visibility.h" #include "swad_user.h" @@ -70,117 +70,117 @@ extern struct Globals Gbl; /***************************** Private prototypes ****************************/ /*****************************************************************************/ -static void TstRes_ResetExamExceptExaCod (struct TstRes_Result *Result); +static void TstPrn_ResetExamExceptExaCod (struct TstPrn_Print *Print); -static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, - struct TstRes_Result *Result, +static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat, + struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility); -static void TstRes_ComputeAnswerScore (struct TstRes_Result *Result, +static void TstPrn_ComputeAnswerScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question); -static void TstRes_ComputeIntAnsScore (struct TstRes_Result *Result, +static void TstPrn_ComputeIntAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question); -static void TstRes_GetCorrectIntAnswerFromDB (struct Tst_Question *Question); -static void TstRes_ComputeFloatAnsScore (struct TstRes_Result *Result, +static void TstPrn_GetCorrectIntAnswerFromDB (struct Tst_Question *Question); +static void TstPrn_ComputeFloatAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question); -static void TstRes_GetCorrectFloatAnswerFromDB (struct Tst_Question *Question); -static void TstRes_ComputeTFAnsScore (struct TstRes_Result *Result, +static void TstPrn_GetCorrectFloatAnswerFromDB (struct Tst_Question *Question); +static void TstPrn_ComputeTFAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question); -static void TstRes_GetCorrectTFAnswerFromDB (struct Tst_Question *Question); -static void TstRes_GetCorrectChoiceAnswerFromDB (struct Tst_Question *Question); +static void TstPrn_GetCorrectTFAnswerFromDB (struct Tst_Question *Question); +static void TstPrn_GetCorrectChoiceAnswerFromDB (struct Tst_Question *Question); -static void TstRes_ComputeScoreQst (struct TstRes_Result *Result, +static void TstPrn_ComputeScoreQst (struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION], // Indexes of all answers of this question bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION]); -static void TstRes_ComputeTextAnsScore (struct TstRes_Result *Result, +static void TstPrn_ComputeTextAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question); -static void TstRes_GetCorrectTextAnswerFromDB (struct Tst_Question *Question); +static void TstPrn_GetCorrectTextAnswerFromDB (struct Tst_Question *Question); -static void TstRes_WriteAnswersExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteAnswersExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility); -static void TstRes_WriteIntAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteIntAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Visibility); -static void TstRes_WriteFloatAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteFloatAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Visibility); -static void TstRes_WriteTFAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteTFAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Visibility); -static void TstRes_WriteChoiceAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteChoiceAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility); -static void TstRes_WriteTextAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteTextAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility); -static void TstRes_WriteHeadUserCorrect (struct UsrData *UsrDat); +static void TstPrn_WriteHeadUserCorrect (struct UsrData *UsrDat); -static void TstRes_StoreOneExamQstInDB (const struct TstRes_Result *Result, +static void TstPrn_StoreOneExamQstInDB (const struct TstPrn_Print *Print, unsigned NumQst); -static void Tst_UpdateQstScoreInDB (const struct TstRes_Result *Result,unsigned NumQst); +static void Tst_UpdateQstScoreInDB (const struct TstPrn_Print *Print,unsigned NumQst); -static void TstRes_PutFormToSelectUsrsToViewUsrsExams (__attribute__((unused)) void *Args); +static void TstPrn_PutFormToSelectUsrsToViewUsrsExams (__attribute__((unused)) void *Args); -static void TstRes_ShowUsrsExams (__attribute__((unused)) void *Args); -static void TstRes_ShowHeaderExams (void); -static void TstRes_ShowExams (struct UsrData *UsrDat); -static void TstRes_ShowExamsSummaryRow (bool ItsMe, +static void TstPrn_ShowUsrsExams (__attribute__((unused)) void *Args); +static void TstPrn_ShowHeaderExams (void); +static void TstPrn_ShowExams (struct UsrData *UsrDat); +static void TstPrn_ShowExamsSummaryRow (bool ItsMe, unsigned NumExams, unsigned NumTotalQsts, unsigned NumTotalQstsNotBlank, double TotalScoreOfAllTests); -static void TstRes_ShowTagsPresentInAnExam (long ResCod); +static void TstPrn_ShowTagsPresentInAnExam (long ResCod); /*****************************************************************************/ /******************************** Reset exam *********************************/ /*****************************************************************************/ -void TstRes_ResetResult (struct TstRes_Result *Result) +void TstPrn_ResetResult (struct TstPrn_Print *Print) { - Result->ResCod = -1L; - TstRes_ResetExamExceptExaCod (Result); + Print->PrnCod = -1L; + TstPrn_ResetExamExceptExaCod (Print); } -static void TstRes_ResetExamExceptExaCod (struct TstRes_Result *Result) +static void TstPrn_ResetExamExceptExaCod (struct TstPrn_Print *Print) { - Result->TimeUTC[Dat_START_TIME] = - Result->TimeUTC[Dat_END_TIME ] = (time_t) 0; - Result->NumQsts = - Result->NumQstsNotBlank = 0; - Result->Sent = false; // After creating an exam, it's not sent - Result->AllowTeachers = false; // Teachers can't seen the exam if student don't allow it - Result->Score = 0.0; + Print->TimeUTC[Dat_START_TIME] = + Print->TimeUTC[Dat_END_TIME ] = (time_t) 0; + Print->NumQsts = + Print->NumQstsNotBlank = 0; + Print->Sent = false; // After creating an exam, it's not sent + Print->AllowTeachers = false; // Teachers can't seen the exam if student don't allow it + Print->Score = 0.0; } /*****************************************************************************/ /***************** Create new blank test exam in database ********************/ /*****************************************************************************/ -void TstRes_CreateExamInDB (struct TstRes_Result *Exam) +void TstPrn_CreateExamInDB (struct TstPrn_Print *Print) { /***** Insert new test exam into table *****/ - Exam->ResCod = + Print->PrnCod = DB_QueryINSERTandReturnCode ("can not create new test exam", "INSERT INTO tst_exams" " (CrsCod,UsrCod,StartTime,EndTime,NumQsts," @@ -190,14 +190,14 @@ void TstRes_CreateExamInDB (struct TstRes_Result *Exam) "'N','N',0)", Gbl.Hierarchy.Crs.CrsCod, Gbl.Usrs.Me.UsrDat.UsrCod, - Exam->NumQsts); + Print->NumQsts); } /*****************************************************************************/ /********************** Update test exam in database *************************/ /*****************************************************************************/ -void TstRes_UpdateExamInDB (const struct TstRes_Result *Exam) +void TstPrn_UpdateExamInDB (const struct TstPrn_Print *Print) { /***** Update score in test exam *****/ Str_SetDecimalPointToUS (); // To print the floating point as a dot @@ -210,13 +210,13 @@ void TstRes_UpdateExamInDB (const struct TstRes_Result *Exam) "Score='%.15lg'" " WHERE ExaCod=%ld" " AND CrsCod=%ld AND UsrCod=%ld", // Extra checks - Exam->NumQstsNotBlank, - Exam->Sent ? 'Y' : - 'N', - Exam->AllowTeachers ? 'Y' : - 'N', - Exam->Score, - Exam->ResCod, + Print->NumQstsNotBlank, + Print->Sent ? 'Y' : + 'N', + Print->AllowTeachers ? 'Y' : + 'N', + Print->Score, + Print->PrnCod, Gbl.Hierarchy.Crs.CrsCod, Gbl.Usrs.Me.UsrDat.UsrCod); Str_SetDecimalPointToLocal (); // Return to local system @@ -226,7 +226,7 @@ void TstRes_UpdateExamInDB (const struct TstRes_Result *Exam) /********************* Show test exam after assessing it *********************/ /*****************************************************************************/ -void TstRes_ShowExamAfterAssess (struct TstRes_Result *Result) +void TstPrn_ShowExamAfterAssess (struct TstPrn_Print *Print) { unsigned NumQst; struct Tst_Question Question; @@ -235,39 +235,39 @@ void TstRes_ShowExamAfterAssess (struct TstRes_Result *Result) HTM_TABLE_BeginWideMarginPadding (10); /***** Initialize score and number of questions not blank *****/ - Result->NumQstsNotBlank = 0; - Result->Score = 0.0; + Print->NumQstsNotBlank = 0; + Print->Score = 0.0; for (NumQst = 0; - NumQst < Result->NumQsts; + NumQst < Print->NumQsts; NumQst++) { Gbl.RowEvenOdd = NumQst % 2; /***** Create test question *****/ Tst_QstConstructor (&Question); - Question.QstCod = Result->Questions[NumQst].QstCod; + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; /***** Get question data *****/ if (Tst_GetQstDataFromDB (&Question)) // Question exists { /***** Write question and answers *****/ - TstRes_WriteQstAndAnsExam (&Gbl.Usrs.Me.UsrDat, - Result,NumQst, + TstPrn_WriteQstAndAnsExam (&Gbl.Usrs.Me.UsrDat, + Print,NumQst, &Question, TstCfg_GetConfigVisibility ()); /***** Store test exam question in database *****/ - TstRes_StoreOneExamQstInDB (Result,NumQst); + TstPrn_StoreOneExamQstInDB (Print,NumQst); /***** Compute total score *****/ - Result->Score += Result->Questions[NumQst].Score; - if (Result->Questions[NumQst].AnswerIsNotBlank) - Result->NumQstsNotBlank++; + Print->Score += Print->PrintedQuestions[NumQst].Score; + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) + Print->NumQstsNotBlank++; /***** Update the number of accesses and the score of this question *****/ if (Gbl.Usrs.Me.Role.Logged == Rol_STD) - Tst_UpdateQstScoreInDB (Result,NumQst); + Tst_UpdateQstScoreInDB (Print,NumQst); } /***** Destroy test question *****/ @@ -282,8 +282,8 @@ void TstRes_ShowExamAfterAssess (struct TstRes_Result *Result) /********** Write a row of a test, with one question and its answer **********/ /*****************************************************************************/ -static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, - struct TstRes_Result *Result, +static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat, + struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility) @@ -301,7 +301,7 @@ static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, /***** If this question has been edited later than test time ==> don't show question ****/ if (QuestionExists) - QuestionUneditedAfterExam = (Question->EditTime < Result->TimeUTC[Dat_START_TIME]); + QuestionUneditedAfterExam = (Question->EditTime < Print->TimeUTC[Dat_START_TIME]); else QuestionUneditedAfterExam = false; @@ -331,8 +331,8 @@ static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, "TEST_MED_SHOW"); /* Answers */ - TstRes_ComputeAnswerScore (Result,NumQst,Question); - TstRes_WriteAnswersExam (UsrDat,Result,NumQst,Question,Visibility); + TstPrn_ComputeAnswerScore (Print,NumQst,Question); + TstPrn_WriteAnswersExam (UsrDat,Print,NumQst,Question,Visibility); } else Ale_ShowAlert (Ale_WARNING,Txt_Question_modified); @@ -346,11 +346,11 @@ static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, HTM_DIV_Begin ("class=\"DAT_SMALL LM\""); HTM_TxtColonNBSP (Txt_Score); HTM_SPAN_Begin ("class=\"%s\"", - Result->Questions[NumQst].StrAnswers[0] ? - (Result->Questions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect - "ANS_BAD") : // Wrong - "ANS_0"); // Blank answer - HTM_Double2Decimals (Result->Questions[NumQst].Score); + 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 (); } @@ -370,40 +370,40 @@ static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat, /*********** Compute score of each question and store in database ************/ /*****************************************************************************/ -void TstRes_ComputeScoresAndStoreExamQuestions (struct TstRes_Result *Exam, +void TstPrn_ComputeScoresAndStoreExamQuestions (struct TstPrn_Print *Print, bool UpdateQstScore) { unsigned NumQst; struct Tst_Question Question; /***** Initialize total score *****/ - Exam->Score = 0.0; - Exam->NumQstsNotBlank = 0; + Print->Score = 0.0; + Print->NumQstsNotBlank = 0; /***** Compute and store scores of all questions *****/ for (NumQst = 0; - NumQst < Exam->NumQsts; + NumQst < Print->NumQsts; NumQst++) { /* Compute question score */ Tst_QstConstructor (&Question); - Question.QstCod = Exam->Questions[NumQst].QstCod; + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; Question.Answer.Type = Tst_GetQstAnswerType (Question.QstCod); - TstRes_ComputeAnswerScore (Exam,NumQst,&Question); + TstPrn_ComputeAnswerScore (Print,NumQst,&Question); Tst_QstDestructor (&Question); /* Store test exam question in database */ - TstRes_StoreOneExamQstInDB (Exam, + TstPrn_StoreOneExamQstInDB (Print, NumQst); // 0, 1, 2, 3... /* Accumulate total score */ - Exam->Score += Exam->Questions[NumQst].Score; - if (Exam->Questions[NumQst].AnswerIsNotBlank) - Exam->NumQstsNotBlank++; + Print->Score += Print->PrintedQuestions[NumQst].Score; + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) + Print->NumQstsNotBlank++; /* Update the number of hits and the score of this question in tests database */ if (UpdateQstScore) - Tst_UpdateQstScoreInDB (Exam,NumQst); + Tst_UpdateQstScoreInDB (Print,NumQst); } } @@ -411,7 +411,7 @@ void TstRes_ComputeScoresAndStoreExamQuestions (struct TstRes_Result *Exam, /************* Write answers of a question when assessing a test *************/ /*****************************************************************************/ -static void TstRes_ComputeAnswerScore (struct TstRes_Result *Result, +static void TstPrn_ComputeAnswerScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question) { @@ -419,20 +419,20 @@ static void TstRes_ComputeAnswerScore (struct TstRes_Result *Result, switch (Question->Answer.Type) { case Tst_ANS_INT: - TstRes_ComputeIntAnsScore (Result,NumQst,Question); + TstPrn_ComputeIntAnsScore (Print,NumQst,Question); break; case Tst_ANS_FLOAT: - TstRes_ComputeFloatAnsScore (Result,NumQst,Question); + TstPrn_ComputeFloatAnsScore (Print,NumQst,Question); break; case Tst_ANS_TRUE_FALSE: - TstRes_ComputeTFAnsScore (Result,NumQst,Question); + TstPrn_ComputeTFAnsScore (Print,NumQst,Question); break; case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE: - TstRes_ComputeChoiceAnsScore (Result,NumQst,Question); + TstPrn_ComputeChoiceAnsScore (Print,NumQst,Question); break; case Tst_ANS_TEXT: - TstRes_ComputeTextAnsScore (Result,NumQst,Question); + TstPrn_ComputeTextAnsScore (Print,NumQst,Question); break; default: break; @@ -443,25 +443,25 @@ static void TstRes_ComputeAnswerScore (struct TstRes_Result *Result, /**************** Write integer answer when assessing a test *****************/ /*****************************************************************************/ -static void TstRes_ComputeIntAnsScore (struct TstRes_Result *Result, +static void TstPrn_ComputeIntAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question) { long AnswerUsr; /***** Get the numerical value of the correct answer *****/ - TstRes_GetCorrectIntAnswerFromDB (Question); + TstPrn_GetCorrectIntAnswerFromDB (Question); /***** Compute score *****/ - Result->Questions[NumQst].Score = 0.0; // Default score for blank or wrong answer - Result->Questions[NumQst].AnswerIsNotBlank = (Result->Questions[NumQst].StrAnswers[0] != '\0'); - if (Result->Questions[NumQst].AnswerIsNotBlank) // If user has answered the answer - if (sscanf (Result->Questions[NumQst].StrAnswers,"%ld",&AnswerUsr) == 1) + Print->PrintedQuestions[NumQst].Score = 0.0; // Default score for blank or wrong answer + Print->PrintedQuestions[NumQst].AnswerIsNotBlank = (Print->PrintedQuestions[NumQst].StrAnswers[0] != '\0'); + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) // If user has answered the answer + if (sscanf (Print->PrintedQuestions[NumQst].StrAnswers,"%ld",&AnswerUsr) == 1) if (AnswerUsr == Question->Answer.Integer) // Correct answer - Result->Questions[NumQst].Score = 1.0; + Print->PrintedQuestions[NumQst].Score = 1.0; } -static void TstRes_GetCorrectIntAnswerFromDB (struct Tst_Question *Question) +static void TstPrn_GetCorrectIntAnswerFromDB (struct Tst_Question *Question) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -490,30 +490,30 @@ static void TstRes_GetCorrectIntAnswerFromDB (struct Tst_Question *Question) /***************** Write float answer when assessing a test ******************/ /*****************************************************************************/ -static void TstRes_ComputeFloatAnsScore (struct TstRes_Result *Result, +static void TstPrn_ComputeFloatAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question) { double AnswerUsr; /***** Get the numerical value of the minimum and maximum correct answers *****/ - TstRes_GetCorrectFloatAnswerFromDB (Question); + TstPrn_GetCorrectFloatAnswerFromDB (Question); /***** Compute score *****/ - Result->Questions[NumQst].Score = 0.0; // Default score for blank or wrong answer - Result->Questions[NumQst].AnswerIsNotBlank = (Result->Questions[NumQst].StrAnswers[0] != '\0'); - if (Result->Questions[NumQst].AnswerIsNotBlank) // If user has answered the answer + Print->PrintedQuestions[NumQst].Score = 0.0; // Default score for blank or wrong answer + Print->PrintedQuestions[NumQst].AnswerIsNotBlank = (Print->PrintedQuestions[NumQst].StrAnswers[0] != '\0'); + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) // If user has answered the answer { - AnswerUsr = Str_GetDoubleFromStr (Result->Questions[NumQst].StrAnswers); + AnswerUsr = Str_GetDoubleFromStr (Print->PrintedQuestions[NumQst].StrAnswers); // A bad formatted floating point answer will interpreted as 0.0 - Result->Questions[NumQst].Score = (AnswerUsr >= Question->Answer.FloatingPoint[0] && - AnswerUsr <= Question->Answer.FloatingPoint[1]) ? 1.0 : // If correct (inside the interval) - 0.0; // If wrong (outside the interval) + Print->PrintedQuestions[NumQst].Score = (AnswerUsr >= Question->Answer.FloatingPoint[0] && + AnswerUsr <= Question->Answer.FloatingPoint[1]) ? 1.0 : // If correct (inside the interval) + 0.0; // If wrong (outside the interval) } } -static void TstRes_GetCorrectFloatAnswerFromDB (struct Tst_Question *Question) +static void TstPrn_GetCorrectFloatAnswerFromDB (struct Tst_Question *Question) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -557,23 +557,23 @@ static void TstRes_GetCorrectFloatAnswerFromDB (struct Tst_Question *Question) /************** Write false / true answer when assessing a test **************/ /*****************************************************************************/ -static void TstRes_ComputeTFAnsScore (struct TstRes_Result *Result, +static void TstPrn_ComputeTFAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question) { /***** Get answer true or false *****/ - TstRes_GetCorrectTFAnswerFromDB (Question); + TstPrn_GetCorrectTFAnswerFromDB (Question); /***** Compute score *****/ - Result->Questions[NumQst].AnswerIsNotBlank = (Result->Questions[NumQst].StrAnswers[0] != '\0'); - if (Result->Questions[NumQst].AnswerIsNotBlank) // User has selected T or F - Result->Questions[NumQst].Score = (Result->Questions[NumQst].StrAnswers[0] == Question->Answer.TF) ? 1.0 : // Correct - -1.0; // Wrong + Print->PrintedQuestions[NumQst].AnswerIsNotBlank = (Print->PrintedQuestions[NumQst].StrAnswers[0] != '\0'); + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) // User has selected T or F + Print->PrintedQuestions[NumQst].Score = (Print->PrintedQuestions[NumQst].StrAnswers[0] == Question->Answer.TF) ? 1.0 : // Correct + -1.0; // Wrong else - Result->Questions[NumQst].Score = 0.0; + Print->PrintedQuestions[NumQst].Score = 0.0; } -static void TstRes_GetCorrectTFAnswerFromDB (struct Tst_Question *Question) +static void TstPrn_GetCorrectTFAnswerFromDB (struct Tst_Question *Question) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -601,7 +601,7 @@ static void TstRes_GetCorrectTFAnswerFromDB (struct Tst_Question *Question) /************ Compute score for single or multiple choice answer *************/ /*****************************************************************************/ -void TstRes_ComputeChoiceAnsScore (struct TstRes_Result *Exam, +void TstPrn_ComputeChoiceAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question) { @@ -609,19 +609,19 @@ void TstRes_ComputeChoiceAnsScore (struct TstRes_Result *Exam, bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION]; /***** Get correct options of test question from database *****/ - TstRes_GetCorrectChoiceAnswerFromDB (Question); + TstPrn_GetCorrectChoiceAnswerFromDB (Question); /***** Get indexes for this question from string *****/ - TstRes_GetIndexesFromStr (Exam->Questions[NumQst].StrIndexes,Indexes); + TstPrn_GetIndexesFromStr (Print->PrintedQuestions[NumQst].StrIndexes,Indexes); /***** Get the user's answers for this question from string *****/ - TstRes_GetAnswersFromStr (Exam->Questions[NumQst].StrAnswers,UsrAnswers); + TstPrn_GetAnswersFromStr (Print->PrintedQuestions[NumQst].StrAnswers,UsrAnswers); /***** Compute the total score of this question *****/ - TstRes_ComputeScoreQst (Exam,NumQst,Question,Indexes,UsrAnswers); + TstPrn_ComputeScoreQst (Print,NumQst,Question,Indexes,UsrAnswers); } -static void TstRes_GetCorrectChoiceAnswerFromDB (struct Tst_Question *Question) +static void TstPrn_GetCorrectChoiceAnswerFromDB (struct Tst_Question *Question) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -654,7 +654,7 @@ static void TstRes_GetCorrectChoiceAnswerFromDB (struct Tst_Question *Question) /********************* Get vector of indexes from string *********************/ /*****************************************************************************/ -void TstRes_GetIndexesFromStr (const char StrIndexesOneQst[TstRes_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc. +void TstPrn_GetIndexesFromStr (const char StrIndexesOneQst[TstPrn_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc. unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]) { unsigned NumOpt; @@ -686,7 +686,7 @@ void TstRes_GetIndexesFromStr (const char StrIndexesOneQst[TstRes_MAX_BYTES_INDE /****************** Get vector of user's answers from string *****************/ /*****************************************************************************/ -void TstRes_GetAnswersFromStr (const char StrAnswersOneQst[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1], +void TstPrn_GetAnswersFromStr (const char StrAnswersOneQst[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1], bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION]) { unsigned NumOpt; @@ -721,7 +721,7 @@ void TstRes_GetAnswersFromStr (const char StrAnswersOneQst[TstRes_MAX_BYTES_ANSW /*********************** Compute the score of a question *********************/ /*****************************************************************************/ -static void TstRes_ComputeScoreQst (struct TstRes_Result *Result, +static void TstPrn_ComputeScoreQst (struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION], // Indexes of all answers of this question @@ -752,64 +752,64 @@ static void TstRes_ComputeScoreQst (struct TstRes_Result *Result, } /* The answer is blank? */ - Result->Questions[NumQst].AnswerIsNotBlank = NumAnsGood != 0 || NumAnsBad != 0; - if (Result->Questions[NumQst].AnswerIsNotBlank) + Print->PrintedQuestions[NumQst].AnswerIsNotBlank = NumAnsGood != 0 || NumAnsBad != 0; + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) { /* Compute the score */ if (Question->Answer.Type == Tst_ANS_UNIQUE_CHOICE) { if (NumOptTotInQst >= 2) // It should be 2 options at least - Result->Questions[NumQst].Score = (double) NumAnsGood - - (double) NumAnsBad / (double) (NumOptTotInQst - 1); + Print->PrintedQuestions[NumQst].Score = (double) NumAnsGood - + (double) NumAnsBad / (double) (NumOptTotInQst - 1); else // 0 or 1 options (impossible) - Result->Questions[NumQst].Score = (double) NumAnsGood; + Print->PrintedQuestions[NumQst].Score = (double) NumAnsGood; } else // AnswerType == Tst_ANS_MULTIPLE_CHOICE { if (NumOptCorrInQst) // There are correct options in the question { if (NumOptCorrInQst < NumOptTotInQst) // If there are correct options and wrong options (typical case) - Result->Questions[NumQst].Score = (double) NumAnsGood / (double) NumOptCorrInQst - - (double) NumAnsBad / (double) (NumOptTotInQst - NumOptCorrInQst); + Print->PrintedQuestions[NumQst].Score = (double) NumAnsGood / (double) NumOptCorrInQst - + (double) NumAnsBad / (double) (NumOptTotInQst - NumOptCorrInQst); else // If all options are correct (extrange case) - Result->Questions[NumQst].Score = (double) NumAnsGood / (double) NumOptCorrInQst; + Print->PrintedQuestions[NumQst].Score = (double) NumAnsGood / (double) NumOptCorrInQst; } else { if (NumOptTotInQst) // There are options but none is correct (extrange case) - Result->Questions[NumQst].Score = - (double) NumAnsBad / (double) NumOptTotInQst; + Print->PrintedQuestions[NumQst].Score = - (double) NumAnsBad / (double) NumOptTotInQst; else // There are no options (impossible!) - Result->Questions[NumQst].Score = 0.0; + Print->PrintedQuestions[NumQst].Score = 0.0; } } } else // Answer is blank - Result->Questions[NumQst].Score = 0.0; + Print->PrintedQuestions[NumQst].Score = 0.0; } /*****************************************************************************/ /********************* Compute score for text answer *************************/ /*****************************************************************************/ -static void TstRes_ComputeTextAnsScore (struct TstRes_Result *Result, +static void TstPrn_ComputeTextAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question) { unsigned NumOpt; - char TextAnsUsr[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; - char TextAnsOK[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char TextAnsUsr[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char TextAnsOK[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; /***** Get correct answers for this question from database *****/ - TstRes_GetCorrectTextAnswerFromDB (Question); + TstPrn_GetCorrectTextAnswerFromDB (Question); /***** Compute score *****/ - Result->Questions[NumQst].Score = 0.0; // Default score for blank or wrong answer - Result->Questions[NumQst].AnswerIsNotBlank = (Result->Questions[NumQst].StrAnswers[0] != '\0'); - if (Result->Questions[NumQst].AnswerIsNotBlank) // If user has answered the answer + Print->PrintedQuestions[NumQst].Score = 0.0; // Default score for blank or wrong answer + Print->PrintedQuestions[NumQst].AnswerIsNotBlank = (Print->PrintedQuestions[NumQst].StrAnswers[0] != '\0'); + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) // If user has answered the answer { /* Filter the user answer */ - Str_Copy (TextAnsUsr,Result->Questions[NumQst].StrAnswers, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + Str_Copy (TextAnsUsr,Print->PrintedQuestions[NumQst].StrAnswers, + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); /* In order to compare student answer to stored answer, the text answers are stored avoiding two or more consecurive spaces */ @@ -822,17 +822,17 @@ static void TstRes_ComputeTextAnsScore (struct TstRes_Result *Result, { /* Filter this correct answer */ Str_Copy (TextAnsOK,Question->Answer.Options[NumOpt].Text, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); Str_ConvertToComparable (TextAnsOK); /* Check is user answer is correct */ if (!strcoll (TextAnsUsr,TextAnsOK)) - Result->Questions[NumQst].Score = 1.0; // Correct answer + Print->PrintedQuestions[NumQst].Score = 1.0; // Correct answer } } } -static void TstRes_GetCorrectTextAnswerFromDB (struct Tst_Question *Question) +static void TstPrn_GetCorrectTextAnswerFromDB (struct Tst_Question *Question) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -875,16 +875,16 @@ static void TstRes_GetCorrectTextAnswerFromDB (struct Tst_Question *Question) /************ Compute and show total grade out of maximum grade **************/ /*****************************************************************************/ -void TstRes_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade) +void TstPrn_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade) { - TstRes_ShowGrade (TstRes_ComputeGrade (NumQsts,Score,MaxGrade),MaxGrade); + TstPrn_ShowGrade (TstPrn_ComputeGrade (NumQsts,Score,MaxGrade),MaxGrade); } /*****************************************************************************/ /**************** Compute total grade out of maximum grade *******************/ /*****************************************************************************/ -double TstRes_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade) +double TstPrn_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade) { double MaxScore; double Grade; @@ -905,7 +905,7 @@ double TstRes_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade) /****************** Show total grade out of maximum grade ********************/ /*****************************************************************************/ -void TstRes_ShowGrade (double Grade,double MaxGrade) +void TstPrn_ShowGrade (double Grade,double MaxGrade) { /***** Write grade over maximum grade *****/ HTM_Double2Decimals (Grade); @@ -917,8 +917,8 @@ void TstRes_ShowGrade (double Grade,double MaxGrade) /************* Write answers of a question when assessing a test *************/ /*****************************************************************************/ -static void TstRes_WriteAnswersExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteAnswersExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility) @@ -927,20 +927,20 @@ static void TstRes_WriteAnswersExam (struct UsrData *UsrDat, switch (Question->Answer.Type) { case Tst_ANS_INT: - TstRes_WriteIntAnsExam (UsrDat,Result,NumQst,Question,Visibility); + TstPrn_WriteIntAnsExam (UsrDat,Print,NumQst,Question,Visibility); break; case Tst_ANS_FLOAT: - TstRes_WriteFloatAnsExam (UsrDat,Result,NumQst,Question,Visibility); + TstPrn_WriteFloatAnsExam (UsrDat,Print,NumQst,Question,Visibility); break; case Tst_ANS_TRUE_FALSE: - TstRes_WriteTFAnsExam (UsrDat,Result,NumQst,Question,Visibility); + TstPrn_WriteTFAnsExam (UsrDat,Print,NumQst,Question,Visibility); break; case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE: - TstRes_WriteChoiceAnsExam (UsrDat,Result,NumQst,Question,Visibility); + TstPrn_WriteChoiceAnsExam (UsrDat,Print,NumQst,Question,Visibility); break; case Tst_ANS_TEXT: - TstRes_WriteTextAnsExam (UsrDat,Result,NumQst,Question,Visibility); + TstPrn_WriteTextAnsExam (UsrDat,Print,NumQst,Question,Visibility); break; default: break; @@ -951,8 +951,8 @@ static void TstRes_WriteAnswersExam (struct UsrData *UsrDat, /******************* Write integer answer in a test exam *********************/ /*****************************************************************************/ -static void TstRes_WriteIntAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteIntAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Visibility) @@ -965,15 +965,15 @@ static void TstRes_WriteIntAnsExam (struct UsrData *UsrDat, /***** Header with the title of each column *****/ HTM_TABLE_BeginPadding (2); HTM_TR_Begin (NULL); - TstRes_WriteHeadUserCorrect (UsrDat); + TstPrn_WriteHeadUserCorrect (UsrDat); HTM_TR_End (); HTM_TR_Begin (NULL); /***** Write the user answer *****/ - if (Result->Questions[NumQst].StrAnswers[0]) // If user has answered the question + if (Print->PrintedQuestions[NumQst].StrAnswers[0]) // If user has answered the question { - if (sscanf (Result->Questions[NumQst].StrAnswers,"%ld",&IntAnswerUsr) == 1) + if (sscanf (Print->PrintedQuestions[NumQst].StrAnswers,"%ld",&IntAnswerUsr) == 1) { HTM_TD_Begin ("class=\"%s CM\"", TstVis_IsVisibleCorrectAns (Visibility) ? @@ -1011,8 +1011,8 @@ static void TstRes_WriteIntAnsExam (struct UsrData *UsrDat, /******************** Write float answer in an test exam *********************/ /*****************************************************************************/ -static void TstRes_WriteFloatAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteFloatAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Visibility) @@ -1026,15 +1026,15 @@ static void TstRes_WriteFloatAnsExam (struct UsrData *UsrDat, /***** Header with the title of each column *****/ HTM_TABLE_BeginPadding (2); HTM_TR_Begin (NULL); - TstRes_WriteHeadUserCorrect (UsrDat); + TstPrn_WriteHeadUserCorrect (UsrDat); HTM_TR_End (); HTM_TR_Begin (NULL); /***** Write the user answer *****/ - if (Result->Questions[NumQst].StrAnswers[0]) // If user has answered the question + if (Print->PrintedQuestions[NumQst].StrAnswers[0]) // If user has answered the question { - FloatAnsUsr = Str_GetDoubleFromStr (Result->Questions[NumQst].StrAnswers); + FloatAnsUsr = Str_GetDoubleFromStr (Print->PrintedQuestions[NumQst].StrAnswers); // A bad formatted floating point answer will interpreted as 0.0 HTM_TD_Begin ("class=\"%s CM\"", TstVis_IsVisibleCorrectAns (Visibility) ? @@ -1072,8 +1072,8 @@ static void TstRes_WriteFloatAnsExam (struct UsrData *UsrDat, /***************** Write false / true answer in a test exam ******************/ /*****************************************************************************/ -static void TstRes_WriteTFAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteTFAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, const struct Tst_Question *Question, unsigned Visibility) @@ -1084,12 +1084,12 @@ static void TstRes_WriteTFAnsExam (struct UsrData *UsrDat, Tst_CheckIfNumberOfAnswersIsOne (Question); /***** Get answer true or false *****/ - AnsTFUsr = Result->Questions[NumQst].StrAnswers[0]; + AnsTFUsr = Print->PrintedQuestions[NumQst].StrAnswers[0]; /***** Header with the title of each column *****/ HTM_TABLE_BeginPadding (2); HTM_TR_Begin (NULL); - TstRes_WriteHeadUserCorrect (UsrDat); + TstPrn_WriteHeadUserCorrect (UsrDat); HTM_TR_End (); HTM_TR_Begin (NULL); @@ -1121,8 +1121,8 @@ static void TstRes_WriteTFAnsExam (struct UsrData *UsrDat, /********** Write single or multiple choice answer in a test exam ************/ /*****************************************************************************/ -static void TstRes_WriteChoiceAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteChoiceAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility) @@ -1139,15 +1139,15 @@ static void TstRes_WriteChoiceAnsExam (struct UsrData *UsrDat, } Ans; /***** Get indexes for this question from string *****/ - TstRes_GetIndexesFromStr (Result->Questions[NumQst].StrIndexes,Indexes); + TstPrn_GetIndexesFromStr (Print->PrintedQuestions[NumQst].StrIndexes,Indexes); /***** Get the user's answers for this question from string *****/ - TstRes_GetAnswersFromStr (Result->Questions[NumQst].StrAnswers,UsrAnswers); + TstPrn_GetAnswersFromStr (Print->PrintedQuestions[NumQst].StrAnswers,UsrAnswers); /***** Begin table *****/ HTM_TABLE_BeginPadding (2); HTM_TR_Begin (NULL); - TstRes_WriteHeadUserCorrect (UsrDat); + TstPrn_WriteHeadUserCorrect (UsrDat); HTM_TD_Empty (2); HTM_TR_End (); @@ -1250,15 +1250,15 @@ static void TstRes_WriteChoiceAnsExam (struct UsrData *UsrDat, /***************** Write text answer when assessing a test *******************/ /*****************************************************************************/ -static void TstRes_WriteTextAnsExam (struct UsrData *UsrDat, - const struct TstRes_Result *Result, +static void TstPrn_WriteTextAnsExam (struct UsrData *UsrDat, + const struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question, unsigned Visibility) { unsigned NumOpt; - char TextAnsUsr[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; - char TextAnsOK[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char TextAnsUsr[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char TextAnsOK[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; bool Correct = false; /***** Get text and correctness of answers for this question from database (one row per answer) *****/ @@ -1283,17 +1283,17 @@ static void TstRes_WriteTextAnsExam (struct UsrData *UsrDat, /***** Header with the title of each column *****/ HTM_TABLE_BeginPadding (2); HTM_TR_Begin (NULL); - TstRes_WriteHeadUserCorrect (UsrDat); + TstPrn_WriteHeadUserCorrect (UsrDat); HTM_TR_End (); HTM_TR_Begin (NULL); /***** Write the user answer *****/ - if (Result->Questions[NumQst].StrAnswers[0]) // If user has answered the question + if (Print->PrintedQuestions[NumQst].StrAnswers[0]) // If user has answered the question { /* Filter the user answer */ - Str_Copy (TextAnsUsr,Result->Questions[NumQst].StrAnswers, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + Str_Copy (TextAnsUsr,Print->PrintedQuestions[NumQst].StrAnswers, + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); /* In order to compare student answer to stored answer, the text answers are stored avoiding two or more consecurive spaces */ @@ -1307,7 +1307,7 @@ static void TstRes_WriteTextAnsExam (struct UsrData *UsrDat, { /* Filter this correct answer */ Str_Copy (TextAnsOK,Question->Answer.Options[NumOpt].Text, - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); Str_ConvertToComparable (TextAnsOK); /* Check is user answer is correct */ @@ -1322,7 +1322,7 @@ static void TstRes_WriteTextAnsExam (struct UsrData *UsrDat, (Correct ? "ANS_OK" : "ANS_BAD") : "ANS_0"); - HTM_Txt (Result->Questions[NumQst].StrAnswers); + HTM_Txt (Print->PrintedQuestions[NumQst].StrAnswers); } else // If user has omitted the answer HTM_TD_Begin (NULL); @@ -1386,7 +1386,7 @@ static void TstRes_WriteTextAnsExam (struct UsrData *UsrDat, /********* one for the user's answer and other for the correct answer ********/ /*****************************************************************************/ -static void TstRes_WriteHeadUserCorrect (struct UsrData *UsrDat) +static void TstPrn_WriteHeadUserCorrect (struct UsrData *UsrDat) { extern const char *Txt_User[Usr_NUM_SEXS]; extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; @@ -1404,16 +1404,16 @@ static void TstRes_WriteHeadUserCorrect (struct UsrData *UsrDat) /************* Store user's answers of an test exam into database ************/ /*****************************************************************************/ -static void TstRes_StoreOneExamQstInDB (const struct TstRes_Result *Result, +static void TstPrn_StoreOneExamQstInDB (const struct TstPrn_Print *Print, unsigned NumQst) { - char StrIndexes[TstRes_MAX_BYTES_INDEXES_ONE_QST + 1]; - char StrAnswers[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; + char StrIndexes[TstPrn_MAX_BYTES_INDEXES_ONE_QST + 1]; + char StrAnswers[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; /***** Replace each separator of multiple parameters by a comma *****/ /* In database commas are used as separators instead of special chars */ - Par_ReplaceSeparatorMultipleByComma (Result->Questions[NumQst].StrIndexes,StrIndexes); - Par_ReplaceSeparatorMultipleByComma (Result->Questions[NumQst].StrAnswers,StrAnswers); + Par_ReplaceSeparatorMultipleByComma (Print->PrintedQuestions[NumQst].StrIndexes,StrIndexes); + Par_ReplaceSeparatorMultipleByComma (Print->PrintedQuestions[NumQst].StrAnswers,StrAnswers); /***** Insert question and user's answers into database *****/ Str_SetDecimalPointToUS (); // To print the floating point as a dot @@ -1422,9 +1422,9 @@ static void TstRes_StoreOneExamQstInDB (const struct TstRes_Result *Result, " (ExaCod,QstCod,QstInd,Score,Indexes,Answers)" " VALUES" " (%ld,%ld,%u,'%.15lg','%s','%s')", - Result->ResCod,Result->Questions[NumQst].QstCod, + Print->PrnCod,Print->PrintedQuestions[NumQst].QstCod, NumQst, // 0, 1, 2, 3... - Result->Questions[NumQst].Score, + Print->PrintedQuestions[NumQst].Score, StrIndexes, StrAnswers); Str_SetDecimalPointToLocal (); // Return to local system @@ -1434,24 +1434,24 @@ static void TstRes_StoreOneExamQstInDB (const struct TstRes_Result *Result, /*********************** Update the score of a question **********************/ /*****************************************************************************/ -static void Tst_UpdateQstScoreInDB (const struct TstRes_Result *Result,unsigned NumQst) +static void Tst_UpdateQstScoreInDB (const struct TstPrn_Print *Print,unsigned NumQst) { /***** Update number of clicks and score of the question *****/ Str_SetDecimalPointToUS (); // To print the floating point as a dot - if (Result->Questions[NumQst].AnswerIsNotBlank) + if (Print->PrintedQuestions[NumQst].AnswerIsNotBlank) DB_QueryUPDATE ("can not update the score of a question", "UPDATE tst_questions" " SET NumHits=NumHits+1,NumHitsNotBlank=NumHitsNotBlank+1," "Score=Score+(%.15lg)" " WHERE QstCod=%ld", - Result->Questions[NumQst].Score, - Result->Questions[NumQst].QstCod); + Print->PrintedQuestions[NumQst].Score, + Print->PrintedQuestions[NumQst].QstCod); else // The answer is blank DB_QueryUPDATE ("can not update the score of a question", "UPDATE tst_questions" " SET NumHits=NumHits+1" " WHERE QstCod=%ld", - Result->Questions[NumQst].QstCod); + Print->PrintedQuestions[NumQst].QstCod); Str_SetDecimalPointToLocal (); // Return to local system } @@ -1459,12 +1459,12 @@ static void Tst_UpdateQstScoreInDB (const struct TstRes_Result *Result,unsigned /************* Select users and dates to show their test exams ***************/ /*****************************************************************************/ -void TstRes_SelUsrsToViewUsrsExams (void) +void TstPrn_SelUsrsToViewUsrsExams (void) { - TstRes_PutFormToSelectUsrsToViewUsrsExams (NULL); + TstPrn_PutFormToSelectUsrsToViewUsrsExams (NULL); } -static void TstRes_PutFormToSelectUsrsToViewUsrsExams (__attribute__((unused)) void *Args) +static void TstPrn_PutFormToSelectUsrsToViewUsrsExams (__attribute__((unused)) void *Args) { extern const char *Hlp_ASSESSMENT_Tests_results; extern const char *Txt_Results; @@ -1483,7 +1483,7 @@ static void TstRes_PutFormToSelectUsrsToViewUsrsExams (__attribute__((unused)) v /******************** Select dates to show my test exams *********************/ /*****************************************************************************/ -void TstRes_SelDatesToSeeMyExams (void) +void TstPrn_SelDatesToSeeMyExams (void) { extern const char *Hlp_ASSESSMENT_Tests_results; extern const char *Txt_Results; @@ -1514,7 +1514,7 @@ void TstRes_SelDatesToSeeMyExams (void) /***************************** Show my test exams ****************************/ /*****************************************************************************/ -void TstRes_ShowMyExams (void) +void TstPrn_ShowMyExams (void) { extern const char *Hlp_ASSESSMENT_Tests_results; extern const char *Txt_Results; @@ -1528,11 +1528,11 @@ void TstRes_ShowMyExams (void) Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,2); /***** Header of the table with the list of users *****/ - TstRes_ShowHeaderExams (); + TstPrn_ShowHeaderExams (); /***** List my test exams *****/ TstCfg_GetConfigFromDB (); // To get feedback type - TstRes_ShowExams (&Gbl.Usrs.Me.UsrDat); + TstPrn_ShowExams (&Gbl.Usrs.Me.UsrDat); /***** End table and box *****/ Box_BoxTableEnd (); @@ -1542,18 +1542,18 @@ void TstRes_ShowMyExams (void) /******************** Get users and show their test exams ********************/ /*****************************************************************************/ -void TstRes_GetUsrsAndShowExams (void) +void TstPrn_GetUsrsAndShowExams (void) { Usr_GetSelectedUsrsAndGoToAct (&Gbl.Usrs.Selected, - TstRes_ShowUsrsExams,NULL, - TstRes_PutFormToSelectUsrsToViewUsrsExams,NULL); + TstPrn_ShowUsrsExams,NULL, + TstPrn_PutFormToSelectUsrsToViewUsrsExams,NULL); } /*****************************************************************************/ /********************* Show test exams for several users *********************/ /*****************************************************************************/ -static void TstRes_ShowUsrsExams (__attribute__((unused)) void *Args) +static void TstPrn_ShowUsrsExams (__attribute__((unused)) void *Args) { extern const char *Hlp_ASSESSMENT_Tests_results; extern const char *Txt_Results; @@ -1568,7 +1568,7 @@ static void TstRes_ShowUsrsExams (__attribute__((unused)) void *Args) Hlp_ASSESSMENT_Tests_results,Box_NOT_CLOSABLE,2); /***** Header of the table with the list of users *****/ - TstRes_ShowHeaderExams (); + TstPrn_ShowHeaderExams (); /***** List the test exams of the selected users *****/ Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; @@ -1582,7 +1582,7 @@ static void TstRes_ShowUsrsExams (__attribute__((unused)) void *Args) { /***** Show test exams *****/ Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); - TstRes_ShowExams (&Gbl.Usrs.Other.UsrDat); + TstPrn_ShowExams (&Gbl.Usrs.Other.UsrDat); } } @@ -1594,7 +1594,7 @@ static void TstRes_ShowUsrsExams (__attribute__((unused)) void *Args) /************************ Show header of my test exams ***********************/ /*****************************************************************************/ -static void TstRes_ShowHeaderExams (void) +static void TstPrn_ShowHeaderExams (void) { extern const char *Txt_User[Usr_NUM_SEXS]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; @@ -1623,7 +1623,7 @@ static void TstRes_ShowHeaderExams (void) /************ Show the test exams of a user in the current course ************/ /*****************************************************************************/ -static void TstRes_ShowExams (struct UsrData *UsrDat) +static void TstPrn_ShowExams (struct UsrData *UsrDat) { extern const char *Txt_View_test; MYSQL_RES *mysql_res; @@ -1633,7 +1633,7 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) static unsigned UniqueId = 0; Dat_StartEndTime_t StartEndTime; char *Id; - struct TstRes_Result Result; + struct TstPrn_Print Print; unsigned NumTotalQsts = 0; unsigned NumTotalQstsNotBlank = 0; double TotalScoreOfAllTests = 0.0; @@ -1687,35 +1687,35 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) row = mysql_fetch_row (mysql_res); /* Get test code (row[0]) */ - TstRes_ResetResult (&Result); - if ((Result.ResCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + TstPrn_ResetResult (&Print); + if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of test exam."); /* Get if exam has been sent (row[5]) */ - Result.Sent = (row[5][0] == 'Y'); + Print.Sent = (row[5][0] == 'Y'); /* Get if teachers are allowed to see this test exam (row[6]) */ - Result.AllowTeachers = (row[6][0] == 'Y'); - ClassDat = Result.AllowTeachers ? "DAT" : + Print.AllowTeachers = (row[6][0] == 'Y'); + ClassDat = Print.AllowTeachers ? "DAT" : "DAT_LIGHT"; switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: - ICanView.NumQsts = Result.Sent && ItsMe; - ICanView.Score = Result.Sent && ItsMe && + ICanView.NumQsts = Print.Sent && ItsMe; + ICanView.Score = Print.Sent && ItsMe && TstVis_IsVisibleTotalScore (TstCfg_GetConfigVisibility ()); - ICanView.Exam = Result.Sent && ItsMe; + ICanView.Exam = Print.Sent && ItsMe; break; case Rol_NET: case Rol_TCH: case Rol_DEG_ADM: case Rol_CTR_ADM: case Rol_INS_ADM: - ICanView.NumQsts = Result.Sent; // If the exam has been sent, + ICanView.NumQsts = Print.Sent; // If the exam has been sent, // teachers can see the number of questions ICanView.Score = - ICanView.Exam = Result.Sent && (ItsMe || Result.AllowTeachers); + ICanView.Exam = Print.Sent && (ItsMe || Print.AllowTeachers); break; case Rol_SYS_ADM: ICanView.NumQsts = @@ -1733,8 +1733,8 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) HTM_TR_Begin (NULL); /* Write date and time (row[1] and row[2] hold UTC date-times) */ - Result.TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]); - Result.TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]); + Print.TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]); + Print.TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]); UniqueId++; for (StartEndTime = (Dat_StartEndTime_t) 0; StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); @@ -1744,7 +1744,7 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) Lay_NotEnoughMemoryExit (); HTM_TD_Begin ("id=\"%s\" class=\"%s LT COLOR%u\"", Id,ClassDat,Gbl.RowEvenOdd); - Dat_WriteLocalDateHMSFromUTC (Id,Result.TimeUTC[StartEndTime], + Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime], Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, true,true,false,0x7); HTM_TD_End (); @@ -1752,56 +1752,56 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) } /* Get number of questions (row[3]) */ - if (sscanf (row[3],"%u",&Result.NumQsts) != 1) - Result.NumQsts = 0; - if (Result.AllowTeachers) - NumTotalQsts += Result.NumQsts; + if (sscanf (row[3],"%u",&Print.NumQsts) != 1) + Print.NumQsts = 0; + if (Print.AllowTeachers) + NumTotalQsts += Print.NumQsts; /* Get number of questions not blank (row[4]) */ - if (sscanf (row[4],"%u",&Result.NumQstsNotBlank) != 1) - Result.NumQstsNotBlank = 0; - if (Result.AllowTeachers) - NumTotalQstsNotBlank += Result.NumQstsNotBlank; + if (sscanf (row[4],"%u",&Print.NumQstsNotBlank) != 1) + Print.NumQstsNotBlank = 0; + if (Print.AllowTeachers) + NumTotalQstsNotBlank += Print.NumQstsNotBlank; /* Get score (row[7]) */ Str_SetDecimalPointToUS (); // To get the decimal point as a dot - if (sscanf (row[7],"%lf",&Result.Score) != 1) - Result.Score = 0.0; + if (sscanf (row[7],"%lf",&Print.Score) != 1) + Print.Score = 0.0; Str_SetDecimalPointToLocal (); // Return to local system - if (Result.AllowTeachers) - TotalScoreOfAllTests += Result.Score; + if (Print.AllowTeachers) + TotalScoreOfAllTests += Print.Score; /* Write number of questions */ HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); if (ICanView.NumQsts) - HTM_Unsigned (Result.NumQsts); + HTM_Unsigned (Print.NumQsts); HTM_TD_End (); /* Write number of questions not blank */ HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); if (ICanView.NumQsts) - HTM_Unsigned (Result.NumQstsNotBlank); + HTM_Unsigned (Print.NumQstsNotBlank); HTM_TD_End (); /* Write score */ HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); if (ICanView.Score) - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); HTM_TD_End (); /* Write average score per question */ HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); if (ICanView.Score) - HTM_Double2Decimals (Result.NumQsts ? Result.Score / - (double) Result.NumQsts : - 0.0); + HTM_Double2Decimals (Print.NumQsts ? Print.Score / + (double) Print.NumQsts : + 0.0); HTM_TD_End (); /* Write grade */ HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd); if (ICanView.Score) - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, - TstRes_SCORE_MAX); + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, + TstPrn_SCORE_MAX); HTM_TD_End (); /* Link to show this test exam */ @@ -1810,19 +1810,19 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) { Frm_StartForm (Gbl.Action.Act == ActSeeMyTstRes ? ActSeeOneTstResMe : ActSeeOneTstResOth); - TstRes_PutParamExaCod (Result.ResCod); + TstPrn_PutParamExaCod (Print.PrnCod); Ico_PutIconLink ("tasks.svg",Txt_View_test); Frm_EndForm (); } HTM_TD_End (); HTM_TR_End (); - if (Result.AllowTeachers) + if (Print.AllowTeachers) NumExamsVisibleByTchs++; } /***** Write totals for this user *****/ - TstRes_ShowExamsSummaryRow (ItsMe,NumExamsVisibleByTchs, + TstPrn_ShowExamsSummaryRow (ItsMe,NumExamsVisibleByTchs, NumTotalQsts,NumTotalQstsNotBlank, TotalScoreOfAllTests); } @@ -1842,7 +1842,7 @@ static void TstRes_ShowExams (struct UsrData *UsrDat) /****************** Write parameter with code of test exam *******************/ /*****************************************************************************/ -void TstRes_PutParamExaCod (long ExaCod) +void TstPrn_PutParamExaCod (long ExaCod) { Par_PutHiddenParamLong (NULL,"ExaCod",ExaCod); } @@ -1851,7 +1851,7 @@ void TstRes_PutParamExaCod (long ExaCod) /****************** Get parameter with code of test exam *********************/ /*****************************************************************************/ -long TstRes_GetParamExaCod (void) +long TstPrn_GetParamExaCod (void) { /***** Get code of exam *****/ return Par_GetParToLong ("ExaCod"); @@ -1861,7 +1861,7 @@ long TstRes_GetParamExaCod (void) /**************** Show row with summary of user's test exams *****************/ /*****************************************************************************/ -static void TstRes_ShowExamsSummaryRow (bool ItsMe, +static void TstPrn_ShowExamsSummaryRow (bool ItsMe, unsigned NumExams, unsigned NumTotalQsts, unsigned NumTotalQstsNotBlank, @@ -1929,8 +1929,8 @@ static void TstRes_ShowExamsSummaryRow (bool ItsMe, /***** Write score over Tst_SCORE_MAX *****/ HTM_TD_Begin ("class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd); if (ICanViewTotalScore) - TstRes_ComputeAndShowGrade (NumTotalQsts,TotalScoreOfAllTests, - TstRes_SCORE_MAX); + TstPrn_ComputeAndShowGrade (NumTotalQsts,TotalScoreOfAllTests, + TstPrn_SCORE_MAX); HTM_TD_End (); /***** Last cell *****/ @@ -1945,7 +1945,7 @@ static void TstRes_ShowExamsSummaryRow (bool ItsMe, /******************** Show one test exam of another user *********************/ /*****************************************************************************/ -void TstRes_ShowOneExam (void) +void TstPrn_ShowOneExam (void) { extern const char *Hlp_ASSESSMENT_Tests_results; extern const char *Txt_Test_result; @@ -1957,7 +1957,7 @@ void TstRes_ShowOneExam (void) extern const char *Txt_Score; extern const char *Txt_Grade; extern const char *Txt_Tags; - struct TstRes_Result Result; + struct TstPrn_Print Print; bool ShowPhoto; char PhotoURL[PATH_MAX + 1]; Dat_StartEndTime_t StartEndTime; @@ -1967,12 +1967,12 @@ void TstRes_ShowOneExam (void) bool ICanViewScore; /***** Get the code of the test *****/ - TstRes_ResetResult (&Result); - if ((Result.ResCod = TstRes_GetParamExaCod ()) == -1L) + TstPrn_ResetResult (&Print); + if ((Print.PrnCod = TstPrn_GetParamExaCod ()) == -1L) Lay_ShowErrorAndExit ("Code of test is missing."); /***** Get test exam data *****/ - TstRes_GetExamDataByExaCod (&Result); + TstPrn_GetExamDataByExaCod (&Print); TstCfg_SetConfigVisibility (TstVis_MAX_VISIBILITY); /***** Check if I can view this test exam *****/ @@ -2002,7 +2002,7 @@ void TstRes_ShowOneExam (void) case ActSeeOneTstResOth: ICanViewTest = ICanViewScore = ItsMe || - Result.AllowTeachers; + Print.AllowTeachers; break; default: ICanViewTest = @@ -2023,7 +2023,7 @@ void TstRes_ShowOneExam (void) if (ICanViewTest) // I am allowed to view this test exam { /***** Get questions and user's answers of the test exam from database *****/ - TstRes_GetExamQuestionsFromDB (&Result); + TstPrn_GetExamQuestionsFromDB (&Print); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Test_result, @@ -2082,7 +2082,7 @@ void TstRes_ShowOneExam (void) HTM_TD_End (); HTM_TD_Begin ("id=\"%s\" class=\"DAT LT\"",Id); - Dat_WriteLocalDateHMSFromUTC (Id,Result.TimeUTC[StartEndTime], + Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime], Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,true,true,0x7); HTM_TD_End (); @@ -2101,8 +2101,8 @@ void TstRes_ShowOneExam (void) HTM_TD_Begin ("class=\"DAT LT\""); HTM_TxtF ("%u (%u %s)", - Result.NumQsts, - Result.NumQstsNotBlank,Txt_non_blank_QUESTIONS); + Print.NumQsts, + Print.NumQstsNotBlank,Txt_non_blank_QUESTIONS); HTM_TD_End (); HTM_TR_End (); @@ -2116,7 +2116,7 @@ void TstRes_ShowOneExam (void) HTM_TD_Begin ("class=\"DAT LT\""); if (ICanViewScore) - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); else Ico_PutIconNotVisible (); HTM_TD_End (); @@ -2130,8 +2130,8 @@ void TstRes_ShowOneExam (void) HTM_TD_Begin ("class=\"DAT LT\""); if (ICanViewScore) - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, - TstRes_SCORE_MAX); + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, + TstPrn_SCORE_MAX); else Ico_PutIconNotVisible (); HTM_TD_End (); @@ -2146,13 +2146,13 @@ void TstRes_ShowOneExam (void) HTM_TD_End (); HTM_TD_Begin ("class=\"DAT LT\""); - TstRes_ShowTagsPresentInAnExam (Result.ResCod); + TstPrn_ShowTagsPresentInAnExam (Print.PrnCod); HTM_TD_End (); HTM_TR_End (); /***** Write answers and solutions *****/ - TstRes_ShowExamAnswers (&Gbl.Usrs.Other.UsrDat,&Result, + TstPrn_ShowExamAnswers (&Gbl.Usrs.Other.UsrDat,&Print, TstCfg_GetConfigVisibility ()); /***** End table *****/ @@ -2163,11 +2163,11 @@ void TstRes_ShowOneExam (void) { HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\""); HTM_TxtColonNBSP (Txt_Score); - HTM_Double2Decimals (Result.Score); + HTM_Double2Decimals (Print.Score); HTM_BR (); HTM_TxtColonNBSP (Txt_Grade); - TstRes_ComputeAndShowGrade (Result.NumQsts,Result.Score, - TstRes_SCORE_MAX); + TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score, + TstPrn_SCORE_MAX); HTM_DIV_End (); } @@ -2182,7 +2182,7 @@ void TstRes_ShowOneExam (void) /********************* Show test tags in this test exam **********************/ /*****************************************************************************/ -static void TstRes_ShowTagsPresentInAnExam (long ResCod) +static void TstPrn_ShowTagsPresentInAnExam (long ResCod) { MYSQL_RES *mysql_res; unsigned NumTags; @@ -2211,27 +2211,27 @@ static void TstRes_ShowTagsPresentInAnExam (long ResCod) /************** Show user's and correct answers of a test exam ***************/ /*****************************************************************************/ -void TstRes_ShowExamAnswers (struct UsrData *UsrDat, - struct TstRes_Result *Result, +void TstPrn_ShowExamAnswers (struct UsrData *UsrDat, + struct TstPrn_Print *Print, unsigned Visibility) { unsigned NumQst; struct Tst_Question Question; for (NumQst = 0; - NumQst < Result->NumQsts; + NumQst < Print->NumQsts; NumQst++) { Gbl.RowEvenOdd = NumQst % 2; /***** Create test question *****/ Tst_QstConstructor (&Question); - Question.QstCod = Result->Questions[NumQst].QstCod; + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; /***** Get question data *****/ if (Tst_GetQstDataFromDB (&Question)) // Question exists? /***** Write questions and answers *****/ - TstRes_WriteQstAndAnsExam (UsrDat,Result,NumQst,&Question,Visibility); + TstPrn_WriteQstAndAnsExam (UsrDat,Print,NumQst,&Question,Visibility); /***** Destroy test question *****/ Tst_QstDestructor (&Question); @@ -2242,7 +2242,7 @@ void TstRes_ShowExamAnswers (struct UsrData *UsrDat, /************ Get data of a test exam using its test exam code ***************/ /*****************************************************************************/ -void TstRes_GetExamDataByExaCod (struct TstRes_Result *Result) +void TstPrn_GetExamDataByExaCod (struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -2259,7 +2259,7 @@ void TstRes_GetExamDataByExaCod (struct TstRes_Result *Result) "Score" // row[7] " FROM tst_exams" " WHERE ExaCod=%ld AND CrsCod=%ld", - Result->ResCod, + Print->PrnCod, Gbl.Hierarchy.Crs.CrsCod) == 1) { row = mysql_fetch_row (mysql_res); @@ -2268,31 +2268,31 @@ void TstRes_GetExamDataByExaCod (struct TstRes_Result *Result) Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]); /* Get date-time (row[1] and row[2] hold UTC date-time) */ - Result->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]); - Result->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]); + Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]); + Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]); /* Get number of questions (row[3]) */ - if (sscanf (row[3],"%u",&Result->NumQsts) != 1) - Result->NumQsts = 0; + if (sscanf (row[3],"%u",&Print->NumQsts) != 1) + Print->NumQsts = 0; /* Get number of questions not blank (row[4]) */ - if (sscanf (row[4],"%u",&Result->NumQstsNotBlank) != 1) - Result->NumQstsNotBlank = 0; + if (sscanf (row[4],"%u",&Print->NumQstsNotBlank) != 1) + Print->NumQstsNotBlank = 0; /* Get if exam has been sent (row[5]) */ - Result->Sent = (row[5][0] == 'Y'); + Print->Sent = (row[5][0] == 'Y'); /* Get if teachers are allowed to see this test exam (row[6]) */ - Result->AllowTeachers = (row[6][0] == 'Y'); + Print->AllowTeachers = (row[6][0] == 'Y'); /* Get score (row[7]) */ Str_SetDecimalPointToUS (); // To get the decimal point as a dot - if (sscanf (row[7],"%lf",&Result->Score) != 1) - Result->Score = 0.0; + if (sscanf (row[7],"%lf",&Print->Score) != 1) + Print->Score = 0.0; Str_SetDecimalPointToLocal (); // Return to local system } else - TstRes_ResetExamExceptExaCod (Result); + TstPrn_ResetExamExceptExaCod (Print); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); @@ -2302,7 +2302,7 @@ void TstRes_GetExamDataByExaCod (struct TstRes_Result *Result) /************* Get the questions of a test exam from database ****************/ /*****************************************************************************/ -void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result) +void TstPrn_GetExamQuestionsFromDB (struct TstPrn_Print *Print) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -2322,12 +2322,12 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result) " WHERE tst_exam_questions.ExaCod=%ld" " AND tst_exam_questions.QstCod=tst_questions.QstCod" " ORDER BY tst_exam_questions.QstInd", - Result->ResCod); + Print->PrnCod); /***** List questions *****/ // The number of questions in table of exam questions // should match the number of questions got from exam - if (NumQsts == Result->NumQsts) + if (NumQsts == Print->NumQsts) for (NumQst = 0; NumQst < NumQsts; NumQst++) @@ -2335,33 +2335,33 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result) row = mysql_fetch_row (mysql_res); /* Get question code (row[0]) */ - if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + if ((Print->PrintedQuestions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); /* Get answer type (row[1]) */ AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); /* Get indexes for this question (row[2]) */ - Str_Copy (Result->Questions[NumQst].StrIndexes,row[2], - TstRes_MAX_BYTES_INDEXES_ONE_QST); + Str_Copy (Print->PrintedQuestions[NumQst].StrIndexes,row[2], + TstPrn_MAX_BYTES_INDEXES_ONE_QST); /* Get answers selected by user for this question (row[3]) */ - Str_Copy (Result->Questions[NumQst].StrAnswers,row[3], - TstRes_MAX_BYTES_ANSWERS_ONE_QST); + Str_Copy (Print->PrintedQuestions[NumQst].StrAnswers,row[3], + TstPrn_MAX_BYTES_ANSWERS_ONE_QST); /* Replace each comma by a separator of multiple parameters */ /* In database commas are used as separators instead of special chars */ - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes); + Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrIndexes); if (AnswerType == Tst_ANS_MULTIPLE_CHOICE) // Only multiple choice questions have multiple answers separated by commas // Other types of questions have a unique answer, and comma may be part of that answer - Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers); + Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrAnswers); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); - if (NumQsts != Result->NumQsts) + if (NumQsts != Print->NumQsts) Lay_WrongExamExit (); } @@ -2369,7 +2369,7 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result) /********************** Remove test exams made by a user *********************/ /*****************************************************************************/ -void TstRes_RemoveExamsMadeByUsrInAllCrss (long UsrCod) +void TstPrn_RemoveExamsMadeByUsrInAllCrss (long UsrCod) { /***** Remove test exams made by the specified user *****/ DB_QueryDELETE ("can not remove test exams made by a user", @@ -2389,7 +2389,7 @@ void TstRes_RemoveExamsMadeByUsrInAllCrss (long UsrCod) /*************** Remove test exams made by a user in a course ****************/ /*****************************************************************************/ -void TstRes_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod) +void TstPrn_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod) { /***** Remove test exams made by the given user *****/ DB_QueryDELETE ("can not remove test exams made by a user in a course", @@ -2409,7 +2409,7 @@ void TstRes_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod) /******************* Remove all test exams made in a course ******************/ /*****************************************************************************/ -void TstRes_RemoveCrsExams (long CrsCod) +void TstPrn_RemoveCrsExams (long CrsCod) { /***** Remove questions of test exams made in the course *****/ DB_QueryDELETE ("can not remove test exams made in a course", diff --git a/swad_test_exam.h b/swad_test_print.h similarity index 52% rename from swad_test_exam.h rename to swad_test_print.h index ea64f467..f5427522 100644 --- a/swad_test_exam.h +++ b/swad_test_print.h @@ -1,7 +1,7 @@ -// swad_test_exam.c: test exams made by users +// swad_test_print.h: test exam prints made by users -#ifndef _SWAD_TST_EXA -#define _SWAD_TST_EXA +#ifndef _SWAD_TST_PRN +#define _SWAD_TST_PRN /* SWAD (Shared Workspace At a Distance in Spanish), is a web platform developed at the University of Granada (Spain), @@ -27,85 +27,88 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -#include "swad_test.h" +#include "swad_test_config.h" +#include "swad_test_type.h" #include "swad_user.h" /*****************************************************************************/ /***************************** Public constants ******************************/ /*****************************************************************************/ -#define TstRes_MAX_BYTES_INDEXES_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (3 + 1)) +#define TstPrn_MAX_BYTES_INDEXES_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (3 + 1)) -#define TstRes_MAX_CHARS_ANSWERS_ONE_QST (128 - 1) // 127 -#define TstRes_MAX_BYTES_ANSWERS_ONE_QST ((TstRes_MAX_CHARS_ANSWERS_ONE_QST + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 +#define TstPrn_MAX_CHARS_ANSWERS_ONE_QST (128 - 1) // 127 +#define TstPrn_MAX_BYTES_ANSWERS_ONE_QST ((TstPrn_MAX_CHARS_ANSWERS_ONE_QST + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 -#define TstRes_SCORE_MAX 10 // Maximum score of a test (10 in Spain). Must be unsigned! // TODO: Make this configurable by teachers +#define TstPrn_SCORE_MAX 10 // Maximum score of a test (10 in Spain). Must be unsigned! // TODO: Make this configurable by teachers /*****************************************************************************/ /******************************* Public types ********************************/ /*****************************************************************************/ -struct TstRes_Result +struct TstPrn_PrintedQuestion { - long ResCod; // Test result code + long QstCod; // Question code + char StrIndexes[TstPrn_MAX_BYTES_INDEXES_ONE_QST + 1]; // 0 1 2 3, 3 0 2 1, etc. + char StrAnswers[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user + double Score; // Question score + bool AnswerIsNotBlank; // Answer not blank? + }; + +struct TstPrn_Print + { + long PrnCod; // Test print code time_t TimeUTC[Dat_NUM_START_END_TIME]; unsigned NumQsts; // Number of questions unsigned NumQstsNotBlank; // Number of questions not blank - bool Sent; // This test result has been sent or not? + bool Sent; // This test print has been sent or not? // "Sent" means that user has clicked "Send" button after finishing bool AllowTeachers; // Are teachers allowed to see this test result? - double Score; // Total score of the test result - struct - { - long QstCod; // Question code - char StrIndexes[TstRes_MAX_BYTES_INDEXES_ONE_QST + 1]; // 0 1 2 3, 3 0 2 1, etc. - char StrAnswers[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user - double Score; // Question score - bool AnswerIsNotBlank; // Answer not blank? - } Questions[TstCfg_MAX_QUESTIONS_PER_TEST]; + double Score; // Total score of the test print + struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST]; }; /*****************************************************************************/ /***************************** Public prototypes *****************************/ /*****************************************************************************/ -void TstRes_ResetResult (struct TstRes_Result *Result); -void TstRes_CreateExamInDB (struct TstRes_Result *Exam); -void TstRes_UpdateExamInDB (const struct TstRes_Result *Exam); +void TstPrn_ResetResult (struct TstPrn_Print *Print); +void TstPrn_CreateExamInDB (struct TstPrn_Print *Print); +void TstPrn_UpdateExamInDB (const struct TstPrn_Print *Print); -void TstRes_ShowExamAfterAssess (struct TstRes_Result *Exam); +void TstPrn_ShowExamAfterAssess (struct TstPrn_Print *Print); -void TstRes_ComputeScoresAndStoreExamQuestions (struct TstRes_Result *Exam, +void TstPrn_ComputeScoresAndStoreExamQuestions (struct TstPrn_Print *Print, bool UpdateQstScore); -void TstRes_ComputeChoiceAnsScore (struct TstRes_Result *Result, +void TstPrn_ComputeChoiceAnsScore (struct TstPrn_Print *Print, unsigned NumQst, struct Tst_Question *Question); -void TstRes_GetIndexesFromStr (const char StrIndexesOneQst[TstRes_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc. +void TstPrn_GetIndexesFromStr (const char StrIndexesOneQst[TstPrn_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc. unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]); -void TstRes_GetAnswersFromStr (const char StrAnswersOneQst[TstRes_MAX_BYTES_ANSWERS_ONE_QST + 1], +void TstPrn_GetAnswersFromStr (const char StrAnswersOneQst[TstPrn_MAX_BYTES_ANSWERS_ONE_QST + 1], bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION]); -void TstRes_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade); -double TstRes_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade); -void TstRes_ShowGrade (double Grade,double MaxGrade); +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 TstRes_SelUsrsToViewUsrsExams (void); -void TstRes_SelDatesToSeeMyExams (void); -void TstRes_ShowMyExams (void); -void TstRes_GetUsrsAndShowExams (void); +void TstPrn_SelUsrsToViewUsrsExams (void); +void TstPrn_SelDatesToSeeMyExams (void); +void TstPrn_ShowMyExams (void); +void TstPrn_GetUsrsAndShowExams (void); -void TstRes_PutParamExaCod (long ExaCod); -long TstRes_GetParamExaCod (void); +void TstPrn_PutParamExaCod (long ExaCod); +long TstPrn_GetParamExaCod (void); -void TstRes_ShowOneExam (void); -void TstRes_ShowExamAnswers (struct UsrData *UsrDat, - struct TstRes_Result *Result, +void TstPrn_ShowOneExam (void); +void TstPrn_ShowExamAnswers (struct UsrData *UsrDat, + struct TstPrn_Print *Print, unsigned Visibility); -void TstRes_GetExamDataByExaCod (struct TstRes_Result *Result); +void TstPrn_GetExamDataByExaCod (struct TstPrn_Print *Print); -void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result); -void TstRes_RemoveExamsMadeByUsrInAllCrss (long UsrCod); -void TstRes_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod); -void TstRes_RemoveCrsExams (long CrsCod); +void TstPrn_GetExamQuestionsFromDB (struct TstPrn_Print *Print); +void TstPrn_RemoveExamsMadeByUsrInAllCrss (long UsrCod); +void TstPrn_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod); +void TstPrn_RemoveCrsExams (long CrsCod); #endif diff --git a/swad_test_type.h b/swad_test_type.h new file mode 100644 index 00000000..3a2733db --- /dev/null +++ b/swad_test_type.h @@ -0,0 +1,99 @@ +// swad_test_type.h: definition of types for tests + +#ifndef _SWAD_TST_TYP +#define _SWAD_TST_TYP +/* + 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 . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#define Tst_MAX_TAGS_PER_QUESTION 5 + +#define Tst_MAX_CHARS_TAG (128 - 1) // 127 +#define Tst_MAX_BYTES_TAG ((Tst_MAX_CHARS_TAG + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 + +/*****************************************************************************/ +/***************************** Public constants ******************************/ +/*****************************************************************************/ + +#define Tst_MAX_OPTIONS_PER_QUESTION 10 + +/*****************************************************************************/ +/******************************* Public types ********************************/ +/*****************************************************************************/ + +struct Tst_Tags + { + unsigned Num; + bool All; + char *List; + char Txt[Tst_MAX_TAGS_PER_QUESTION][Tst_MAX_BYTES_TAG + 1]; + }; + +#define Tst_NUM_ANS_TYPES 6 +#define Tst_MAX_BYTES_LIST_ANSWER_TYPES (Tst_NUM_ANS_TYPES * (Cns_MAX_DECIMAL_DIGITS_UINT + 1)) +typedef enum + { + Tst_ANS_INT = 0, + Tst_ANS_FLOAT = 1, + Tst_ANS_TRUE_FALSE = 2, + Tst_ANS_UNIQUE_CHOICE = 3, + Tst_ANS_MULTIPLE_CHOICE = 4, + Tst_ANS_TEXT = 5, + Tst_ANS_ALL = 6, // All/any type of answer + } Tst_AnswerType_t; + +struct Tst_Question + { + long QstCod; + struct Tst_Tags Tags; + time_t EditTime; + char *Stem; + char *Feedback; + struct Media Media; + struct + { + Tst_AnswerType_t Type; + unsigned NumOptions; + bool Shuffle; + char TF; + struct + { + bool Correct; + char *Text; + char *Feedback; + struct Media Media; + } Options[Tst_MAX_OPTIONS_PER_QUESTION]; + long Integer; + double FloatingPoint[2]; + } Answer; + unsigned long NumHits; + unsigned long NumHitsNotBlank; + double Score; + }; + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +#endif diff --git a/swad_text.c b/swad_text.c index 88aa52d9..31f9ac69 100644 --- a/swad_text.c +++ b/swad_text.c @@ -30708,6 +30708,27 @@ const char *Txt_Please_check_your_privacy_settings = "Por favor, verifique suas configurações de privacidade."; #endif +const char *Txt_Please_review_your_answers_before_submitting_the_exam = +#if L==1 // ca + "Si us plau, revisi les seves respostes abans d'enviar l'examen."; +#elif L==2 // de + "Bitte überprüfen Sie Ihre Antworten, bevor Sie die Prüfung einreichen."; +#elif L==3 // en + "Please review your answers before submitting the exam."; +#elif L==4 // es + "Por favor, revise sus respuestas antes de enviar el examen."; +#elif L==5 // fr + "S'il vous plaît, veuillez revoir vos réponses avant de soumettre l'examen."; +#elif L==6 // gn + "Por favor, revise sus respuestas antes de enviar el examen."; // Okoteve traducción +#elif L==7 // it + "Si prega di rivedere le risposte prima di inviare l'esame."; +#elif L==8 // pl + "Przejrzyj swoje odpowiedzi przed przesłaniem egzaminu."; +#elif L==9 // pt + "Por favor, revise suas respostas antes de enviar o exame."; +#endif + const char *Txt_Please_select_the_country_of_your_institution = #if L==1 // ca "Si us plau, seleccioneu el país de la seva institució.";