mirror of https://github.com/acanas/swad-core.git
Version 21.63: Nov 26, 2021 Fixing of corruption in test prints and match prints.
This commit is contained in:
parent
d0e3b8da03
commit
5517a2d430
|
@ -13565,4 +13565,59 @@ SELECT tml_pubs.PubCod,
|
||||||
SELECT MAX(PstCod) AS NewestPstCod FROM for_posts GROUP BY ThrCod ORDER BY NewestPstCod DESC LIMIT 10;
|
SELECT MAX(PstCod) AS NewestPstCod FROM for_posts GROUP BY ThrCod ORDER BY NewestPstCod DESC LIMIT 10;
|
||||||
|
|
||||||
SELECT PstCod FROM for_posts ORDER BY PstCod DESC LIMIT 1;
|
SELECT PstCod FROM for_posts ORDER BY PstCod DESC LIMIT 1;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
2021-11-25: Error en juegos
|
||||||
|
|
||||||
|
mch_results.Score se ha guardado erróneamente en los juegos realizados aproximadamente entre estas fechas:
|
||||||
|
mch_result.StartTime>=20211124210000 AND mch_result.StartTime<=20211125160000
|
||||||
|
|
||||||
|
Sólo los que han contestado alguna pregunta:
|
||||||
|
mch_result.NumQstsNotBlank>0
|
||||||
|
|
||||||
|
La función:
|
||||||
|
void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod)
|
||||||
|
calcula Score y lo guarda en la base de datos.
|
||||||
|
Llama a:
|
||||||
|
Mch_GetMatchQuestionsFromDB (&Print);
|
||||||
|
MchPrn_ComputeScore (&Print);
|
||||||
|
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],&Question);
|
||||||
|
TstPrn_GetCorrectAndComputeChoAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||||
|
struct Qst_Question *Question);
|
||||||
|
Qst_GetCorrectChoAnswerFromDB (Question); // <----- Aquí estaba el fallo
|
||||||
|
SELECT Correct
|
||||||
|
FROM tst_answers
|
||||||
|
WHERE QstCod=%ld // Question code
|
||||||
|
ORDER BY AnsInd;
|
||||||
|
TstPrn_ComputeChoAnsScore (PrintedQuestion,Question);
|
||||||
|
Print->Score += Print->PrintedQuestions[NumQst].Score;
|
||||||
|
MchPrn_UpdateMatchPrintInDB (&Print);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,9 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
|
||||||
[ActChgPlgIP ] = { 780,-1,TabUnk,ActLstPlg , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,Plg_ChangePlgIP ,Plg_ContEditAfterChgPlg ,NULL},
|
[ActChgPlgIP ] = { 780,-1,TabUnk,ActLstPlg , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,Plg_ChangePlgIP ,Plg_ContEditAfterChgPlg ,NULL},
|
||||||
|
|
||||||
[ActSetUp ] = { 840, 5,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mtn_SetUp ,NULL},
|
[ActSetUp ] = { 840, 5,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mtn_SetUp ,NULL},
|
||||||
[ActReqRemOldCrs ] = {1109,-1,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mtn_RemoveOldCrss ,NULL},
|
[ActFixMchSco ] = {1915,-1,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,MchPrn_FixMatchesPrintsScores ,NULL},
|
||||||
|
[ActFixTstSco ] = {1916,-1,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstPrn_FixTestsPrintsScores ,NULL},
|
||||||
|
[ActReqRemOldCrs ] = {1109,-1,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mtn_RemoveOldCrss ,NULL},
|
||||||
[ActRemOldCrs ] = {1110,-1,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Crs_RemoveOldCrss ,NULL},
|
[ActRemOldCrs ] = {1110,-1,TabUnk,ActMtn , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Crs_RemoveOldCrss ,NULL},
|
||||||
|
|
||||||
// TabCty ******************************************************************
|
// TabCty ******************************************************************
|
||||||
|
@ -3739,6 +3741,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
|
||||||
ActLstOneGam, // #1912
|
ActLstOneGam, // #1912
|
||||||
ActEdiMch, // #1913
|
ActEdiMch, // #1913
|
||||||
ActChgMch, // #1914
|
ActChgMch, // #1914
|
||||||
|
ActFixMchSco, // #1915
|
||||||
|
ActFixTstSco, // #1916
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -65,7 +65,7 @@ typedef enum
|
||||||
|
|
||||||
typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action
|
typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action
|
||||||
|
|
||||||
#define Act_MAX_ACTION_COD 1914
|
#define Act_MAX_ACTION_COD 1916
|
||||||
|
|
||||||
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
|
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
|
||||||
|
|
||||||
|
@ -212,8 +212,10 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
|
||||||
#define ActChgPlgIP (ActRenMaiFul + 38)
|
#define ActChgPlgIP (ActRenMaiFul + 38)
|
||||||
|
|
||||||
#define ActSetUp (ActRenMaiFul + 39)
|
#define ActSetUp (ActRenMaiFul + 39)
|
||||||
#define ActReqRemOldCrs (ActRenMaiFul + 40)
|
#define ActFixMchSco (ActRenMaiFul + 40)
|
||||||
#define ActRemOldCrs (ActRenMaiFul + 41)
|
#define ActFixTstSco (ActRenMaiFul + 41)
|
||||||
|
#define ActReqRemOldCrs (ActRenMaiFul + 42)
|
||||||
|
#define ActRemOldCrs (ActRenMaiFul + 43)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************************** Country tab ********************************/
|
/******************************** Country tab ********************************/
|
||||||
|
|
|
@ -602,14 +602,15 @@ TODO: FIX BUG, URGENT! En las fechas como par
|
||||||
|
|
||||||
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 21.62.3 (2021-11-25)"
|
#define Log_PLATFORM_VERSION "SWAD 21.63 (2021-11-26)"
|
||||||
#define CSS_FILE "swad21.59.css"
|
#define CSS_FILE "swad21.59.css"
|
||||||
#define JS_FILE "swad21.59.js"
|
#define JS_FILE "swad21.59.js"
|
||||||
/*
|
/*
|
||||||
TODO: Rename CENTRE to CENTER in help wiki.
|
TODO: Rename CENTRE to CENTER in help wiki.
|
||||||
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
||||||
|
|
||||||
Version 21.62.3: Nov 25, 2021 Fixed bug in test questions. Reported by Javier Fernández Baldomero and others. (319438 lines)
|
Version 21.63: Nov 26, 2021 Fixing of corruption in test prints and match prints. (320010 lines)
|
||||||
|
Version 21.62.3: Nov 25, 2021 Fixed bug in test questions. Reported by Javier Fernández Baldomero and Jesús González Peñalver. (319438 lines)
|
||||||
Version 21.62.2: Nov 24, 2021 Fixed bug in forums. Reported by Javier Fernández Baldomero. (319422 lines)
|
Version 21.62.2: Nov 24, 2021 Fixed bug in forums. Reported by Javier Fernández Baldomero. (319422 lines)
|
||||||
Version 21.62.1: Nov 24, 2021 Added some header files. (319422 lines)
|
Version 21.62.1: Nov 24, 2021 Added some header files. (319422 lines)
|
||||||
Version 21.62: Nov 24, 2021 Code refactoring in photos. (319415 lines)
|
Version 21.62: Nov 24, 2021 Code refactoring in photos. (319415 lines)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "swad_course.h"
|
#include "swad_course.h"
|
||||||
#include "swad_database.h"
|
#include "swad_database.h"
|
||||||
|
#include "swad_match_print.h"
|
||||||
#include "swad_menu.h"
|
#include "swad_menu.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -43,8 +44,10 @@ void Mtn_Maintenance (void)
|
||||||
{
|
{
|
||||||
/***** Contextual menu *****/
|
/***** Contextual menu *****/
|
||||||
Mnu_ContextMenuBegin ();
|
Mnu_ContextMenuBegin ();
|
||||||
Mtn_PutLinkToSetUp (); // Set up
|
Mtn_PutLinkToSetUp (); // Set up
|
||||||
Crs_PutLinkToRemoveOldCrss (); // Remove old courses
|
// MchPrn_PutLinkToFixMatchesPrintsScores (); // Fix match prints scores
|
||||||
|
// TstPrn_PutLinkToFixTestsPrintsScores (); // Fix test prints scores
|
||||||
|
Crs_PutLinkToRemoveOldCrss (); // Remove old courses
|
||||||
Mnu_ContextMenuEnd ();
|
Mnu_ContextMenuEnd ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
38
swad_match.c
38
swad_match.c
|
@ -106,12 +106,9 @@ static bool Mch_CheckIfVisibilityOfResultsCanBeChanged (const struct Mch_Match *
|
||||||
static void Mch_ListOneOrMoreMatchesIcons (struct Gam_Games *Games,
|
static void Mch_ListOneOrMoreMatchesIcons (struct Gam_Games *Games,
|
||||||
const struct Mch_Match *Match,
|
const struct Mch_Match *Match,
|
||||||
const char *Anchor);
|
const char *Anchor);
|
||||||
static void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match);
|
|
||||||
static void Mch_ListOneOrMoreMatchesTimes (const struct Mch_Match *Match,unsigned UniqueId);
|
|
||||||
static void Mch_ListOneOrMoreMatchesTitleGrps (const struct Mch_Match *Match,
|
static void Mch_ListOneOrMoreMatchesTitleGrps (const struct Mch_Match *Match,
|
||||||
const char *Anchor);
|
const char *Anchor);
|
||||||
static void Mch_GetAndWriteNamesOfGrpsAssociatedToMatch (const struct Mch_Match *Match);
|
static void Mch_GetAndWriteNamesOfGrpsAssociatedToMatch (const struct Mch_Match *Match);
|
||||||
static void Mch_ListOneOrMoreMatchesNumPlayers (const struct Mch_Match *Match);
|
|
||||||
static void Mch_ListOneOrMoreMatchesStatus (struct Mch_Match *Match,unsigned NumQsts);
|
static void Mch_ListOneOrMoreMatchesStatus (struct Mch_Match *Match,unsigned NumQsts);
|
||||||
static void Mch_ListOneOrMoreMatchesResult (struct Gam_Games *Games,
|
static void Mch_ListOneOrMoreMatchesResult (struct Gam_Games *Games,
|
||||||
const struct Mch_Match *Match);
|
const struct Mch_Match *Match);
|
||||||
|
@ -587,7 +584,7 @@ static void Mch_ListOneOrMoreMatchesIcons (struct Gam_Games *Games,
|
||||||
/************* Put a column for teacher who created the match ****************/
|
/************* Put a column for teacher who created the match ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match)
|
void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match)
|
||||||
{
|
{
|
||||||
/***** Match author (teacher) *****/
|
/***** Match author (teacher) *****/
|
||||||
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
@ -599,7 +596,7 @@ static void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match)
|
||||||
/***************** Put a column for match start and end times ****************/
|
/***************** Put a column for match start and end times ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mch_ListOneOrMoreMatchesTimes (const struct Mch_Match *Match,unsigned UniqueId)
|
void Mch_ListOneOrMoreMatchesTimes (const struct Mch_Match *Match,unsigned UniqueId)
|
||||||
{
|
{
|
||||||
Dat_StartEndTime_t StartEndTime;
|
Dat_StartEndTime_t StartEndTime;
|
||||||
char *Id;
|
char *Id;
|
||||||
|
@ -718,7 +715,7 @@ static void Mch_GetAndWriteNamesOfGrpsAssociatedToMatch (const struct Mch_Match
|
||||||
/******************* Put a column for number of players **********************/
|
/******************* Put a column for number of players **********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mch_ListOneOrMoreMatchesNumPlayers (const struct Mch_Match *Match)
|
void Mch_ListOneOrMoreMatchesNumPlayers (const struct Mch_Match *Match)
|
||||||
{
|
{
|
||||||
/***** Number of players who have answered any question in the match ******/
|
/***** Number of players who have answered any question in the match ******/
|
||||||
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
@ -3728,35 +3725,6 @@ void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print)
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/******************** Compute match score for a student **********************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
void Mch_ComputeScore (struct MchPrn_Print *Print)
|
|
||||||
{
|
|
||||||
unsigned NumQst;
|
|
||||||
struct Qst_Question Question;
|
|
||||||
|
|
||||||
for (NumQst = 0, Print->Score = 0.0;
|
|
||||||
NumQst < Print->NumQsts.All;
|
|
||||||
NumQst++)
|
|
||||||
{
|
|
||||||
/***** Create test question *****/
|
|
||||||
Qst_QstConstructor (&Question);
|
|
||||||
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod;
|
|
||||||
Question.Answer.Type = Qst_ANS_UNIQUE_CHOICE;
|
|
||||||
|
|
||||||
/***** Compute score for this answer ******/
|
|
||||||
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],&Question);
|
|
||||||
|
|
||||||
/***** Update total score *****/
|
|
||||||
Print->Score += Print->PrintedQuestions[NumQst].Score;
|
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
|
||||||
Qst_QstDestructor (&Question);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************** Draw a bar with the percentage of answers *****************/
|
/***************** Draw a bar with the percentage of answers *****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -98,6 +98,9 @@ void Mch_ListMatches (struct Gam_Games *Games,
|
||||||
struct Gam_Game *Game,
|
struct Gam_Game *Game,
|
||||||
bool PutFormNewMatch);
|
bool PutFormNewMatch);
|
||||||
void Mch_GetDataOfMatchByCod (struct Mch_Match *Match);
|
void Mch_GetDataOfMatchByCod (struct Mch_Match *Match);
|
||||||
|
void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match);
|
||||||
|
void Mch_ListOneOrMoreMatchesTimes (const struct Mch_Match *Match,unsigned UniqueId);
|
||||||
|
void Mch_ListOneOrMoreMatchesNumPlayers (const struct Mch_Match *Match);
|
||||||
|
|
||||||
void Mch_ToggleVisResultsMchUsr (void);
|
void Mch_ToggleVisResultsMchUsr (void);
|
||||||
|
|
||||||
|
@ -150,8 +153,6 @@ void Mch_StoreQuestionAnswer (const struct Mch_Match *Match,unsigned QstInd,
|
||||||
|
|
||||||
void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print);
|
void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print);
|
||||||
|
|
||||||
void Mch_ComputeScore (struct MchPrn_Print *Print);
|
|
||||||
|
|
||||||
void Mch_DrawBarNumUsrs (unsigned NumRespondersAns,unsigned NumRespondersQst,bool Correct);
|
void Mch_DrawBarNumUsrs (unsigned NumRespondersAns,unsigned NumRespondersQst,bool Correct);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -297,6 +297,31 @@ unsigned Mch_DB_GetAvailableMatchesInGame (MYSQL_RES **mysql_res,long GamCod)
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************* Get matches between dates *************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Mch_DB_GetMatchesBetweenDates (MYSQL_RES **mysql_res,
|
||||||
|
const char *From,
|
||||||
|
const char *To)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get matches",
|
||||||
|
"SELECT GamCod," // row[ 0]
|
||||||
|
"MchCod," // row[ 1]
|
||||||
|
"UsrCod," // row[ 2]
|
||||||
|
"UNIX_TIMESTAMP(StartTime)," // row[ 3]
|
||||||
|
"UNIX_TIMESTAMP(EndTime)," // row[ 4]
|
||||||
|
"Title" // row[ 5]
|
||||||
|
" FROM mch_matches"
|
||||||
|
" WHERE StartTime>='%s'"
|
||||||
|
" AND StartTime<='%s'"
|
||||||
|
" ORDER BY GamCod,"
|
||||||
|
"MchCod",
|
||||||
|
From,
|
||||||
|
To);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/****************** Get parameter with what is being shown *******************/
|
/****************** Get parameter with what is being shown *******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -974,6 +999,34 @@ void Mch_DB_UpdateMatchPrint (const struct MchPrn_Print *Print)
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************* Update match print score **************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Mch_DB_UpdateMatchPrintScore (const struct MchPrn_Print *Print)
|
||||||
|
{
|
||||||
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
|
/*
|
||||||
|
DB_QueryUPDATE ("can not update match print",
|
||||||
|
"UPDATE mch_results"
|
||||||
|
" SET Score='%.15lg'"
|
||||||
|
" WHERE MchCod=%ld"
|
||||||
|
" AND UsrCod=%ld",
|
||||||
|
Print->Score,
|
||||||
|
Print->MchCod,
|
||||||
|
Print->UsrCod);
|
||||||
|
*/
|
||||||
|
HTM_TxtF ("UPDATE mch_results"
|
||||||
|
" SET Score='%.15lg'"
|
||||||
|
" WHERE MchCod=%ld"
|
||||||
|
" AND UsrCod=%ld",
|
||||||
|
Print->Score,
|
||||||
|
Print->MchCod,
|
||||||
|
Print->UsrCod);
|
||||||
|
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*********************** Check if match print exists *************************/
|
/*********************** Check if match print exists *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1018,6 +1071,23 @@ unsigned Mch_DB_GetMatchPrintData (MYSQL_RES **mysql_res,
|
||||||
Gbl.Hierarchy.Crs.CrsCod);
|
Gbl.Hierarchy.Crs.CrsCod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********* Get data of a match print using match code and user code **********/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Mch_DB_GetPrintsInMatch (MYSQL_RES **mysql_res,long MchCod)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get match prints",
|
||||||
|
"SELECT UsrCod," // row[0]
|
||||||
|
"NumQsts," // row[1]
|
||||||
|
"NumQstsNotBlank," // row[2]
|
||||||
|
"Score" // row[3]
|
||||||
|
" FROM mch_results"
|
||||||
|
" WHERE MchCod=%ld",
|
||||||
|
MchCod);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************ Get number of users who have played a given match **************/
|
/************ Get number of users who have played a given match **************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -44,6 +44,9 @@ unsigned Mch_DB_GetDataOfMatchByCod (MYSQL_RES **mysql_res,long MchCod);
|
||||||
unsigned Mch_DB_GetStartEndMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
unsigned Mch_DB_GetStartEndMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
||||||
unsigned Mch_DB_GetMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
unsigned Mch_DB_GetMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
||||||
unsigned Mch_DB_GetAvailableMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
unsigned Mch_DB_GetAvailableMatchesInGame (MYSQL_RES **mysql_res,long GamCod);
|
||||||
|
unsigned Mch_DB_GetMatchesBetweenDates (MYSQL_RES **mysql_res,
|
||||||
|
const char *From,
|
||||||
|
const char *To);
|
||||||
Mch_Showing_t Mch_DB_GetShowingFromStr (const char *Str);
|
Mch_Showing_t Mch_DB_GetShowingFromStr (const char *Str);
|
||||||
unsigned Mch_DB_GetNumMchsInGame (long GamCod);
|
unsigned Mch_DB_GetNumMchsInGame (long GamCod);
|
||||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod);
|
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod);
|
||||||
|
@ -110,10 +113,12 @@ unsigned Mch_DB_GetElapsedTimeInMatch (MYSQL_RES **mysql_res,long MchCod);
|
||||||
//----------------------------- Match results ---------------------------------
|
//----------------------------- Match results ---------------------------------
|
||||||
void Mch_DB_CreateMatchPrint (const struct MchPrn_Print *Print);
|
void Mch_DB_CreateMatchPrint (const struct MchPrn_Print *Print);
|
||||||
void Mch_DB_UpdateMatchPrint (const struct MchPrn_Print *Print);
|
void Mch_DB_UpdateMatchPrint (const struct MchPrn_Print *Print);
|
||||||
|
void Mch_DB_UpdateMatchPrintScore (const struct MchPrn_Print *Print);
|
||||||
|
|
||||||
bool Mch_DB_CheckIfMatchPrintExists (const struct MchPrn_Print *Print);
|
bool Mch_DB_CheckIfMatchPrintExists (const struct MchPrn_Print *Print);
|
||||||
unsigned Mch_DB_GetMatchPrintData (MYSQL_RES **mysql_res,
|
unsigned Mch_DB_GetMatchPrintData (MYSQL_RES **mysql_res,
|
||||||
const struct MchPrn_Print *Print);
|
const struct MchPrn_Print *Print);
|
||||||
|
unsigned Mch_DB_GetPrintsInMatch (MYSQL_RES **mysql_res,long MchCod);
|
||||||
unsigned Mch_DB_GetNumUsrsWhoHavePlayedMch (long MchCod);
|
unsigned Mch_DB_GetNumUsrsWhoHavePlayedMch (long MchCod);
|
||||||
unsigned Mch_DB_GetUsrsWhoHavePlayedMch (MYSQL_RES **mysql_res,long MchCod);
|
unsigned Mch_DB_GetUsrsWhoHavePlayedMch (MYSQL_RES **mysql_res,long MchCod);
|
||||||
unsigned Mch_DB_GetUsrsWhoHavePlayedGam (MYSQL_RES **mysql_res,long GamCod);
|
unsigned Mch_DB_GetUsrsWhoHavePlayedGam (MYSQL_RES **mysql_res,long GamCod);
|
||||||
|
|
|
@ -25,8 +25,11 @@
|
||||||
/********************************* Headers ***********************************/
|
/********************************* Headers ***********************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#include <math.h> // For fabs
|
||||||
|
|
||||||
#include "swad_database.h"
|
#include "swad_database.h"
|
||||||
#include "swad_date.h"
|
#include "swad_date.h"
|
||||||
|
#include "swad_error.h"
|
||||||
#include "swad_global.h"
|
#include "swad_global.h"
|
||||||
#include "swad_match.h"
|
#include "swad_match.h"
|
||||||
#include "swad_match_database.h"
|
#include "swad_match_database.h"
|
||||||
|
@ -42,8 +45,11 @@ extern struct Globals Gbl;
|
||||||
/***************************** Private prototypes ****************************/
|
/***************************** Private prototypes ****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void MchPrn_ComputeScore (struct MchPrn_Print *Print);
|
||||||
static void MchPrn_UpdateMatchPrintInDB (const struct MchPrn_Print *Print);
|
static void MchPrn_UpdateMatchPrintInDB (const struct MchPrn_Print *Print);
|
||||||
|
|
||||||
|
static void MchPrn_ListPrintsToFix (long MchCod);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**************************** Reset match print ******************************/
|
/**************************** Reset match print ******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -72,12 +78,41 @@ void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod)
|
||||||
Print.MchCod = MchCod;
|
Print.MchCod = MchCod;
|
||||||
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||||
Mch_GetMatchQuestionsFromDB (&Print);
|
Mch_GetMatchQuestionsFromDB (&Print);
|
||||||
Mch_ComputeScore (&Print);
|
MchPrn_ComputeScore (&Print);
|
||||||
|
|
||||||
/***** Update my match result in database *****/
|
/***** Update my match result in database *****/
|
||||||
MchPrn_UpdateMatchPrintInDB (&Print);
|
MchPrn_UpdateMatchPrintInDB (&Print);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************** Compute match print score for a student *******************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void MchPrn_ComputeScore (struct MchPrn_Print *Print)
|
||||||
|
{
|
||||||
|
unsigned NumQst;
|
||||||
|
struct Qst_Question Question;
|
||||||
|
|
||||||
|
for (NumQst = 0, Print->Score = 0.0;
|
||||||
|
NumQst < Print->NumQsts.All;
|
||||||
|
NumQst++)
|
||||||
|
{
|
||||||
|
/***** Create test question *****/
|
||||||
|
Qst_QstConstructor (&Question);
|
||||||
|
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod;
|
||||||
|
Question.Answer.Type = Qst_ANS_UNIQUE_CHOICE;
|
||||||
|
|
||||||
|
/***** Compute score for this answer ******/
|
||||||
|
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],&Question);
|
||||||
|
|
||||||
|
/***** Update total score *****/
|
||||||
|
Print->Score += Print->PrintedQuestions[NumQst].Score;
|
||||||
|
|
||||||
|
/***** Destroy test question *****/
|
||||||
|
Qst_QstDestructor (&Question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************************* Create/update match print *************************/
|
/************************* Create/update match print *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -133,3 +168,232 @@ void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******** Recompute scores stored in match prints made on 2021-11-25 *********/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void MchPrn_PutLinkToFixMatchesPrintsScores (void)
|
||||||
|
{
|
||||||
|
Lay_PutContextualLinkIconText (ActFixMchSco,NULL,
|
||||||
|
NULL,NULL,
|
||||||
|
"recycle.svg",
|
||||||
|
"Recalcular puntuación partidas");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MchPrn_FixMatchesPrintsScores (void)
|
||||||
|
{
|
||||||
|
extern const char *Txt_Matches;
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumMatches;
|
||||||
|
unsigned NumMatch;
|
||||||
|
unsigned UniqueId;
|
||||||
|
struct Mch_Match Match;
|
||||||
|
Dat_StartEndTime_t StartEndTime;
|
||||||
|
|
||||||
|
/***** Reset match *****/
|
||||||
|
Mch_ResetMatch (&Match);
|
||||||
|
|
||||||
|
Box_BoxBegin ("100%",Txt_Matches,
|
||||||
|
NULL,NULL,
|
||||||
|
NULL,Box_NOT_CLOSABLE);
|
||||||
|
|
||||||
|
/***** Get data of matches from database *****/
|
||||||
|
NumMatches = Mch_DB_GetMatchesBetweenDates (&mysql_res,
|
||||||
|
"2021-11-24 20:00:00", // From
|
||||||
|
"2021-11-25 16:00:00"); // To
|
||||||
|
|
||||||
|
/***** Begin table *****/
|
||||||
|
HTM_TABLE_BeginWidePadding (2);
|
||||||
|
|
||||||
|
/***** Write rows *****/
|
||||||
|
for (NumMatch = 0, UniqueId = 1;
|
||||||
|
NumMatch < NumMatches;
|
||||||
|
NumMatch++, UniqueId++)
|
||||||
|
{
|
||||||
|
Gbl.RowEvenOdd = NumMatch % 2;
|
||||||
|
|
||||||
|
/***** Get match data *****/
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
/*
|
||||||
|
row[0]: GamCod
|
||||||
|
row[1]: MchCod
|
||||||
|
row[2]: UsrCod
|
||||||
|
row[3]: UNIX_TIMESTAMP(StartTime)
|
||||||
|
row[4]: UNIX_TIMESTAMP(EndTime)
|
||||||
|
row[5]: Title
|
||||||
|
*/
|
||||||
|
/* Code of the game (row[0]) */
|
||||||
|
if ((Match.GamCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
|
||||||
|
Err_WrongGameExit ();
|
||||||
|
|
||||||
|
/* Code of the match (row[1]) */
|
||||||
|
if ((Match.MchCod = Str_ConvertStrCodToLongCod (row[1])) <= 0)
|
||||||
|
Err_WrongMatchExit ();
|
||||||
|
|
||||||
|
/* Get match teacher (row[2]) */
|
||||||
|
Match.UsrCod = Str_ConvertStrCodToLongCod (row[2]);
|
||||||
|
|
||||||
|
/* Get start/end times (row[3], row[4] hold start/end UTC times) */
|
||||||
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
||||||
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
||||||
|
StartEndTime++)
|
||||||
|
Match.TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[3 + StartEndTime]);
|
||||||
|
|
||||||
|
/* Get the title of the match (row[5]) */
|
||||||
|
if (row[5])
|
||||||
|
Str_Copy (Match.Title,row[5],sizeof (Match.Title) - 1);
|
||||||
|
else
|
||||||
|
Match.Title[0] = '\0';
|
||||||
|
|
||||||
|
/***** List match *****/
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
/* Game code */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("GamCod: ");
|
||||||
|
HTM_Long (Match.GamCod);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Match code */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("MchCod: ");
|
||||||
|
HTM_Long (Match.MchCod);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Match author */
|
||||||
|
Mch_ListOneOrMoreMatchesAuthor (&Match);
|
||||||
|
|
||||||
|
/* Start/end date/time */
|
||||||
|
Mch_ListOneOrMoreMatchesTimes (&Match,UniqueId);
|
||||||
|
|
||||||
|
/* Match title */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt (Match.Title);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Number of players who have played the match */
|
||||||
|
Mch_ListOneOrMoreMatchesNumPlayers (&Match);
|
||||||
|
|
||||||
|
/* Filling */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
/***** Match prints *****/
|
||||||
|
MchPrn_ListPrintsToFix (Match.MchCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** End table *****/
|
||||||
|
HTM_TABLE_End ();
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** End box *****/
|
||||||
|
Box_BoxEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MchPrn_ListPrintsToFix (long MchCod)
|
||||||
|
{
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumPrints;
|
||||||
|
unsigned NumPrint;
|
||||||
|
struct MchPrn_Print Print;
|
||||||
|
double StoredScore;
|
||||||
|
|
||||||
|
/***** Get data of prints from database *****/
|
||||||
|
NumPrints = Mch_DB_GetPrintsInMatch (&mysql_res,MchCod);
|
||||||
|
|
||||||
|
/***** Write rows *****/
|
||||||
|
for (NumPrint = 0;
|
||||||
|
NumPrint < NumPrints;
|
||||||
|
NumPrint++)
|
||||||
|
{
|
||||||
|
/***** Get match print data *****/
|
||||||
|
Print.MchCod = MchCod;
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
/*
|
||||||
|
row[0]: UsrCod
|
||||||
|
row[1]: NumQsts
|
||||||
|
row[2]: NumQstsNotBlank
|
||||||
|
row[3]: Score
|
||||||
|
*/
|
||||||
|
/* Get student code (row[0]) */
|
||||||
|
Print.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
|
||||||
|
|
||||||
|
/* Get number of questions (row[1]) */
|
||||||
|
if (sscanf (row[1],"%u",&Print.NumQsts.All) != 1)
|
||||||
|
Print.NumQsts.All = 0;
|
||||||
|
|
||||||
|
/* Get number of questions not blank (row[2]) */
|
||||||
|
if (sscanf (row[2],"%u",&Print.NumQsts.NotBlank) != 1)
|
||||||
|
Print.NumQsts.NotBlank = 0;
|
||||||
|
|
||||||
|
/* Get score (row[3]) */
|
||||||
|
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
||||||
|
if (sscanf (row[3],"%lf",&StoredScore) != 1)
|
||||||
|
StoredScore = 0.0;
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
|
||||||
|
/***** Write row *****/
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
/* Indent */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_TD_End ();
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Student */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
Usr_WriteAuthor1Line (Print.UsrCod,false);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Number of questions */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("NumQsts: ");
|
||||||
|
HTM_Unsigned (Print.NumQsts.All);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Number of questions not blank */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("NumQstsNotBlank: ");
|
||||||
|
HTM_Unsigned (Print.NumQsts.NotBlank);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Stored score */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("Stored score: ");
|
||||||
|
HTM_Double (StoredScore);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Compute score */
|
||||||
|
Mch_GetMatchQuestionsFromDB (&Print);
|
||||||
|
MchPrn_ComputeScore (&Print);
|
||||||
|
|
||||||
|
/* Computed score */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("Computed score: ");
|
||||||
|
HTM_Double (Print.Score);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Store computed score? */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
if (fabs (StoredScore-Print.Score) < 0.0000000001)
|
||||||
|
HTM_Txt ("=");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HTM_Txt ("!");
|
||||||
|
Mch_DB_UpdateMatchPrintScore (&Print);
|
||||||
|
}
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
}
|
||||||
|
|
|
@ -59,4 +59,7 @@ void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod);
|
||||||
|
|
||||||
void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
|
void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
|
||||||
|
|
||||||
|
void MchPrn_PutLinkToFixMatchesPrintsScores (void);
|
||||||
|
void MchPrn_FixMatchesPrintsScores (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -119,7 +119,7 @@ void MchRes_ShowMyMchResultsInCrs (void)
|
||||||
|
|
||||||
/***** List my matches results in the current course *****/
|
/***** List my matches results in the current course *****/
|
||||||
MchRes_ShowResultsBegin (&Games,Txt_Results,true); // List games to select
|
MchRes_ShowResultsBegin (&Games,Txt_Results,true); // List games to select
|
||||||
MchRes_ListMyMchResultsInCrs (&Games);
|
MchRes_ListMyMchResultsInCrs (&Games);
|
||||||
MchRes_ShowResultsEnd ();
|
MchRes_ShowResultsEnd ();
|
||||||
|
|
||||||
/***** Free list of games *****/
|
/***** Free list of games *****/
|
||||||
|
@ -172,7 +172,7 @@ void MchRes_ShowMyMchResultsInGam (void)
|
||||||
Str_BuildStringStr (Txt_Results_of_game_X,Game.Title),
|
Str_BuildStringStr (Txt_Results_of_game_X,Game.Title),
|
||||||
false); // Do not list games to select
|
false); // Do not list games to select
|
||||||
Str_FreeString ();
|
Str_FreeString ();
|
||||||
MchRes_ListMyMchResultsInGam (&Games,Game.GamCod);
|
MchRes_ListMyMchResultsInGam (&Games,Game.GamCod);
|
||||||
MchRes_ShowResultsEnd ();
|
MchRes_ShowResultsEnd ();
|
||||||
|
|
||||||
/***** Game end *****/
|
/***** Game end *****/
|
||||||
|
@ -224,7 +224,7 @@ void MchRes_ShowMyMchResultsInMch (void)
|
||||||
MchRes_ShowResultsBegin (&Games,Str_BuildStringStr (Txt_Results_of_match_X,Match.Title),
|
MchRes_ShowResultsBegin (&Games,Str_BuildStringStr (Txt_Results_of_match_X,Match.Title),
|
||||||
false); // Do not list games to select
|
false); // Do not list games to select
|
||||||
Str_FreeString ();
|
Str_FreeString ();
|
||||||
MchRes_ListMyMchResultsInMch (&Games,Match.MchCod);
|
MchRes_ListMyMchResultsInMch (&Games,Match.MchCod);
|
||||||
MchRes_ShowResultsEnd ();
|
MchRes_ShowResultsEnd ();
|
||||||
|
|
||||||
/***** Game end *****/
|
/***** Game end *****/
|
||||||
|
@ -277,7 +277,7 @@ static void MchRes_ShowAllMchResultsInSelectedGames (void *Games)
|
||||||
MchRes_ShowResultsBegin ((struct Gam_Games *) Games,
|
MchRes_ShowResultsBegin ((struct Gam_Games *) Games,
|
||||||
Txt_Results,
|
Txt_Results,
|
||||||
true); // List games to select
|
true); // List games to select
|
||||||
MchRes_ListAllMchResultsInSelectedGames ((struct Gam_Games *) Games);
|
MchRes_ListAllMchResultsInSelectedGames ((struct Gam_Games *) Games);
|
||||||
MchRes_ShowResultsEnd ();
|
MchRes_ShowResultsEnd ();
|
||||||
|
|
||||||
/***** Free list of games *****/
|
/***** Free list of games *****/
|
||||||
|
@ -376,7 +376,7 @@ void MchRes_ShowAllMchResultsInGam (void)
|
||||||
Str_BuildStringStr (Txt_Results_of_game_X,Game.Title),
|
Str_BuildStringStr (Txt_Results_of_game_X,Game.Title),
|
||||||
false); // Do not list games to select
|
false); // Do not list games to select
|
||||||
Str_FreeString ();
|
Str_FreeString ();
|
||||||
MchRes_ListAllMchResultsInGam (&Games,Game.GamCod);
|
MchRes_ListAllMchResultsInGam (&Games,Game.GamCod);
|
||||||
MchRes_ShowResultsEnd ();
|
MchRes_ShowResultsEnd ();
|
||||||
|
|
||||||
/***** Game end *****/
|
/***** Game end *****/
|
||||||
|
@ -451,7 +451,7 @@ void MchRes_ShowAllMchResultsInMch (void)
|
||||||
Str_BuildStringStr (Txt_Results_of_match_X,Match.Title),
|
Str_BuildStringStr (Txt_Results_of_match_X,Match.Title),
|
||||||
false); // Do not list games to select
|
false); // Do not list games to select
|
||||||
Str_FreeString ();
|
Str_FreeString ();
|
||||||
MchRes_ListAllMchResultsInMch (&Games,Match.MchCod);
|
MchRes_ListAllMchResultsInMch (&Games,Match.MchCod);
|
||||||
MchRes_ShowResultsEnd ();
|
MchRes_ShowResultsEnd ();
|
||||||
|
|
||||||
/***** Game end *****/
|
/***** Game end *****/
|
||||||
|
@ -913,7 +913,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
|
||||||
TotalScore,
|
TotalScore,
|
||||||
TotalGrade);
|
TotalGrade);
|
||||||
}
|
}
|
||||||
else
|
else // No results
|
||||||
{
|
{
|
||||||
/* Columns for dates and match */
|
/* Columns for dates and match */
|
||||||
HTM_TD_Begin ("colspan=\"3\" class=\"LINE_BOTTOM COLOR%u\"",
|
HTM_TD_Begin ("colspan=\"3\" class=\"LINE_BOTTOM COLOR%u\"",
|
||||||
|
|
|
@ -149,6 +149,32 @@ void Qst_DB_UpdateQstScore (long QstCod,bool AnswerIsNotBlank,double Score)
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************* Fix the score of a question ***********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Qst_DB_FixQstScore (long QstCod,bool AnswerIsNotBlank,
|
||||||
|
double BadScore,double GoodScore)
|
||||||
|
{
|
||||||
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
|
if (AnswerIsNotBlank) // User's answer is not blank
|
||||||
|
DB_QueryUPDATE ("can not update the score of a question",
|
||||||
|
"UPDATE tst_questions"
|
||||||
|
" SET Score=Score-(%.15lg)+(%.15lg)"
|
||||||
|
" WHERE QstCod=%ld",
|
||||||
|
BadScore,GoodScore,
|
||||||
|
QstCod);
|
||||||
|
/*
|
||||||
|
Ale_ShowAlert (Ale_INFO,
|
||||||
|
"UPDATE tst_questions"
|
||||||
|
" SET Score=Score-(%.15lg)+(%.15lg)"
|
||||||
|
" WHERE QstCod=%ld",
|
||||||
|
BadScore,GoodScore,
|
||||||
|
QstCod);
|
||||||
|
*/
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*********************** Change the shuffle of a question ********************/
|
/*********************** Change the shuffle of a question ********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
long Qst_DB_CreateQst (const struct Qst_Question *Question);
|
long Qst_DB_CreateQst (const struct Qst_Question *Question);
|
||||||
void Qst_DB_UpdateQst (const struct Qst_Question *Question);
|
void Qst_DB_UpdateQst (const struct Qst_Question *Question);
|
||||||
void Qst_DB_UpdateQstScore (long QstCod,bool AnswerIsNotBlank,double Score);
|
void Qst_DB_UpdateQstScore (long QstCod,bool AnswerIsNotBlank,double Score);
|
||||||
|
void Qst_DB_FixQstScore (long QstCod,bool AnswerIsNotBlank,
|
||||||
|
double BadScore,double GoodScore);
|
||||||
void Qst_DB_UpdateQstShuffle (long QstCod,bool Shuffle);
|
void Qst_DB_UpdateQstShuffle (long QstCod,bool Shuffle);
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Qst_DB_CreateIntAnswer (struct Qst_Question *Question);
|
void Qst_DB_CreateIntAnswer (struct Qst_Question *Question);
|
||||||
|
|
|
@ -276,7 +276,8 @@ void Tst_ReceiveTestDraft (void)
|
||||||
else // Print not yet sent
|
else // Print not yet sent
|
||||||
{
|
{
|
||||||
/***** Get test print questions from database *****/
|
/***** Get test print questions from database *****/
|
||||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
if (!TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||||
|
Err_WrongExamExit ();
|
||||||
|
|
||||||
/***** Get answers from form to assess a test *****/
|
/***** Get answers from form to assess a test *****/
|
||||||
TstPrn_GetAnswersFromForm (&Print);
|
TstPrn_GetAnswersFromForm (&Print);
|
||||||
|
@ -332,7 +333,8 @@ void Tst_AssessTest (void)
|
||||||
else // Print not yet sent
|
else // Print not yet sent
|
||||||
{
|
{
|
||||||
/***** Get test print questions from database *****/
|
/***** Get test print questions from database *****/
|
||||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
if (!TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||||
|
Err_WrongExamExit ();
|
||||||
|
|
||||||
/***** Get answers from form to assess a test *****/
|
/***** Get answers from form to assess a test *****/
|
||||||
TstPrn_GetAnswersFromForm (&Print);
|
TstPrn_GetAnswersFromForm (&Print);
|
||||||
|
|
|
@ -241,6 +241,54 @@ void Tst_DB_UpdatePrint (const struct TstPrn_Print *Print)
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************** Update test print score **************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tst_DB_UpdatePrintScore (const struct TstPrn_Print *Print)
|
||||||
|
{
|
||||||
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
|
DB_QueryUPDATE ("can not update match print",
|
||||||
|
"UPDATE tst_exams"
|
||||||
|
" SET Score='%.15lg'"
|
||||||
|
" WHERE ExaCod=%ld",
|
||||||
|
Print->Score,
|
||||||
|
Print->PrnCod);
|
||||||
|
/*
|
||||||
|
HTM_TxtF ("UPDATE tst_exams"
|
||||||
|
" SET Score='%.15lg'"
|
||||||
|
" WHERE ExaCod=%ld",
|
||||||
|
Print->Score,
|
||||||
|
Print->PrnCod);
|
||||||
|
*/
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************ Get test prints between dates **********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Tst_DB_GetPrintsBetweenDates (MYSQL_RES **mysql_res,
|
||||||
|
const char *From,
|
||||||
|
const char *To)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get prints",
|
||||||
|
"SELECT ExaCod," // row[0]
|
||||||
|
"UsrCod," // row[1]
|
||||||
|
"UNIX_TIMESTAMP(StartTime)," // row[2]
|
||||||
|
"UNIX_TIMESTAMP(EndTime)," // row[3]
|
||||||
|
"NumQsts," // row[4]
|
||||||
|
"NumQstsNotBlank," // row[5]
|
||||||
|
"Score" // row[6]
|
||||||
|
" FROM tst_exams"
|
||||||
|
" WHERE StartTime>='%s'"
|
||||||
|
" AND StartTime<='%s'"
|
||||||
|
" ORDER BY ExaCod",
|
||||||
|
From,
|
||||||
|
To);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************ Get the test prints of a user in the current course ************/
|
/************ Get the test prints of a user in the current course ************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -351,6 +399,41 @@ void Tst_DB_StoreOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************ Store user's answers of an test print into database ************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tst_DB_FixOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd)
|
||||||
|
{
|
||||||
|
/***** Insert question and user's answers into database *****/
|
||||||
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
|
DB_QueryREPLACE ("can not update a question of a test",
|
||||||
|
"REPLACE INTO tst_exam_questions"
|
||||||
|
" (ExaCod,QstCod,QstInd,Score,Indexes,Answers)"
|
||||||
|
" VALUES"
|
||||||
|
" (%ld,%ld,%u,'%.15lg','%s','%s')",
|
||||||
|
Print->PrnCod,
|
||||||
|
Print->PrintedQuestions[QstInd].QstCod,
|
||||||
|
QstInd, // 0, 1, 2, 3...
|
||||||
|
Print->PrintedQuestions[QstInd].Score,
|
||||||
|
Print->PrintedQuestions[QstInd].StrIndexes,
|
||||||
|
Print->PrintedQuestions[QstInd].StrAnswers);
|
||||||
|
/*
|
||||||
|
Ale_ShowAlert (Ale_INFO,
|
||||||
|
"REPLACE INTO tst_exam_questions"
|
||||||
|
" (ExaCod,QstCod,QstInd,Score,Indexes,Answers)"
|
||||||
|
" VALUES"
|
||||||
|
" (%ld,%ld,%u,'%.15lg','%s','%s')",
|
||||||
|
Print->PrnCod,
|
||||||
|
Print->PrintedQuestions[QstInd].QstCod,
|
||||||
|
QstInd, // 0, 1, 2, 3...
|
||||||
|
Print->PrintedQuestions[QstInd].Score,
|
||||||
|
Print->PrintedQuestions[QstInd].StrIndexes,
|
||||||
|
Print->PrintedQuestions[QstInd].StrAnswers);
|
||||||
|
*/
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**************** Get all tags of questions in a test print ******************/
|
/**************** Get all tags of questions in a test print ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -358,7 +441,7 @@ void Tst_DB_StoreOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd
|
||||||
unsigned Tst_DB_GetTagsPresentInAPrint (MYSQL_RES **mysql_res,long PrnCod)
|
unsigned Tst_DB_GetTagsPresentInAPrint (MYSQL_RES **mysql_res,long PrnCod)
|
||||||
{
|
{
|
||||||
return (unsigned)
|
return (unsigned)
|
||||||
DB_QuerySELECT (mysql_res,"can not get tags present in a test",
|
DB_QuerySELECT (mysql_res,"can not get tags present in a test print",
|
||||||
"SELECT tst_tags.TagTxt" // row[0]
|
"SELECT tst_tags.TagTxt" // row[0]
|
||||||
" FROM (SELECT DISTINCT "
|
" FROM (SELECT DISTINCT "
|
||||||
"tst_question_tags.TagCod"
|
"tst_question_tags.TagCod"
|
||||||
|
@ -379,7 +462,7 @@ unsigned Tst_DB_GetTagsPresentInAPrint (MYSQL_RES **mysql_res,long PrnCod)
|
||||||
unsigned Tst_DB_GetPrintQuestions (MYSQL_RES **mysql_res,long PrnCod)
|
unsigned Tst_DB_GetPrintQuestions (MYSQL_RES **mysql_res,long PrnCod)
|
||||||
{
|
{
|
||||||
return (unsigned)
|
return (unsigned)
|
||||||
DB_QuerySELECT (mysql_res,"can not get questions of a test",
|
DB_QuerySELECT (mysql_res,"can not get questions of a test print",
|
||||||
"SELECT QstCod," // row[0]
|
"SELECT QstCod," // row[0]
|
||||||
"Score," // row[1]
|
"Score," // row[1]
|
||||||
"Indexes," // row[2]
|
"Indexes," // row[2]
|
||||||
|
|
|
@ -50,7 +50,11 @@ void Tst_DB_RemoveTstConfig (long CrsCod);
|
||||||
//------------------------------- Test prints ---------------------------------
|
//------------------------------- Test prints ---------------------------------
|
||||||
long Tst_DB_CreatePrint (unsigned NumQsts);
|
long Tst_DB_CreatePrint (unsigned NumQsts);
|
||||||
void Tst_DB_UpdatePrint (const struct TstPrn_Print *Print);
|
void Tst_DB_UpdatePrint (const struct TstPrn_Print *Print);
|
||||||
|
void Tst_DB_UpdatePrintScore (const struct TstPrn_Print *Print);
|
||||||
|
|
||||||
|
unsigned Tst_DB_GetPrintsBetweenDates (MYSQL_RES **mysql_res,
|
||||||
|
const char *From,
|
||||||
|
const char *To);
|
||||||
unsigned Tst_DB_GetUsrPrintsInCurrentCrs (MYSQL_RES **mysql_res,long UsrCod);
|
unsigned Tst_DB_GetUsrPrintsInCurrentCrs (MYSQL_RES **mysql_res,long UsrCod);
|
||||||
unsigned Tst_DB_GetPrintDataByPrnCod (MYSQL_RES **mysql_res,long PrnCod);
|
unsigned Tst_DB_GetPrintDataByPrnCod (MYSQL_RES **mysql_res,long PrnCod);
|
||||||
|
|
||||||
|
@ -60,6 +64,7 @@ void Tst_DB_RemovePrintsMadeByInCrs (long CrsCod);
|
||||||
|
|
||||||
//-------------------------- Test print questions -----------------------------
|
//-------------------------- Test print questions -----------------------------
|
||||||
void Tst_DB_StoreOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd);
|
void Tst_DB_StoreOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd);
|
||||||
|
void Tst_DB_FixOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd);
|
||||||
|
|
||||||
unsigned Tst_DB_GetTagsPresentInAPrint (MYSQL_RES **mysql_res,long PrnCod);
|
unsigned Tst_DB_GetTagsPresentInAPrint (MYSQL_RES **mysql_res,long PrnCod);
|
||||||
unsigned Tst_DB_GetPrintQuestions (MYSQL_RES **mysql_res,long PrnCod);
|
unsigned Tst_DB_GetPrintQuestions (MYSQL_RES **mysql_res,long PrnCod);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define _GNU_SOURCE // For asprintf
|
#define _GNU_SOURCE // For asprintf
|
||||||
|
#include <math.h> // For fabs
|
||||||
#include <stdbool.h> // For boolean type
|
#include <stdbool.h> // For boolean type
|
||||||
#include <stddef.h> // For NULL
|
#include <stddef.h> // For NULL
|
||||||
#include <stdio.h> // For asprintf
|
#include <stdio.h> // For asprintf
|
||||||
|
@ -167,6 +168,8 @@ static void TstRes_CheckIfICanSeePrintResult (const struct TstPrn_Print *Print,
|
||||||
|
|
||||||
static void TstPrn_ShowTagsPresentInAPrint (long PrnCod);
|
static void TstPrn_ShowTagsPresentInAPrint (long PrnCod);
|
||||||
|
|
||||||
|
static void TstPrn_ComputeScoresAndFixQuestionsOfPrint (struct TstPrn_Print *Print);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Reset test print ******************************/
|
/***************************** Reset test print ******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2174,7 +2177,8 @@ void TstPrn_ShowOnePrint (void)
|
||||||
if (ICanView.Result) // I am allowed to view this test print result
|
if (ICanView.Result) // I am allowed to view this test print result
|
||||||
{
|
{
|
||||||
/***** Get questions and user's answers of the test from database *****/
|
/***** Get questions and user's answers of the test from database *****/
|
||||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
if (!TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||||
|
Err_WrongExamExit ();
|
||||||
|
|
||||||
/***** Begin box *****/
|
/***** Begin box *****/
|
||||||
Box_BoxBegin (NULL,Txt_Result,
|
Box_BoxBegin (NULL,Txt_Result,
|
||||||
|
@ -2490,7 +2494,7 @@ void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
||||||
/************* Get the questions of a test print from database ***************/
|
/************* Get the questions of a test print from database ***************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
bool TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
@ -2529,8 +2533,7 @@ void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
if (NumQsts != Print->NumQsts.All)
|
return (NumQsts == Print->NumQsts.All);
|
||||||
Err_WrongExamExit ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2608,3 +2611,226 @@ unsigned TstPrn_GetNumPrintsGeneratedByMe (void)
|
||||||
|
|
||||||
return NumPrintsGeneratedByMe;
|
return NumPrintsGeneratedByMe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********* Recompute scores stored in test prints made on 2021-11-25 *********/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void TstPrn_PutLinkToFixTestsPrintsScores (void)
|
||||||
|
{
|
||||||
|
Lay_PutContextualLinkIconText (ActFixTstSco,NULL,
|
||||||
|
NULL,NULL,
|
||||||
|
"recycle.svg",
|
||||||
|
"Recalcular puntuación tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstPrn_FixTestsPrintsScores (void)
|
||||||
|
{
|
||||||
|
extern const char *Txt_Results;
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumPrints;
|
||||||
|
unsigned NumPrint;
|
||||||
|
unsigned UniqueId;
|
||||||
|
char *Id;
|
||||||
|
struct TstPrn_Print Print;
|
||||||
|
long UsrCod;
|
||||||
|
Dat_StartEndTime_t StartEndTime;
|
||||||
|
double StoredScore;
|
||||||
|
|
||||||
|
/***** Reset match *****/
|
||||||
|
Box_BoxBegin ("100%",Txt_Results,
|
||||||
|
NULL,NULL,
|
||||||
|
NULL,Box_NOT_CLOSABLE);
|
||||||
|
|
||||||
|
/***** Get data of matches from database *****/
|
||||||
|
NumPrints = Tst_DB_GetPrintsBetweenDates (&mysql_res,
|
||||||
|
"2021-11-24 20:00:00", // From
|
||||||
|
"2021-11-25 16:00:00"); // To
|
||||||
|
|
||||||
|
/***** Begin table *****/
|
||||||
|
HTM_TABLE_BeginWidePadding (2);
|
||||||
|
|
||||||
|
/***** Write rows *****/
|
||||||
|
for (NumPrint = 0, UniqueId = 1;
|
||||||
|
NumPrint < NumPrints;
|
||||||
|
NumPrint++, UniqueId++)
|
||||||
|
{
|
||||||
|
Gbl.RowEvenOdd = NumPrint % 2;
|
||||||
|
|
||||||
|
/***** Get match data *****/
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
/*
|
||||||
|
row[0]: ExaCod
|
||||||
|
row[1]: UsrCod
|
||||||
|
row[2]: UNIX_TIMESTAMP(StartTime)
|
||||||
|
row[3]: UNIX_TIMESTAMP(EndTime)
|
||||||
|
row[4]: NumQsts
|
||||||
|
row[5]: NumQstsNotBlank
|
||||||
|
row[6]: Score
|
||||||
|
*/
|
||||||
|
/* Code of the print (row[0]) */
|
||||||
|
if ((Print.PrnCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
|
||||||
|
Err_WrongGameExit ();
|
||||||
|
|
||||||
|
/* Get user code (row[1]) */
|
||||||
|
UsrCod = Str_ConvertStrCodToLongCod (row[1]);
|
||||||
|
|
||||||
|
/* Get start/end times (row[2], row[3] hold start/end UTC times) */
|
||||||
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
||||||
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
||||||
|
StartEndTime++)
|
||||||
|
Print.TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[2 + StartEndTime]);
|
||||||
|
|
||||||
|
/* Get number of questions (row[4]) */
|
||||||
|
if (sscanf (row[4],"%u",&Print.NumQsts.All) != 1)
|
||||||
|
Print.NumQsts.All = 0;
|
||||||
|
|
||||||
|
/* Get number of questions not blank (row[5]) */
|
||||||
|
if (sscanf (row[5],"%u",&Print.NumQsts.NotBlank) != 1)
|
||||||
|
Print.NumQsts.NotBlank = 0;
|
||||||
|
|
||||||
|
/* Get score (row[6]) */
|
||||||
|
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
||||||
|
if (sscanf (row[6],"%lf",&StoredScore) != 1)
|
||||||
|
StoredScore = 0.0;
|
||||||
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
|
|
||||||
|
/***** List print *****/
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
/* Print code */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("PrnCod: ");
|
||||||
|
HTM_Long (Print.PrnCod);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Student */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
Usr_WriteAuthor1Line (UsrCod,false);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Write dates and times */
|
||||||
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
||||||
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
||||||
|
StartEndTime++)
|
||||||
|
{
|
||||||
|
if (asprintf (&Id,"tst_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
HTM_TD_Begin ("id=\"%s\" class=\"DAT LT COLOR%u\"",
|
||||||
|
Id,Gbl.RowEvenOdd);
|
||||||
|
Dat_WriteLocalDateHMSFromUTC (Id,Print.TimeUTC[StartEndTime],
|
||||||
|
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
|
||||||
|
true,true,false,0x7);
|
||||||
|
HTM_TD_End ();
|
||||||
|
free (Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Number of questions */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("NumQsts: ");
|
||||||
|
HTM_Unsigned (Print.NumQsts.All);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Number of questions not blank */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("NumQstsNotBlank: ");
|
||||||
|
HTM_Unsigned (Print.NumQsts.NotBlank);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Stored score */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_Txt ("Stored score: ");
|
||||||
|
HTM_Double (StoredScore);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Compute score */
|
||||||
|
if (TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||||
|
{
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
TstPrn_ComputeScoresAndFixQuestionsOfPrint (&Print);
|
||||||
|
HTM_Txt ("Computed score: ");
|
||||||
|
HTM_Double (Print.Score);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/* Store computed score? */
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
if (fabs (StoredScore-Print.Score) < 0.0000000001)
|
||||||
|
HTM_Txt ("=");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HTM_Txt ("!");
|
||||||
|
Tst_DB_UpdatePrintScore (&Print);
|
||||||
|
}
|
||||||
|
HTM_TD_End ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
Ale_ShowAlert (Ale_ERROR,"Wrong exam.");
|
||||||
|
HTM_TD_End ();
|
||||||
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
HTM_TD_End ();
|
||||||
|
}
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** End table *****/
|
||||||
|
HTM_TABLE_End ();
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** End box *****/
|
||||||
|
Box_BoxEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*********** Compute score of each question and store in database ************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void TstPrn_ComputeScoresAndFixQuestionsOfPrint (struct TstPrn_Print *Print)
|
||||||
|
{
|
||||||
|
unsigned QstInd;
|
||||||
|
struct Qst_Question Question;
|
||||||
|
double BadScore;
|
||||||
|
double GoodScore;
|
||||||
|
|
||||||
|
/***** Initialize total score *****/
|
||||||
|
Print->Score = 0.0;
|
||||||
|
Print->NumQsts.NotBlank = 0;
|
||||||
|
|
||||||
|
/***** Compute and store scores of all questions *****/
|
||||||
|
for (QstInd = 0;
|
||||||
|
QstInd < Print->NumQsts.All;
|
||||||
|
QstInd++)
|
||||||
|
{
|
||||||
|
/* Make a copy of score retrieved from database before computing it */
|
||||||
|
BadScore = Print->PrintedQuestions[QstInd].Score;
|
||||||
|
|
||||||
|
/* Compute question score */
|
||||||
|
Qst_QstConstructor (&Question);
|
||||||
|
Question.QstCod = Print->PrintedQuestions[QstInd].QstCod;
|
||||||
|
Question.Answer.Type = Qst_DB_GetQstAnswerType (Question.QstCod);
|
||||||
|
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[QstInd],&Question);
|
||||||
|
Qst_QstDestructor (&Question);
|
||||||
|
|
||||||
|
/* Make a copy of just computed score */
|
||||||
|
GoodScore = Print->PrintedQuestions[QstInd].Score;
|
||||||
|
|
||||||
|
/* Store test question in database */
|
||||||
|
Tst_DB_FixOneQstOfPrint (Print,
|
||||||
|
QstInd); // 0, 1, 2, 3...
|
||||||
|
|
||||||
|
/* Accumulate total score */
|
||||||
|
Print->Score += Print->PrintedQuestions[QstInd].Score;
|
||||||
|
if (Print->PrintedQuestions[QstInd].StrAnswers[0]) // User's answer is not blank
|
||||||
|
Print->NumQsts.NotBlank++;
|
||||||
|
|
||||||
|
/* Update the number of hits and the score of this question in tests database */
|
||||||
|
Qst_DB_FixQstScore (Print->PrintedQuestions[QstInd].QstCod,
|
||||||
|
Print->PrintedQuestions[QstInd].StrAnswers[0] != '\0',
|
||||||
|
BadScore,GoodScore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -151,11 +151,14 @@ void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
|
||||||
unsigned Visibility);
|
unsigned Visibility);
|
||||||
void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print);
|
void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print);
|
||||||
|
|
||||||
void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print);
|
bool TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print);
|
||||||
void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod);
|
void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod);
|
||||||
void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
||||||
void TstPrn_RemoveCrsPrints (long CrsCod);
|
void TstPrn_RemoveCrsPrints (long CrsCod);
|
||||||
|
|
||||||
unsigned TstPrn_GetNumPrintsGeneratedByMe (void);
|
unsigned TstPrn_GetNumPrintsGeneratedByMe (void);
|
||||||
|
|
||||||
|
void TstPrn_PutLinkToFixTestsPrintsScores (void);
|
||||||
|
void TstPrn_FixTestsPrintsScores (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue