mirror of
https://github.com/acanas/swad-core.git
synced 2024-06-13 04:04:35 +02:00
Version19.12
This commit is contained in:
parent
b7987d6356
commit
b4bc3aa6ef
|
@ -12878,4 +12878,19 @@ REPLACE gam_time (MchCod,QstInd,ElapsedTime) VALUES (61,1,ADDTIME(ElapsedTime,SE
|
||||||
|
|
||||||
INSERT INTO gam_time (MchCod,QstInd) VALUES (61,1,SEC_TO_TIME(1)) ON DUPLICATE KEY UPDATE ElapsedTime=ADDTIME(ElapsedTime,SEC_TO_TIME(1));
|
INSERT INTO gam_time (MchCod,QstInd) VALUES (61,1,SEC_TO_TIME(1)) ON DUPLICATE KEY UPDATE ElapsedTime=ADDTIME(ElapsedTime,SEC_TO_TIME(1));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------
|
||||||
|
|
||||||
|
SELECT gam_questions.QstCod,
|
||||||
|
gam_questions.QstInd,
|
||||||
|
mch_indexes.Indexes
|
||||||
|
FROM mch_matches,gam_questions,mch_indexes
|
||||||
|
WHERE mch_matches.MchCod=69
|
||||||
|
AND mch_matches.GamCod=gam_questions.GamCod
|
||||||
|
AND mch_matches.MchCod=mch_indexes.MchCod
|
||||||
|
AND gam_questions.QstInd=mch_indexes.QstInd
|
||||||
|
ORDER BY gam_questions.QstInd;
|
||||||
|
|
||||||
|
|
||||||
|
SELECT Correct FROM tst_answers WHERE QstCod=1787 ORDER BY AnsInd;
|
||||||
|
|
11
sql/swad.sql
11
sql/swad.sql
|
@ -613,11 +613,12 @@ CREATE TABLE IF NOT EXISTS gam_games (
|
||||||
--
|
--
|
||||||
-- Table mch_answers: stores the users' answers to the matches
|
-- Table mch_answers: stores the users' answers to the matches
|
||||||
--
|
--
|
||||||
CREATE TABLE IF NOT EXISTS mch_answers ("
|
CREATE TABLE IF NOT EXISTS mch_answers (
|
||||||
MchCod INT NOT NULL,"
|
MchCod INT NOT NULL,
|
||||||
UsrCod INT NOT NULL,"
|
UsrCod INT NOT NULL,
|
||||||
QstInd INT NOT NULL,"
|
QstInd INT NOT NULL,
|
||||||
AnsInd TINYINT NOT NULL,"
|
NumOpt TINYINT NOT NULL,
|
||||||
|
AnsInd TINYINT NOT NULL,
|
||||||
UNIQUE INDEX(MchCod,UsrCod,QstInd));
|
UNIQUE INDEX(MchCod,UsrCod,QstInd));
|
||||||
--
|
--
|
||||||
-- Table mch_groups: stores the groups associated to each match in a game
|
-- Table mch_groups: stores the groups associated to each match in a game
|
||||||
|
|
|
@ -470,10 +470,15 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
|
||||||
En OpenSWAD:
|
En OpenSWAD:
|
||||||
ps2pdf source.ps destination.pdf
|
ps2pdf source.ps destination.pdf
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 19.11 (2019-09-23)"
|
#define Log_PLATFORM_VERSION "SWAD 19.12 (2019-09-24)"
|
||||||
#define CSS_FILE "swad19.3.css"
|
#define CSS_FILE "swad19.3.css"
|
||||||
#define JS_FILE "swad18.130.2.js"
|
#define JS_FILE "swad18.130.2.js"
|
||||||
/*
|
/*
|
||||||
|
*
|
||||||
|
Version 19.12: Sep 24, 2019 View matches results. Not finished. (245973 lines)
|
||||||
|
1 change necessary in database:
|
||||||
|
ALTER TABLE mch_answers ADD COLUMN NumOpt TINYINT NOT NULL AFTER QstInd;
|
||||||
|
|
||||||
Version 19.11: Sep 23, 2019 Create indexes when a match is created. (245933 lines)
|
Version 19.11: Sep 23, 2019 Create indexes when a match is created. (245933 lines)
|
||||||
Version 19.10.3: Sep 23, 2019 View matches results. Not finished. (245815 lines)
|
Version 19.10.3: Sep 23, 2019 View matches results. Not finished. (245815 lines)
|
||||||
Version 19.10.2: Sep 23, 2019 View matches results. Not finished. (245812 lines)
|
Version 19.10.2: Sep 23, 2019 View matches results. Not finished. (245812 lines)
|
||||||
|
|
|
@ -1339,15 +1339,17 @@ mysql> DESCRIBE mch_answers;
|
||||||
| MchCod | int(11) | NO | PRI | NULL | |
|
| MchCod | int(11) | NO | PRI | NULL | |
|
||||||
| UsrCod | int(11) | NO | PRI | NULL | |
|
| UsrCod | int(11) | NO | PRI | NULL | |
|
||||||
| QstInd | int(11) | NO | PRI | NULL | |
|
| QstInd | int(11) | NO | PRI | NULL | |
|
||||||
| AnsInd | tinyint(4) | NO | PRI | NULL | |
|
| NumOpt | tinyint(4) | NO | | NULL | |
|
||||||
|
| AnsInd | tinyint(4) | NO | | NULL | |
|
||||||
+--------+------------+------+-----+---------+-------+
|
+--------+------------+------+-----+---------+-------+
|
||||||
4 rows in set (0.00 sec)
|
5 rows in set (0.00 sec)
|
||||||
*/
|
*/
|
||||||
DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_answers ("
|
DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_answers ("
|
||||||
"MchCod INT NOT NULL,"
|
"MchCod INT NOT NULL,"
|
||||||
"UsrCod INT NOT NULL,"
|
"UsrCod INT NOT NULL,"
|
||||||
"QstInd INT NOT NULL,"
|
"QstInd INT NOT NULL,"
|
||||||
"AnsInd TINYINT NOT NULL,"
|
"NumOpt TINYINT NOT NULL," // Number of button on screen (Always ordered: 0,1,2,3)
|
||||||
|
"AnsInd TINYINT NOT NULL," // Answer index (Can be shuffled: 0,3,1,2)
|
||||||
"UNIQUE INDEX(MchCod,UsrCod,QstInd))");
|
"UNIQUE INDEX(MchCod,UsrCod,QstInd))");
|
||||||
|
|
||||||
/***** Table mch_groups *****/
|
/***** Table mch_groups *****/
|
||||||
|
|
16
swad_game.c
16
swad_game.c
|
@ -1382,13 +1382,13 @@ void Gam_PutParamQstInd (unsigned QstInd)
|
||||||
|
|
||||||
unsigned Gam_GetParamQstInd (void)
|
unsigned Gam_GetParamQstInd (void)
|
||||||
{
|
{
|
||||||
long LongNum;
|
long QstInd;
|
||||||
|
|
||||||
LongNum = Par_GetParToLong ("QstInd");
|
QstInd = Par_GetParToLong ("QstInd");
|
||||||
if (LongNum < 0)
|
if (QstInd < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong question index.");
|
Lay_ShowErrorAndExit ("Wrong question index.");
|
||||||
|
|
||||||
return (unsigned) LongNum;
|
return (unsigned) QstInd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1397,11 +1397,11 @@ unsigned Gam_GetParamQstInd (void)
|
||||||
|
|
||||||
unsigned Gam_GetQstIndFromStr (const char *UnsignedStr)
|
unsigned Gam_GetQstIndFromStr (const char *UnsignedStr)
|
||||||
{
|
{
|
||||||
long LongNum;
|
long QstInd;
|
||||||
|
|
||||||
LongNum = Str_ConvertStrCodToLongCod (UnsignedStr);
|
QstInd = Str_ConvertStrCodToLongCod (UnsignedStr);
|
||||||
return (LongNum > 0) ? (unsigned) LongNum :
|
return (QstInd > 0) ? (unsigned) QstInd :
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
232
swad_match.c
232
swad_match.c
|
@ -99,6 +99,12 @@ struct Match
|
||||||
} Status;
|
} Status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Mch_UsrAnswer
|
||||||
|
{
|
||||||
|
int NumOpt; // < 0 ==> no answer selected
|
||||||
|
int AnsInd; // < 0 ==> no answer selected
|
||||||
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Private constants *****************************/
|
/***************************** Private constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -177,8 +183,8 @@ static void Mch_ShowMatchTitle (struct Match *Match);
|
||||||
static void Mch_ShowQuestionAndAnswersTch (struct Match *Match);
|
static void Mch_ShowQuestionAndAnswersTch (struct Match *Match);
|
||||||
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match);
|
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match);
|
||||||
|
|
||||||
static void Mch_PutParamAnswer (unsigned AnsInd);
|
static void Mch_PutParamNumOpt (unsigned NumOpt);
|
||||||
static unsigned Mch_GetParamAnswer (void);
|
static unsigned Mch_GetParamNumOpt (void);
|
||||||
|
|
||||||
static void Mch_PutBigButton (Act_Action_t NextAction,long MchCod,
|
static void Mch_PutBigButton (Act_Action_t NextAction,long MchCod,
|
||||||
const char *Icon,const char *Txt);
|
const char *Icon,const char *Txt);
|
||||||
|
@ -194,7 +200,8 @@ static bool Mch_GetIfMatchIsBeingPlayed (long MchCod);
|
||||||
static void Mch_RegisterMeAsPlayerInMatch (long MchCod);
|
static void Mch_RegisterMeAsPlayerInMatch (long MchCod);
|
||||||
static void Mch_GetNumPlayers (struct Match *Match);
|
static void Mch_GetNumPlayers (struct Match *Match);
|
||||||
|
|
||||||
static int Mch_GetQstAnsFromDB (long MchCod,long UsrCod,unsigned QstInd);
|
static void Mch_GetQstAnsFromDB (long MchCod,long UsrCod,unsigned QstInd,
|
||||||
|
struct Mch_UsrAnswer *UsrAnswer);
|
||||||
static void Mch_ComputeScore (struct Match *Match,unsigned NumQsts,long UsrCod,
|
static void Mch_ComputeScore (struct Match *Match,unsigned NumQsts,long UsrCod,
|
||||||
unsigned *NumQstsNotBlank,double *TotalScore);
|
unsigned *NumQstsNotBlank,double *TotalScore);
|
||||||
|
|
||||||
|
@ -1088,7 +1095,7 @@ static void Mch_CreateIndexes (long GamCod,long MchCod)
|
||||||
DB_QuerySELECT (&mysql_res,"can not get questions of a game",
|
DB_QuerySELECT (&mysql_res,"can not get questions of a game",
|
||||||
"SELECT gam_questions.QstCod," // row[0]
|
"SELECT gam_questions.QstCod," // row[0]
|
||||||
"gam_questions.QstInd," // row[1]
|
"gam_questions.QstInd," // row[1]
|
||||||
"tst_questions.AnsType" // row[2]
|
"tst_questions.AnsType," // row[2]
|
||||||
"tst_questions.Shuffle" // row[3]
|
"tst_questions.Shuffle" // row[3]
|
||||||
" FROM gam_questions,tst_questions"
|
" FROM gam_questions,tst_questions"
|
||||||
" WHERE gam_questions.GamCod=%ld"
|
" WHERE gam_questions.GamCod=%ld"
|
||||||
|
@ -1153,10 +1160,10 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
||||||
DB_QuerySELECT (&mysql_res,"can not get questions of a game",
|
DB_QuerySELECT (&mysql_res,"can not get questions of a game",
|
||||||
"SELECT AnsInd" // row[0]
|
"SELECT AnsInd" // row[0]
|
||||||
" FROM tst_answers"
|
" FROM tst_answers"
|
||||||
" WHERE GamCod=%ld"
|
" WHERE QstCod=%ld"
|
||||||
" ORDER BY %s",
|
" ORDER BY %s",
|
||||||
QstCod,
|
QstCod,
|
||||||
Shuffle ? "RAND(NOW())" :
|
Shuffle ? "RAND()" : // Use RAND() because is really random; RAND(NOW()) repeats order
|
||||||
"AnsInd");
|
"AnsInd");
|
||||||
|
|
||||||
/***** For each answer in question... *****/
|
/***** For each answer in question... *****/
|
||||||
|
@ -1170,10 +1177,10 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
||||||
if ((LongNum = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
if ((LongNum = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong answer index.");
|
Lay_ShowErrorAndExit ("Wrong answer index.");
|
||||||
AnsInd = (unsigned) LongNum;
|
AnsInd = (unsigned) LongNum;
|
||||||
|
snprintf (StrOneAnswer,sizeof (StrOneAnswer),
|
||||||
|
"%u",AnsInd);
|
||||||
|
|
||||||
/* Concatenate answer index to list of answers */
|
/* Concatenate answer index to list of answers */
|
||||||
snprintf (StrOneAnswer,10 + 1,
|
|
||||||
"%u",AnsInd);
|
|
||||||
if (NumAns)
|
if (NumAns)
|
||||||
Str_Concat (StrAnswersOneQst,",",
|
Str_Concat (StrAnswersOneQst,",",
|
||||||
Tst_MAX_BYTES_ANSWERS_ONE_QST);
|
Tst_MAX_BYTES_ANSWERS_ONE_QST);
|
||||||
|
@ -1193,6 +1200,38 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
||||||
MchCod,QstInd,StrAnswersOneQst);
|
MchCod,QstInd,StrAnswersOneQst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************** Get indexes for a question from database ******************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Mch_GetIndexes (long MchCod,unsigned QstInd,
|
||||||
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION])
|
||||||
|
{
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1];
|
||||||
|
|
||||||
|
/***** Get indexes for a question from database *****/
|
||||||
|
if (!DB_QuerySELECT (&mysql_res,"can not get data of a question",
|
||||||
|
"SELECT Indexes" // row[0]
|
||||||
|
" FROM mch_indexes"
|
||||||
|
" WHERE MchCod=%ld AND QstInd=%u",
|
||||||
|
MchCod,QstInd))
|
||||||
|
Lay_ShowErrorAndExit ("No indexes found for a question.");
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
|
/* Get indexes (row[0]) */
|
||||||
|
Str_Copy (StrIndexesOneQst,row[0],
|
||||||
|
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Get indexes from string *****/
|
||||||
|
Par_ReplaceCommaBySeparatorMultiple (StrIndexesOneQst);
|
||||||
|
Tst_GetIndexesFromStr (StrIndexesOneQst,Indexes);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************* Create groups associated to a match *********************/
|
/******************* Create groups associated to a match *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1976,7 +2015,10 @@ static void Mch_ShowQuestionAndAnswersTch (struct Match *Match)
|
||||||
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
|
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
|
||||||
"TEST_MED_EDIT_LIST_STEM");
|
"TEST_MED_EDIT_LIST_STEM");
|
||||||
|
|
||||||
/* Write answers? */
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Write answers? *****/
|
||||||
switch (Match->Status.Showing)
|
switch (Match->Status.Showing)
|
||||||
{
|
{
|
||||||
case Mch_NOTHING:
|
case Mch_NOTHING:
|
||||||
|
@ -2013,14 +2055,9 @@ static void Mch_ShowQuestionAndAnswersTch (struct Match *Match)
|
||||||
|
|
||||||
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
{
|
{
|
||||||
bool Shuffle = false; // TODO: Read shuffle from question
|
struct Mch_UsrAnswer UsrAnswer;
|
||||||
MYSQL_RES *mysql_res;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int StdAnsInd;
|
|
||||||
unsigned NumOptions;
|
unsigned NumOptions;
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
unsigned Index;
|
|
||||||
bool ErrorInIndex = false;
|
|
||||||
|
|
||||||
/***** Show question *****/
|
/***** Show question *****/
|
||||||
/* Write buttons for answers? */
|
/* Write buttons for answers? */
|
||||||
|
@ -2030,24 +2067,14 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
{
|
{
|
||||||
/***** Get student's answer to this question
|
/***** Get student's answer to this question
|
||||||
(<0 ==> no answer) *****/
|
(<0 ==> no answer) *****/
|
||||||
StdAnsInd = Mch_GetQstAnsFromDB (Match->MchCod,
|
Mch_GetQstAnsFromDB (Match->MchCod,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
Match->Status.QstInd);
|
Match->Status.QstInd,
|
||||||
|
&UsrAnswer);
|
||||||
|
|
||||||
/***** Get number of options in this question *****/
|
/***** Get number of options in this question *****/
|
||||||
NumOptions = Tst_GetNumAnswersQst (Match->Status.QstCod);
|
NumOptions = Tst_GetNumAnswersQst (Match->Status.QstCod);
|
||||||
|
|
||||||
/***** Get answers of question from database *****/
|
|
||||||
Shuffle = false;
|
|
||||||
NumOptions = Tst_GetAnswersQst (Match->Status.QstCod,&mysql_res,Shuffle);
|
|
||||||
/*
|
|
||||||
row[0] AnsInd
|
|
||||||
row[1] Answer
|
|
||||||
row[2] Feedback
|
|
||||||
row[3] MedCod
|
|
||||||
row[4] Correct
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***** Start table *****/
|
/***** Start table *****/
|
||||||
Tbl_StartTableWide (8);
|
Tbl_StartTableWide (8);
|
||||||
|
|
||||||
|
@ -2055,24 +2082,7 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
NumOpt < NumOptions;
|
NumOpt < NumOptions;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
{
|
{
|
||||||
/***** Get next answer *****/
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
|
||||||
|
|
||||||
/***** Assign index (row[0]).
|
|
||||||
Index is 0,1,2,3... if no shuffle
|
|
||||||
or 1,3,0,2... (example) if shuffle *****/
|
|
||||||
if (sscanf (row[0],"%u",&Index) == 1)
|
|
||||||
{
|
|
||||||
if (Index >= Tst_MAX_OPTIONS_PER_QUESTION)
|
|
||||||
ErrorInIndex = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ErrorInIndex = true;
|
|
||||||
if (ErrorInIndex)
|
|
||||||
Lay_ShowErrorAndExit ("Wrong index of answer when showing a test.");
|
|
||||||
|
|
||||||
/***** Start row *****/
|
/***** Start row *****/
|
||||||
// if (NumOpt % 2 == 0)
|
|
||||||
fprintf (Gbl.F.Out,"<tr>");
|
fprintf (Gbl.F.Out,"<tr>");
|
||||||
|
|
||||||
/***** Write letter for this option *****/
|
/***** Write letter for this option *****/
|
||||||
|
@ -2086,12 +2096,12 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
Frm_StartForm (ActAnsMchQstStd);
|
Frm_StartForm (ActAnsMchQstStd);
|
||||||
Mch_PutParamMchCod (Match->MchCod); // Current match being played
|
Mch_PutParamMchCod (Match->MchCod); // Current match being played
|
||||||
Gam_PutParamQstInd (Match->Status.QstInd); // Current question index shown
|
Gam_PutParamQstInd (Match->Status.QstInd); // Current question index shown
|
||||||
Mch_PutParamAnswer (Index); // Index for this option
|
Mch_PutParamNumOpt (NumOpt); // Number of button
|
||||||
fprintf (Gbl.F.Out,"<button type=\"submit\""
|
fprintf (Gbl.F.Out,"<button type=\"submit\""
|
||||||
" onmousedown=\"document.getElementById('%s').submit();"
|
" onmousedown=\"document.getElementById('%s').submit();"
|
||||||
"return false;\" class=\"",
|
"return false;\" class=\"",
|
||||||
Gbl.Form.Id);
|
Gbl.Form.Id);
|
||||||
if (StdAnsInd == (int) NumOpt) // Student's answer
|
if (UsrAnswer.NumOpt == (int) NumOpt) // Student's answer
|
||||||
fprintf (Gbl.F.Out,"MATCH_STD_ANSWER_SELECTED ");
|
fprintf (Gbl.F.Out,"MATCH_STD_ANSWER_SELECTED ");
|
||||||
fprintf (Gbl.F.Out,"MATCH_STD_BUTTON BT_%c\">"
|
fprintf (Gbl.F.Out,"MATCH_STD_BUTTON BT_%c\">"
|
||||||
"%c"
|
"%c"
|
||||||
|
@ -2104,7 +2114,6 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
fprintf (Gbl.F.Out,"</td>");
|
fprintf (Gbl.F.Out,"</td>");
|
||||||
|
|
||||||
/***** End row *****/
|
/***** End row *****/
|
||||||
// if (NumOpt % 2 == 1)
|
|
||||||
fprintf (Gbl.F.Out,"</tr>");
|
fprintf (Gbl.F.Out,"</tr>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2116,29 +2125,28 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************* Write parameter with student's answer *******************/
|
/****** Write parameter with number of option (button) pressed by user *******/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mch_PutParamAnswer (unsigned AnsInd)
|
static void Mch_PutParamNumOpt (unsigned NumOpt)
|
||||||
{
|
{
|
||||||
Par_PutHiddenParamUnsigned ("Ans",AnsInd);
|
Par_PutHiddenParamUnsigned ("NumOpt",NumOpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************* Get parameter with student's answer *********************/
|
/******* Get parameter with number of option (button) pressed by user ********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static unsigned Mch_GetParamAnswer (void)
|
static unsigned Mch_GetParamNumOpt (void)
|
||||||
{
|
{
|
||||||
long LongNum;
|
long NumOpt;
|
||||||
|
|
||||||
LongNum = Par_GetParToLong ("Ans");
|
NumOpt = Par_GetParToLong ("NumOpt");
|
||||||
if (LongNum < 0)
|
if (NumOpt < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong answer index.");
|
Lay_ShowErrorAndExit ("Wrong number of option.");
|
||||||
|
|
||||||
return (unsigned) LongNum;
|
return (unsigned) NumOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2384,32 +2392,41 @@ void Mch_RefreshMatchStd (void)
|
||||||
/**** Receive previous question answer in a match question from database *****/
|
/**** Receive previous question answer in a match question from database *****/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static int Mch_GetQstAnsFromDB (long MchCod,long UsrCod,unsigned QstInd)
|
static void Mch_GetQstAnsFromDB (long MchCod,long UsrCod,unsigned QstInd,
|
||||||
|
struct Mch_UsrAnswer *UsrAnswer)
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
unsigned NumRows;
|
unsigned NumRows;
|
||||||
int AnsInd = -1; // <0 ==> no answer selected
|
|
||||||
|
/***** Set default values for number of option and answer index *****/
|
||||||
|
UsrAnswer->NumOpt = -1; // < 0 ==> no answer selected
|
||||||
|
UsrAnswer->AnsInd = -1; // < 0 ==> no answer selected
|
||||||
|
|
||||||
/***** Get student's answer *****/
|
/***** Get student's answer *****/
|
||||||
NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get student's answer to a match question",
|
NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get user's answer to a match question",
|
||||||
"SELECT AnsInd FROM mch_answers"
|
"SELECT NumOpt," // row[0]
|
||||||
|
"AnsInd" // row[1]
|
||||||
|
" FROM mch_answers"
|
||||||
" WHERE MchCod=%ld"
|
" WHERE MchCod=%ld"
|
||||||
" AND UsrCod=%ld"
|
" AND UsrCod=%ld"
|
||||||
" AND QstInd=%u",
|
" AND QstInd=%u",
|
||||||
MchCod,UsrCod,QstInd);
|
MchCod,UsrCod,QstInd);
|
||||||
if (NumRows) // Answer found...
|
if (NumRows) // Answer found...
|
||||||
{
|
{
|
||||||
/***** Get answer index *****/
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
if (sscanf (row[0],"%d",&AnsInd) != 1)
|
|
||||||
|
/***** Get number of option index (row[0]) *****/
|
||||||
|
if (sscanf (row[0],"%d",&(UsrAnswer->NumOpt)) != 1)
|
||||||
|
Lay_ShowErrorAndExit ("Error when getting student's answer to a match question.");
|
||||||
|
|
||||||
|
/***** Get answer index (row[1]) *****/
|
||||||
|
if (sscanf (row[1],"%d",&(UsrAnswer->AnsInd)) != 1)
|
||||||
Lay_ShowErrorAndExit ("Error when getting student's answer to a match question.");
|
Lay_ShowErrorAndExit ("Error when getting student's answer to a match question.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
return AnsInd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2420,8 +2437,9 @@ void Mch_ReceiveQstAnsFromStd (void)
|
||||||
{
|
{
|
||||||
struct Match Match;
|
struct Match Match;
|
||||||
unsigned QstInd;
|
unsigned QstInd;
|
||||||
unsigned StdAnsInd;
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION];
|
||||||
int PreviousStdAnsInd;
|
struct Mch_UsrAnswer PreviousUsrAnswer;
|
||||||
|
struct Mch_UsrAnswer UsrAnswer;
|
||||||
unsigned NumQsts;
|
unsigned NumQsts;
|
||||||
unsigned NumQstsNotBlank;
|
unsigned NumQstsNotBlank;
|
||||||
double TotalScore;
|
double TotalScore;
|
||||||
|
@ -2437,39 +2455,53 @@ void Mch_ReceiveQstAnsFromStd (void)
|
||||||
/***** Get question index from form *****/
|
/***** Get question index from form *****/
|
||||||
QstInd = Gam_GetParamQstInd ();
|
QstInd = Gam_GetParamQstInd ();
|
||||||
|
|
||||||
|
/***** Get indexes for this question from database *****/
|
||||||
|
Mch_GetIndexes (Match.MchCod,QstInd,Indexes);
|
||||||
|
|
||||||
/***** Check that question index is the current one being played *****/
|
/***** Check that question index is the current one being played *****/
|
||||||
if (QstInd == Match.Status.QstInd) // Receiving an answer
|
if (QstInd == Match.Status.QstInd) // Receiving an answer
|
||||||
// to the current question being played
|
// to the current question being played
|
||||||
{
|
{
|
||||||
/***** Get answer index *****/
|
/***** Get answer index *****/
|
||||||
/*-------+--------------+
|
/*
|
||||||
| Button | Answer index |
|
Indexes[4] = {0,3,1,2}
|
||||||
+--------+--------------+
|
+-------+--------+----------+---------+
|
||||||
| a | 0 |
|
| Button | Option | Answer | Correct |
|
||||||
| b | 1 |
|
| letter | number | index | |
|
||||||
| c | 2 |
|
| screen | screen | database | |
|
||||||
| d | 3 |
|
+--------+--------+----------+---------+
|
||||||
| ... | ... |
|
| a | 0 | 0 | |
|
||||||
+--------+-------------*/
|
| b | 1 | 3 | |
|
||||||
StdAnsInd = Mch_GetParamAnswer ();
|
| c | 2 | 1 | Y | <---- User press button #2 (index = 1, correct)
|
||||||
|
| d | 3 | 2 | |
|
||||||
|
+--------+--------+----------+---------+
|
||||||
|
UsrAnswer.NumOpt = 2
|
||||||
|
UsrAnswer.AnsInd = 1
|
||||||
|
*/
|
||||||
|
UsrAnswer.NumOpt = Mch_GetParamNumOpt ();
|
||||||
|
UsrAnswer.AnsInd = Indexes[UsrAnswer.NumOpt];
|
||||||
|
|
||||||
/***** Get previous student's answer to this question
|
/***** Get previous student's answer to this question
|
||||||
(<0 ==> no answer) *****/
|
(<0 ==> no answer) *****/
|
||||||
PreviousStdAnsInd = Mch_GetQstAnsFromDB (Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd);
|
Mch_GetQstAnsFromDB (Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd,
|
||||||
|
&PreviousUsrAnswer);
|
||||||
|
|
||||||
/***** Store student's answer *****/
|
/***** Store student's answer *****/
|
||||||
if (PreviousStdAnsInd == (int) StdAnsInd)
|
if (PreviousUsrAnswer.AnsInd == UsrAnswer.AnsInd)
|
||||||
DB_QueryDELETE ("can not register your answer to the match question",
|
DB_QueryDELETE ("can not remove your answer to the match question",
|
||||||
"DELETE FROM mch_answers"
|
"DELETE FROM mch_answers"
|
||||||
" WHERE MchCod=%ld AND UsrCod=%ld AND QstInd=%u",
|
" WHERE MchCod=%ld AND UsrCod=%ld AND QstInd=%u",
|
||||||
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd);
|
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd);
|
||||||
else
|
else if (UsrAnswer.NumOpt >= 0 &&
|
||||||
|
UsrAnswer.AnsInd >= 0)
|
||||||
DB_QueryREPLACE ("can not register your answer to the match question",
|
DB_QueryREPLACE ("can not register your answer to the match question",
|
||||||
"REPLACE mch_answers"
|
"REPLACE mch_answers"
|
||||||
" (MchCod,UsrCod,QstInd,AnsInd)"
|
" (MchCod,UsrCod,QstInd,NumOpt,AnsInd)"
|
||||||
" VALUES"
|
" VALUES"
|
||||||
" (%ld,%ld,%u,%u)",
|
" (%ld,%ld,%u,%d,%d)",
|
||||||
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd,StdAnsInd);
|
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd,
|
||||||
|
UsrAnswer.NumOpt,
|
||||||
|
UsrAnswer.AnsInd);
|
||||||
|
|
||||||
/***** Update student's match result *****/
|
/***** Update student's match result *****/
|
||||||
NumQsts = Gam_GetNumQstsGame (Match.GamCod);
|
NumQsts = Gam_GetNumQstsGame (Match.GamCod);
|
||||||
|
@ -2488,7 +2520,7 @@ void Mch_ReceiveQstAnsFromStd (void)
|
||||||
"NumQsts=%u,"
|
"NumQsts=%u,"
|
||||||
"NumQstsNotBlank=%u,"
|
"NumQstsNotBlank=%u,"
|
||||||
"Score='%lf'"
|
"Score='%lf'"
|
||||||
" WHERE MchCod=%ld AND UsrCod=%ld",
|
" WHERE MchCod=%ld AND UsrCod=%ld",
|
||||||
NumQsts,NumQstsNotBlank,TotalScore,
|
NumQsts,NumQstsNotBlank,TotalScore,
|
||||||
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod);
|
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||||
else // Result doesn't exist
|
else // Result doesn't exist
|
||||||
|
@ -2529,7 +2561,7 @@ static void Mch_ComputeScore (struct Match *Match,unsigned NumQsts,long UsrCod,
|
||||||
double ScoreThisQst;
|
double ScoreThisQst;
|
||||||
bool AnswerIsNotBlank;
|
bool AnswerIsNotBlank;
|
||||||
long LongNum;
|
long LongNum;
|
||||||
int AnsInd;
|
struct Mch_UsrAnswer UsrAnswer;
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION];
|
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION];
|
||||||
|
|
||||||
|
@ -2540,11 +2572,11 @@ static void Mch_ComputeScore (struct Match *Match,unsigned NumQsts,long UsrCod,
|
||||||
"SELECT gam_questions.QstCod," // row[0]
|
"SELECT gam_questions.QstCod," // row[0]
|
||||||
"gam_questions.QstInd," // row[1]
|
"gam_questions.QstInd," // row[1]
|
||||||
"mch_indexes.Indexes" // row[2]
|
"mch_indexes.Indexes" // row[2]
|
||||||
" FROM mch_matches,gam_questions,mch_questions"
|
" FROM mch_matches,gam_questions,mch_indexes"
|
||||||
" WHERE mch_matches.MchCod=%ld"
|
" WHERE mch_matches.MchCod=%ld"
|
||||||
" AND mch_matches.GamCod=gam_questions.GamCod"
|
" AND mch_matches.GamCod=gam_questions.GamCod"
|
||||||
" AND mch_matches.MchCod=mch_indexes.MchCod"
|
" AND mch_matches.MchCod=mch_indexes.MchCod"
|
||||||
" AND mch_matches.QstInd=mch_indexes.QstInd"
|
" AND gam_questions.QstInd=mch_indexes.QstInd"
|
||||||
" ORDER BY gam_questions.QstInd");
|
" ORDER BY gam_questions.QstInd");
|
||||||
|
|
||||||
/***** For each question in match... *****/
|
/***** For each question in match... *****/
|
||||||
|
@ -2568,20 +2600,22 @@ static void Mch_ComputeScore (struct Match *Match,unsigned NumQsts,long UsrCod,
|
||||||
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
||||||
|
|
||||||
/***** Get answers selected by user for this question *****/
|
/***** Get answers selected by user for this question *****/
|
||||||
AnsInd = Mch_GetQstAnsFromDB (Match->MchCod,UsrCod,QstInd);
|
Mch_GetQstAnsFromDB (Match->MchCod,UsrCod,QstInd,&UsrAnswer);
|
||||||
if (AnsInd >= 0) // AnsInd >= 0 ==> answer selected
|
if (UsrAnswer.AnsInd >= 0) // AnsInd >= 0 ==> answer selected
|
||||||
{
|
{
|
||||||
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
||||||
"%d",AnsInd);
|
"%d",UsrAnswer.AnsInd);
|
||||||
(*NumQstsNotBlank)++;
|
(*NumQstsNotBlank)++;
|
||||||
}
|
}
|
||||||
else // AnsInd < 0 ==> no answer selected
|
else // AnsInd < 0 ==> no answer selected
|
||||||
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
|
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
|
||||||
|
|
||||||
/***** Get indexes for this question from string *****/
|
/***** Get indexes for this question from string *****/
|
||||||
|
Par_ReplaceCommaBySeparatorMultiple (Gbl.Test.StrIndexesOneQst[NumQst]);
|
||||||
Tst_GetIndexesFromStr (Gbl.Test.StrIndexesOneQst[NumQst],Indexes);
|
Tst_GetIndexesFromStr (Gbl.Test.StrIndexesOneQst[NumQst],Indexes);
|
||||||
|
|
||||||
/***** Get the user's answers for this question from string *****/
|
/***** Get the user's answers for this question from string *****/
|
||||||
|
Par_ReplaceCommaBySeparatorMultiple (Gbl.Test.StrAnswersOneQst[NumQst]);
|
||||||
Tst_GetAnswersFromStr (Gbl.Test.StrAnswersOneQst[NumQst],AnswersUsr);
|
Tst_GetAnswersFromStr (Gbl.Test.StrAnswersOneQst[NumQst],AnswersUsr);
|
||||||
|
|
||||||
/***** Get correct answers of test question from database *****/
|
/***** Get correct answers of test question from database *****/
|
||||||
|
@ -3486,7 +3520,7 @@ static void Mch_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod)
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
long LongNum;
|
long LongNum;
|
||||||
unsigned QstInd;
|
unsigned QstInd;
|
||||||
int AnsInd;
|
struct Mch_UsrAnswer UsrAnswer;
|
||||||
|
|
||||||
/***** Get questions and answers of a match result *****/
|
/***** Get questions and answers of a match result *****/
|
||||||
NumQsts = (unsigned)
|
NumQsts = (unsigned)
|
||||||
|
@ -3521,11 +3555,11 @@ static void Mch_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod)
|
||||||
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
||||||
|
|
||||||
/* Get answers selected by user for this question */
|
/* Get answers selected by user for this question */
|
||||||
AnsInd = Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd);
|
Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer);
|
||||||
if (AnsInd >= 0) // AnsInd >= 0 ==> answer selected
|
if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
|
||||||
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
||||||
"%d",AnsInd);
|
"%d",UsrAnswer.AnsInd);
|
||||||
else // AnsInd < 0 ==> no answer selected
|
else // UsrAnswer.AnsInd < 0 ==> no answer selected
|
||||||
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
|
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
|
||||||
|
|
||||||
/* Replace each comma by a separator of multiple parameters */
|
/* Replace each comma by a separator of multiple parameters */
|
||||||
|
|
|
@ -48,6 +48,8 @@ void Mch_RemoveMatchTch (void);
|
||||||
|
|
||||||
void Mch_CreateNewMatchTch (void);
|
void Mch_CreateNewMatchTch (void);
|
||||||
void Mch_RequestStartResumeMatchTch (void);
|
void Mch_RequestStartResumeMatchTch (void);
|
||||||
|
void Mch_GetIndexes (long MchCod,unsigned QstInd,
|
||||||
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
||||||
void Mch_PauseMatchTch (void);
|
void Mch_PauseMatchTch (void);
|
||||||
void Mch_ResumeMatchTch (void);
|
void Mch_ResumeMatchTch (void);
|
||||||
void Mch_ToggleDisplayResultsMatchTch (void);
|
void Mch_ToggleDisplayResultsMatchTch (void);
|
||||||
|
|
|
@ -981,9 +981,11 @@ bool Par_GetNextStrUntilSeparParamMult (const char **StrSrc,char *StrDst,size_t
|
||||||
do
|
do
|
||||||
if ((Ch = (unsigned char) **StrSrc))
|
if ((Ch = (unsigned char) **StrSrc))
|
||||||
(*StrSrc)++;
|
(*StrSrc)++;
|
||||||
while (Ch && Ch < 32); // Skip special characters (the separator will be a special character less than 32)
|
while (Ch && Ch < 32); // Skip special characters
|
||||||
|
// (the separator will be a special character
|
||||||
|
// less than 32)
|
||||||
|
|
||||||
while (Ch >= 32)
|
while (Ch >= 32) // Until special character or end
|
||||||
{
|
{
|
||||||
CharsFound = true;
|
CharsFound = true;
|
||||||
if (i < LongMax)
|
if (i < LongMax)
|
||||||
|
|
|
@ -85,6 +85,7 @@ unsigned Par_GetParAndChangeFormat (const char *ParamName,char *ParamValue,size_
|
||||||
Str_ChangeTo_t ChangeTo,bool RemoveLeadingAndTrailingSpaces);
|
Str_ChangeTo_t ChangeTo,bool RemoveLeadingAndTrailingSpaces);
|
||||||
|
|
||||||
bool Par_GetNextStrUntilSeparParamMult (const char **StrSrc,char *StrDst,size_t LongMax);
|
bool Par_GetNextStrUntilSeparParamMult (const char **StrSrc,char *StrDst,size_t LongMax);
|
||||||
|
bool Par_GetNextStrUntilComma (const char **StrSrc,char *StrDst,size_t LongMax);
|
||||||
void Par_ReplaceSeparatorMultipleByComma (const char *StrSrc,char *StrDst);
|
void Par_ReplaceSeparatorMultipleByComma (const char *StrSrc,char *StrDst);
|
||||||
void Par_ReplaceCommaBySeparatorMultiple (char *Str);
|
void Par_ReplaceCommaBySeparatorMultiple (char *Str);
|
||||||
|
|
||||||
|
|
78
swad_test.c
78
swad_test.c
|
@ -4017,13 +4017,22 @@ void Tst_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ON
|
||||||
const char *Ptr;
|
const char *Ptr;
|
||||||
char StrOneIndex[10 + 1];
|
char StrOneIndex[10 + 1];
|
||||||
|
|
||||||
|
/***** Initialize to 0 *****/
|
||||||
for (NumOpt = 0, Ptr = StrIndexesOneQst;
|
for (NumOpt = 0, Ptr = StrIndexesOneQst;
|
||||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION && *Ptr;
|
||||||
|
NumOpt++)
|
||||||
|
Indexes[NumOpt] = 0;
|
||||||
|
|
||||||
|
/***** Get indexes from string *****/
|
||||||
|
for (NumOpt = 0, Ptr = StrIndexesOneQst;
|
||||||
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION && *Ptr;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
{
|
{
|
||||||
Par_GetNextStrUntilSeparParamMult (&Ptr,StrOneIndex,10);
|
Par_GetNextStrUntilSeparParamMult (&Ptr,StrOneIndex,10);
|
||||||
if (sscanf (StrOneIndex,"%u",&(Indexes[NumOpt])) != 1)
|
if (sscanf (StrOneIndex,"%u",&(Indexes[NumOpt])) != 1)
|
||||||
Lay_ShowErrorAndExit ("Wrong index of answer when assessing a test.");
|
Lay_ShowErrorAndExit ("Wrong index of answer.");
|
||||||
|
if (Indexes[NumOpt] >= Tst_MAX_OPTIONS_PER_QUESTION)
|
||||||
|
Lay_ShowErrorAndExit ("Wrong index of answer.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4136,12 +4145,10 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
unsigned AnsInd;
|
|
||||||
unsigned NumAnswerersQst;
|
unsigned NumAnswerersQst;
|
||||||
bool Correct;
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||||
bool ErrorInIndex = false;
|
|
||||||
|
|
||||||
/***** Get number of users who hasve answered this question from database *****/
|
/***** Get number of users who have answered this question from database *****/
|
||||||
NumAnswerersQst = Mch_GetNumUsrsWhoHaveAnswerQst (MchCod,QstInd);
|
NumAnswerersQst = Mch_GetNumUsrsWhoHaveAnswerQst (MchCod,QstInd);
|
||||||
|
|
||||||
/***** Get answers of a question from database *****/
|
/***** Get answers of a question from database *****/
|
||||||
|
@ -4154,45 +4161,47 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
|
||||||
row[4] Correct
|
row[4] Correct
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Start table *****/
|
|
||||||
Tbl_StartTableWide (2);
|
|
||||||
|
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
{
|
{
|
||||||
/***** Get next answer *****/
|
/* Get next answer */
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/***** Allocate memory for text in this choice answer *****/
|
/* Allocate memory for text in this choice answer */
|
||||||
if (!Tst_AllocateTextChoiceAnswer (NumOpt))
|
if (!Tst_AllocateTextChoiceAnswer (NumOpt))
|
||||||
/* Abort on error */
|
/* Abort on error */
|
||||||
Ale_ShowAlertsAndExit ();
|
Ale_ShowAlertsAndExit ();
|
||||||
|
|
||||||
/***** Assign index (row[0]).
|
/* Copy text (row[1]) and convert it, that is in HTML, to rigorous HTML */
|
||||||
Index is 0,1,2,3... if no shuffle
|
|
||||||
or 1,3,0,2... (example) if shuffle *****/
|
|
||||||
if (sscanf (row[0],"%u",&AnsInd) == 1)
|
|
||||||
{
|
|
||||||
if (AnsInd >= Tst_MAX_OPTIONS_PER_QUESTION)
|
|
||||||
ErrorInIndex = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ErrorInIndex = true;
|
|
||||||
if (ErrorInIndex)
|
|
||||||
Lay_ShowErrorAndExit ("Wrong index of answer when showing a test.");
|
|
||||||
|
|
||||||
/***** Copy text (row[1]) and convert it, that is in HTML, to rigorous HTML ******/
|
|
||||||
Str_Copy (Gbl.Test.Answer.Options[NumOpt].Text,row[1],
|
Str_Copy (Gbl.Test.Answer.Options[NumOpt].Text,row[1],
|
||||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||||
Gbl.Test.Answer.Options[NumOpt].Text,
|
Gbl.Test.Answer.Options[NumOpt].Text,
|
||||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||||
|
|
||||||
/***** Get media (row[3]) *****/
|
/* Get media (row[3]) */
|
||||||
Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
|
Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media);
|
Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media);
|
||||||
|
|
||||||
|
/* Get if correct (row[4]) */
|
||||||
|
Gbl.Test.Answer.Options[NumOpt].Correct = (row[4][0] == 'Y');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free structure that stores the query result */
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Get indexes for this question in match *****/
|
||||||
|
Mch_GetIndexes (MchCod,QstInd,Indexes);
|
||||||
|
|
||||||
|
/***** Start table *****/
|
||||||
|
Tbl_StartTableWide (2);
|
||||||
|
|
||||||
|
/***** Show one row for each option *****/
|
||||||
|
for (NumOpt = 0;
|
||||||
|
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||||
|
NumOpt++)
|
||||||
|
{
|
||||||
/***** Start row for this option *****/
|
/***** Start row for this option *****/
|
||||||
fprintf (Gbl.F.Out,"<tr>");
|
fprintf (Gbl.F.Out,"<tr>");
|
||||||
|
|
||||||
|
@ -4212,22 +4221,18 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
|
||||||
"</label>",
|
"</label>",
|
||||||
QstInd,NumOpt,
|
QstInd,NumOpt,
|
||||||
Class,
|
Class,
|
||||||
Gbl.Test.Answer.Options[NumOpt].Text);
|
Gbl.Test.Answer.Options[Indexes[NumOpt]].Text);
|
||||||
Med_ShowMedia (&Gbl.Test.Answer.Options[NumOpt].Media,
|
Med_ShowMedia (&Gbl.Test.Answer.Options[Indexes[NumOpt]].Media,
|
||||||
"TEST_MED_SHOW_CONTAINER",
|
"TEST_MED_SHOW_CONTAINER",
|
||||||
"TEST_MED_SHOW");
|
"TEST_MED_SHOW");
|
||||||
|
|
||||||
/* Show result (number of users who answered? */
|
/* Show result (number of users who answered? */
|
||||||
if (ShowResult)
|
if (ShowResult)
|
||||||
{
|
|
||||||
/* Get if correct (row[4]) */
|
|
||||||
Correct = (row[4][0] == 'Y');
|
|
||||||
|
|
||||||
/* Get number of users who selected this answer
|
/* Get number of users who selected this answer
|
||||||
and draw proportional bar */
|
and draw proportional bar */
|
||||||
Mch_GetAndDrawBarNumUsrsWhoHaveChosenAns (MchCod,QstInd,AnsInd,
|
Mch_GetAndDrawBarNumUsrsWhoHaveChosenAns (MchCod,QstInd,Indexes[NumOpt],
|
||||||
NumAnswerersQst,Correct);
|
NumAnswerersQst,
|
||||||
}
|
Gbl.Test.Answer.Options[Indexes[NumOpt]].Correct);
|
||||||
|
|
||||||
fprintf (Gbl.F.Out,"</td>");
|
fprintf (Gbl.F.Out,"</td>");
|
||||||
|
|
||||||
|
@ -4237,9 +4242,6 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
|
||||||
|
|
||||||
/***** End table *****/
|
/***** End table *****/
|
||||||
Tbl_EndTable ();
|
Tbl_EndTable ();
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user