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 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},
|
||||
|
||||
[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},
|
||||
|
||||
// TabCty ******************************************************************
|
||||
|
@ -3739,6 +3741,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
|
|||
ActLstOneGam, // #1912
|
||||
ActEdiMch, // #1913
|
||||
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
|
||||
|
||||
#define Act_MAX_ACTION_COD 1914
|
||||
#define Act_MAX_ACTION_COD 1916
|
||||
|
||||
#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 ActSetUp (ActRenMaiFul + 39)
|
||||
#define ActReqRemOldCrs (ActRenMaiFul + 40)
|
||||
#define ActRemOldCrs (ActRenMaiFul + 41)
|
||||
#define ActFixMchSco (ActRenMaiFul + 40)
|
||||
#define ActFixTstSco (ActRenMaiFul + 41)
|
||||
#define ActReqRemOldCrs (ActRenMaiFul + 42)
|
||||
#define ActRemOldCrs (ActRenMaiFul + 43)
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************** 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.
|
||||
*/
|
||||
#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 JS_FILE "swad21.59.js"
|
||||
/*
|
||||
TODO: Rename CENTRE to CENTER in help wiki.
|
||||
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.1: Nov 24, 2021 Added some header files. (319422 lines)
|
||||
Version 21.62: Nov 24, 2021 Code refactoring in photos. (319415 lines)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "swad_course.h"
|
||||
#include "swad_database.h"
|
||||
#include "swad_match_print.h"
|
||||
#include "swad_menu.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -44,6 +45,8 @@ void Mtn_Maintenance (void)
|
|||
/***** Contextual menu *****/
|
||||
Mnu_ContextMenuBegin ();
|
||||
Mtn_PutLinkToSetUp (); // Set up
|
||||
// MchPrn_PutLinkToFixMatchesPrintsScores (); // Fix match prints scores
|
||||
// TstPrn_PutLinkToFixTestsPrintsScores (); // Fix test prints scores
|
||||
Crs_PutLinkToRemoveOldCrss (); // Remove old courses
|
||||
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,
|
||||
const struct Mch_Match *Match,
|
||||
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,
|
||||
const char *Anchor);
|
||||
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_ListOneOrMoreMatchesResult (struct Gam_Games *Games,
|
||||
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 ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match)
|
||||
void Mch_ListOneOrMoreMatchesAuthor (const struct Mch_Match *Match)
|
||||
{
|
||||
/***** Match author (teacher) *****/
|
||||
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 ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
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;
|
||||
char *Id;
|
||||
|
@ -718,7 +715,7 @@ static void Mch_GetAndWriteNamesOfGrpsAssociatedToMatch (const struct Mch_Match
|
|||
/******************* 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 ******/
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** 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 *****************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -98,6 +98,9 @@ void Mch_ListMatches (struct Gam_Games *Games,
|
|||
struct Gam_Game *Game,
|
||||
bool PutFormNewMatch);
|
||||
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);
|
||||
|
||||
|
@ -150,8 +153,6 @@ void Mch_StoreQuestionAnswer (const struct Mch_Match *Match,unsigned QstInd,
|
|||
|
||||
void Mch_GetMatchQuestionsFromDB (struct MchPrn_Print *Print);
|
||||
|
||||
void Mch_ComputeScore (struct MchPrn_Print *Print);
|
||||
|
||||
void Mch_DrawBarNumUsrs (unsigned NumRespondersAns,unsigned NumRespondersQst,bool Correct);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -297,6 +297,31 @@ unsigned Mch_DB_GetAvailableMatchesInGame (MYSQL_RES **mysql_res,long GamCod)
|
|||
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 *******************/
|
||||
/*****************************************************************************/
|
||||
|
@ -974,6 +999,34 @@ void Mch_DB_UpdateMatchPrint (const struct MchPrn_Print *Print)
|
|||
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 *************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -1018,6 +1071,23 @@ unsigned Mch_DB_GetMatchPrintData (MYSQL_RES **mysql_res,
|
|||
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 **************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -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_GetMatchesInGame (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);
|
||||
unsigned Mch_DB_GetNumMchsInGame (long GamCod);
|
||||
unsigned Mch_DB_GetNumUnfinishedMchsInGame (long GamCod);
|
||||
|
@ -110,10 +113,12 @@ unsigned Mch_DB_GetElapsedTimeInMatch (MYSQL_RES **mysql_res,long MchCod);
|
|||
//----------------------------- Match results ---------------------------------
|
||||
void Mch_DB_CreateMatchPrint (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);
|
||||
unsigned Mch_DB_GetMatchPrintData (MYSQL_RES **mysql_res,
|
||||
const struct MchPrn_Print *Print);
|
||||
unsigned Mch_DB_GetPrintsInMatch (MYSQL_RES **mysql_res,long MchCod);
|
||||
unsigned Mch_DB_GetNumUsrsWhoHavePlayedMch (long MchCod);
|
||||
unsigned Mch_DB_GetUsrsWhoHavePlayedMch (MYSQL_RES **mysql_res,long MchCod);
|
||||
unsigned Mch_DB_GetUsrsWhoHavePlayedGam (MYSQL_RES **mysql_res,long GamCod);
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <math.h> // For fabs
|
||||
|
||||
#include "swad_database.h"
|
||||
#include "swad_date.h"
|
||||
#include "swad_error.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_match.h"
|
||||
#include "swad_match_database.h"
|
||||
|
@ -42,8 +45,11 @@ extern struct Globals Gbl;
|
|||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void MchPrn_ComputeScore (struct MchPrn_Print *Print);
|
||||
static void MchPrn_UpdateMatchPrintInDB (const struct MchPrn_Print *Print);
|
||||
|
||||
static void MchPrn_ListPrintsToFix (long MchCod);
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************************** Reset match print ******************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -72,12 +78,41 @@ void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod)
|
|||
Print.MchCod = MchCod;
|
||||
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
Mch_GetMatchQuestionsFromDB (&Print);
|
||||
Mch_ComputeScore (&Print);
|
||||
MchPrn_ComputeScore (&Print);
|
||||
|
||||
/***** Update my match result in database *****/
|
||||
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 *************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -133,3 +168,232 @@ void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
|
|||
/***** Free structure that stores the query result *****/
|
||||
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_PutLinkToFixMatchesPrintsScores (void);
|
||||
void MchPrn_FixMatchesPrintsScores (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -913,7 +913,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
|
|||
TotalScore,
|
||||
TotalGrade);
|
||||
}
|
||||
else
|
||||
else // No results
|
||||
{
|
||||
/* Columns for dates and match */
|
||||
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
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* 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 ********************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
long Qst_DB_CreateQst (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_FixQstScore (long QstCod,bool AnswerIsNotBlank,
|
||||
double BadScore,double GoodScore);
|
||||
void Qst_DB_UpdateQstShuffle (long QstCod,bool Shuffle);
|
||||
//-----------------------------------------------------------------------------
|
||||
void Qst_DB_CreateIntAnswer (struct Qst_Question *Question);
|
||||
|
|
|
@ -276,7 +276,8 @@ void Tst_ReceiveTestDraft (void)
|
|||
else // Print not yet sent
|
||||
{
|
||||
/***** Get test print questions from database *****/
|
||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||
if (!TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||
Err_WrongExamExit ();
|
||||
|
||||
/***** Get answers from form to assess a test *****/
|
||||
TstPrn_GetAnswersFromForm (&Print);
|
||||
|
@ -332,7 +333,8 @@ void Tst_AssessTest (void)
|
|||
else // Print not yet sent
|
||||
{
|
||||
/***** Get test print questions from database *****/
|
||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||
if (!TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||
Err_WrongExamExit ();
|
||||
|
||||
/***** Get answers from form to assess a test *****/
|
||||
TstPrn_GetAnswersFromForm (&Print);
|
||||
|
|
|
@ -241,6 +241,54 @@ void Tst_DB_UpdatePrint (const struct TstPrn_Print *Print)
|
|||
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 ************/
|
||||
/*****************************************************************************/
|
||||
|
@ -351,6 +399,41 @@ void Tst_DB_StoreOneQstOfPrint (const struct TstPrn_Print *Print,unsigned QstInd
|
|||
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 ******************/
|
||||
/*****************************************************************************/
|
||||
|
@ -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)
|
||||
{
|
||||
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]
|
||||
" FROM (SELECT DISTINCT "
|
||||
"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)
|
||||
{
|
||||
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]
|
||||
"Score," // row[1]
|
||||
"Indexes," // row[2]
|
||||
|
|
|
@ -50,7 +50,11 @@ void Tst_DB_RemoveTstConfig (long CrsCod);
|
|||
//------------------------------- Test prints ---------------------------------
|
||||
long Tst_DB_CreatePrint (unsigned NumQsts);
|
||||
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_GetPrintDataByPrnCod (MYSQL_RES **mysql_res,long PrnCod);
|
||||
|
||||
|
@ -60,6 +64,7 @@ void Tst_DB_RemovePrintsMadeByInCrs (long CrsCod);
|
|||
|
||||
//-------------------------- Test print questions -----------------------------
|
||||
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_GetPrintQuestions (MYSQL_RES **mysql_res,long PrnCod);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#define _GNU_SOURCE // For asprintf
|
||||
#include <math.h> // For fabs
|
||||
#include <stdbool.h> // For boolean type
|
||||
#include <stddef.h> // For NULL
|
||||
#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_ComputeScoresAndFixQuestionsOfPrint (struct TstPrn_Print *Print);
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Reset test print ******************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -2174,7 +2177,8 @@ void TstPrn_ShowOnePrint (void)
|
|||
if (ICanView.Result) // I am allowed to view this test print result
|
||||
{
|
||||
/***** Get questions and user's answers of the test from database *****/
|
||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||
if (!TstPrn_GetPrintQuestionsFromDB (&Print))
|
||||
Err_WrongExamExit ();
|
||||
|
||||
/***** Begin box *****/
|
||||
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 ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||
bool TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
|
@ -2529,8 +2533,7 @@ void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
|||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
if (NumQsts != Print->NumQsts.All)
|
||||
Err_WrongExamExit ();
|
||||
return (NumQsts == Print->NumQsts.All);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -2608,3 +2611,226 @@ unsigned TstPrn_GetNumPrintsGeneratedByMe (void)
|
|||
|
||||
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);
|
||||
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_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
||||
void TstPrn_RemoveCrsPrints (long CrsCod);
|
||||
|
||||
unsigned TstPrn_GetNumPrintsGeneratedByMe (void);
|
||||
|
||||
void TstPrn_PutLinkToFixTestsPrintsScores (void);
|
||||
void TstPrn_FixTestsPrintsScores (void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue