diff --git a/sql/cambios.sql b/sql/cambios.sql
index e5f1fb4a..1ca83a61 100644
--- a/sql/cambios.sql
+++ b/sql/cambios.sql
@@ -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));
-
+
+
+----------------
+
+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;
diff --git a/sql/swad.sql b/sql/swad.sql
index 32b65e08..0828ef14 100644
--- a/sql/swad.sql
+++ b/sql/swad.sql
@@ -613,11 +613,12 @@ CREATE TABLE IF NOT EXISTS gam_games (
--
-- Table mch_answers: stores the users' answers to the matches
--
-CREATE TABLE IF NOT EXISTS mch_answers ("
- MchCod INT NOT NULL,"
- UsrCod INT NOT NULL,"
- QstInd INT NOT NULL,"
- AnsInd TINYINT NOT NULL,"
+CREATE TABLE IF NOT EXISTS mch_answers (
+ MchCod INT NOT NULL,
+ UsrCod INT NOT NULL,
+ QstInd INT NOT NULL,
+ NumOpt TINYINT NOT NULL,
+ AnsInd TINYINT NOT NULL,
UNIQUE INDEX(MchCod,UsrCod,QstInd));
--
-- Table mch_groups: stores the groups associated to each match in a game
diff --git a/swad_changelog.h b/swad_changelog.h
index 8ce2bec0..73e9fd35 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -470,10 +470,15 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
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 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.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)
diff --git a/swad_database.c b/swad_database.c
index 392d3160..9135efd2 100644
--- a/swad_database.c
+++ b/swad_database.c
@@ -1339,15 +1339,17 @@ mysql> DESCRIBE mch_answers;
| MchCod | int(11) | NO | PRI | NULL | |
| UsrCod | 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 ("
"MchCod INT NOT NULL,"
"UsrCod 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))");
/***** Table mch_groups *****/
diff --git a/swad_game.c b/swad_game.c
index 5aeefd9a..b5169c41 100644
--- a/swad_game.c
+++ b/swad_game.c
@@ -1382,13 +1382,13 @@ void Gam_PutParamQstInd (unsigned QstInd)
unsigned Gam_GetParamQstInd (void)
{
- long LongNum;
+ long QstInd;
- LongNum = Par_GetParToLong ("QstInd");
- if (LongNum < 0)
+ QstInd = Par_GetParToLong ("QstInd");
+ if (QstInd < 0)
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)
{
- long LongNum;
+ long QstInd;
- LongNum = Str_ConvertStrCodToLongCod (UnsignedStr);
- return (LongNum > 0) ? (unsigned) LongNum :
- 0;
+ QstInd = Str_ConvertStrCodToLongCod (UnsignedStr);
+ return (QstInd > 0) ? (unsigned) QstInd :
+ 0;
}
/*****************************************************************************/
diff --git a/swad_match.c b/swad_match.c
index c8ff76ab..2952ebd2 100644
--- a/swad_match.c
+++ b/swad_match.c
@@ -99,6 +99,12 @@ struct Match
} Status;
};
+struct Mch_UsrAnswer
+ {
+ int NumOpt; // < 0 ==> no answer selected
+ int AnsInd; // < 0 ==> no answer selected
+ };
+
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
@@ -177,8 +183,8 @@ static void Mch_ShowMatchTitle (struct Match *Match);
static void Mch_ShowQuestionAndAnswersTch (struct Match *Match);
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match);
-static void Mch_PutParamAnswer (unsigned AnsInd);
-static unsigned Mch_GetParamAnswer (void);
+static void Mch_PutParamNumOpt (unsigned NumOpt);
+static unsigned Mch_GetParamNumOpt (void);
static void Mch_PutBigButton (Act_Action_t NextAction,long MchCod,
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_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,
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",
"SELECT gam_questions.QstCod," // row[0]
"gam_questions.QstInd," // row[1]
- "tst_questions.AnsType" // row[2]
+ "tst_questions.AnsType," // row[2]
"tst_questions.Shuffle" // row[3]
" FROM gam_questions,tst_questions"
" 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",
"SELECT AnsInd" // row[0]
" FROM tst_answers"
- " WHERE GamCod=%ld"
+ " WHERE QstCod=%ld"
" ORDER BY %s",
QstCod,
- Shuffle ? "RAND(NOW())" :
+ Shuffle ? "RAND()" : // Use RAND() because is really random; RAND(NOW()) repeats order
"AnsInd");
/***** For each answer in question... *****/
@@ -1170,10 +1177,10 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
if ((LongNum = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong answer index.");
AnsInd = (unsigned) LongNum;
+ snprintf (StrOneAnswer,sizeof (StrOneAnswer),
+ "%u",AnsInd);
/* Concatenate answer index to list of answers */
- snprintf (StrOneAnswer,10 + 1,
- "%u",AnsInd);
if (NumAns)
Str_Concat (StrAnswersOneQst,",",
Tst_MAX_BYTES_ANSWERS_ONE_QST);
@@ -1193,6 +1200,38 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
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 *********************/
/*****************************************************************************/
@@ -1976,7 +2015,10 @@ static void Mch_ShowQuestionAndAnswersTch (struct Match *Match)
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
"TEST_MED_EDIT_LIST_STEM");
- /* Write answers? */
+ /***** Free structure that stores the query result *****/
+ DB_FreeMySQLResult (&mysql_res);
+
+ /***** Write answers? *****/
switch (Match->Status.Showing)
{
case Mch_NOTHING:
@@ -2013,14 +2055,9 @@ static void Mch_ShowQuestionAndAnswersTch (struct Match *Match)
static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
{
- bool Shuffle = false; // TODO: Read shuffle from question
- MYSQL_RES *mysql_res;
- MYSQL_ROW row;
- int StdAnsInd;
+ struct Mch_UsrAnswer UsrAnswer;
unsigned NumOptions;
unsigned NumOpt;
- unsigned Index;
- bool ErrorInIndex = false;
/***** Show question *****/
/* Write buttons for answers? */
@@ -2030,24 +2067,14 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
{
/***** Get student's answer to this question
(<0 ==> no answer) *****/
- StdAnsInd = Mch_GetQstAnsFromDB (Match->MchCod,
- Gbl.Usrs.Me.UsrDat.UsrCod,
- Match->Status.QstInd);
+ Mch_GetQstAnsFromDB (Match->MchCod,
+ Gbl.Usrs.Me.UsrDat.UsrCod,
+ Match->Status.QstInd,
+ &UsrAnswer);
/***** Get number of options in this question *****/
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 *****/
Tbl_StartTableWide (8);
@@ -2055,24 +2082,7 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
NumOpt < NumOptions;
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 *****/
- // if (NumOpt % 2 == 0)
fprintf (Gbl.F.Out,"
");
/***** Write letter for this option *****/
@@ -2086,12 +2096,12 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match)
Frm_StartForm (ActAnsMchQstStd);
Mch_PutParamMchCod (Match->MchCod); // Current match being played
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,"
");
}
@@ -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");
- if (LongNum < 0)
- Lay_ShowErrorAndExit ("Wrong answer index.");
+ NumOpt = Par_GetParToLong ("NumOpt");
+ if (NumOpt < 0)
+ 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 *****/
/*****************************************************************************/
-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_ROW row;
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 *****/
- NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get student's answer to a match question",
- "SELECT AnsInd FROM mch_answers"
+ NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get user's answer to a match question",
+ "SELECT NumOpt," // row[0]
+ "AnsInd" // row[1]
+ " FROM mch_answers"
" WHERE MchCod=%ld"
" AND UsrCod=%ld"
" AND QstInd=%u",
MchCod,UsrCod,QstInd);
if (NumRows) // Answer found...
{
- /***** Get answer index *****/
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.");
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
-
- return AnsInd;
}
/*****************************************************************************/
@@ -2420,8 +2437,9 @@ void Mch_ReceiveQstAnsFromStd (void)
{
struct Match Match;
unsigned QstInd;
- unsigned StdAnsInd;
- int PreviousStdAnsInd;
+ unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION];
+ struct Mch_UsrAnswer PreviousUsrAnswer;
+ struct Mch_UsrAnswer UsrAnswer;
unsigned NumQsts;
unsigned NumQstsNotBlank;
double TotalScore;
@@ -2437,39 +2455,53 @@ void Mch_ReceiveQstAnsFromStd (void)
/***** Get question index from form *****/
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 *****/
if (QstInd == Match.Status.QstInd) // Receiving an answer
// to the current question being played
{
/***** Get answer index *****/
- /*-------+--------------+
- | Button | Answer index |
- +--------+--------------+
- | a | 0 |
- | b | 1 |
- | c | 2 |
- | d | 3 |
- | ... | ... |
- +--------+-------------*/
- StdAnsInd = Mch_GetParamAnswer ();
+ /*
+ Indexes[4] = {0,3,1,2}
+ +-------+--------+----------+---------+
+ | Button | Option | Answer | Correct |
+ | letter | number | index | |
+ | screen | screen | database | |
+ +--------+--------+----------+---------+
+ | a | 0 | 0 | |
+ | b | 1 | 3 | |
+ | 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
(<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 *****/
- if (PreviousStdAnsInd == (int) StdAnsInd)
- DB_QueryDELETE ("can not register your answer to the match question",
+ if (PreviousUsrAnswer.AnsInd == UsrAnswer.AnsInd)
+ DB_QueryDELETE ("can not remove your answer to the match question",
"DELETE FROM mch_answers"
" WHERE MchCod=%ld AND UsrCod=%ld AND QstInd=%u",
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",
"REPLACE mch_answers"
- " (MchCod,UsrCod,QstInd,AnsInd)"
+ " (MchCod,UsrCod,QstInd,NumOpt,AnsInd)"
" VALUES"
- " (%ld,%ld,%u,%u)",
- Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd,StdAnsInd);
+ " (%ld,%ld,%u,%d,%d)",
+ Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd,
+ UsrAnswer.NumOpt,
+ UsrAnswer.AnsInd);
/***** Update student's match result *****/
NumQsts = Gam_GetNumQstsGame (Match.GamCod);
@@ -2488,7 +2520,7 @@ void Mch_ReceiveQstAnsFromStd (void)
"NumQsts=%u,"
"NumQstsNotBlank=%u,"
"Score='%lf'"
- " WHERE MchCod=%ld AND UsrCod=%ld",
+ " WHERE MchCod=%ld AND UsrCod=%ld",
NumQsts,NumQstsNotBlank,TotalScore,
Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod);
else // Result doesn't exist
@@ -2529,7 +2561,7 @@ static void Mch_ComputeScore (struct Match *Match,unsigned NumQsts,long UsrCod,
double ScoreThisQst;
bool AnswerIsNotBlank;
long LongNum;
- int AnsInd;
+ struct Mch_UsrAnswer UsrAnswer;
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this 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]
"gam_questions.QstInd," // row[1]
"mch_indexes.Indexes" // row[2]
- " FROM mch_matches,gam_questions,mch_questions"
+ " FROM mch_matches,gam_questions,mch_indexes"
" WHERE mch_matches.MchCod=%ld"
" AND mch_matches.GamCod=gam_questions.GamCod"
" AND mch_matches.MchCod=mch_indexes.MchCod"
- " AND mch_matches.QstInd=mch_indexes.QstInd"
+ " AND gam_questions.QstInd=mch_indexes.QstInd"
" ORDER BY gam_questions.QstInd");
/***** 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);
/***** Get answers selected by user for this question *****/
- AnsInd = Mch_GetQstAnsFromDB (Match->MchCod,UsrCod,QstInd);
- if (AnsInd >= 0) // AnsInd >= 0 ==> answer selected
+ Mch_GetQstAnsFromDB (Match->MchCod,UsrCod,QstInd,&UsrAnswer);
+ if (UsrAnswer.AnsInd >= 0) // AnsInd >= 0 ==> answer selected
{
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
- "%d",AnsInd);
+ "%d",UsrAnswer.AnsInd);
(*NumQstsNotBlank)++;
}
else // AnsInd < 0 ==> no answer selected
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
/***** Get indexes for this question from string *****/
+ Par_ReplaceCommaBySeparatorMultiple (Gbl.Test.StrIndexesOneQst[NumQst]);
Tst_GetIndexesFromStr (Gbl.Test.StrIndexesOneQst[NumQst],Indexes);
/***** Get the user's answers for this question from string *****/
+ Par_ReplaceCommaBySeparatorMultiple (Gbl.Test.StrAnswersOneQst[NumQst]);
Tst_GetAnswersFromStr (Gbl.Test.StrAnswersOneQst[NumQst],AnswersUsr);
/***** Get correct answers of test question from database *****/
@@ -3486,7 +3520,7 @@ static void Mch_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod)
unsigned NumQst;
long LongNum;
unsigned QstInd;
- int AnsInd;
+ struct Mch_UsrAnswer UsrAnswer;
/***** Get questions and answers of a match result *****/
NumQsts = (unsigned)
@@ -3521,11 +3555,11 @@ static void Mch_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod)
Tst_MAX_BYTES_INDEXES_ONE_QST);
/* Get answers selected by user for this question */
- AnsInd = Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd);
- if (AnsInd >= 0) // AnsInd >= 0 ==> answer selected
+ Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer);
+ if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
- "%d",AnsInd);
- else // AnsInd < 0 ==> no answer selected
+ "%d",UsrAnswer.AnsInd);
+ else // UsrAnswer.AnsInd < 0 ==> no answer selected
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
/* Replace each comma by a separator of multiple parameters */
diff --git a/swad_match.h b/swad_match.h
index ddfab7bd..0f9c77fd 100644
--- a/swad_match.h
+++ b/swad_match.h
@@ -48,6 +48,8 @@ void Mch_RemoveMatchTch (void);
void Mch_CreateNewMatchTch (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_ResumeMatchTch (void);
void Mch_ToggleDisplayResultsMatchTch (void);
diff --git a/swad_parameter.c b/swad_parameter.c
index 924e9b5b..f1442433 100644
--- a/swad_parameter.c
+++ b/swad_parameter.c
@@ -981,9 +981,11 @@ bool Par_GetNextStrUntilSeparParamMult (const char **StrSrc,char *StrDst,size_t
do
if ((Ch = (unsigned char) **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;
if (i < LongMax)
diff --git a/swad_parameter.h b/swad_parameter.h
index 971d4a1a..dc372653 100644
--- a/swad_parameter.h
+++ b/swad_parameter.h
@@ -85,6 +85,7 @@ unsigned Par_GetParAndChangeFormat (const char *ParamName,char *ParamValue,size_
Str_ChangeTo_t ChangeTo,bool RemoveLeadingAndTrailingSpaces);
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_ReplaceCommaBySeparatorMultiple (char *Str);
diff --git a/swad_test.c b/swad_test.c
index f43f80d1..38a551ad 100644
--- a/swad_test.c
+++ b/swad_test.c
@@ -4017,13 +4017,22 @@ void Tst_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ON
const char *Ptr;
char StrOneIndex[10 + 1];
+ /***** Initialize to 0 *****/
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++)
{
Par_GetNextStrUntilSeparParamMult (&Ptr,StrOneIndex,10);
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;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
- unsigned AnsInd;
unsigned NumAnswerersQst;
- bool Correct;
- bool ErrorInIndex = false;
+ unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
- /***** 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);
/***** Get answers of a question from database *****/
@@ -4154,45 +4161,47 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
row[4] Correct
*/
- /***** Start table *****/
- Tbl_StartTableWide (2);
-
for (NumOpt = 0;
NumOpt < Gbl.Test.Answer.NumOptions;
NumOpt++)
{
- /***** Get next answer *****/
+ /* Get next answer */
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))
/* Abort on error */
Ale_ShowAlertsAndExit ();
- /***** 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",&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 ******/
+ /* Copy text (row[1]) and convert it, that is in HTML, to rigorous HTML */
Str_Copy (Gbl.Test.Answer.Options[NumOpt].Text,row[1],
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
Gbl.Test.Answer.Options[NumOpt].Text,
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]);
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 *****/
fprintf (Gbl.F.Out,"
");
@@ -4212,22 +4221,18 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
"",
QstInd,NumOpt,
Class,
- Gbl.Test.Answer.Options[NumOpt].Text);
- Med_ShowMedia (&Gbl.Test.Answer.Options[NumOpt].Media,
+ Gbl.Test.Answer.Options[Indexes[NumOpt]].Text);
+ Med_ShowMedia (&Gbl.Test.Answer.Options[Indexes[NumOpt]].Media,
"TEST_MED_SHOW_CONTAINER",
"TEST_MED_SHOW");
/* Show result (number of users who answered? */
if (ShowResult)
- {
- /* Get if correct (row[4]) */
- Correct = (row[4][0] == 'Y');
-
/* Get number of users who selected this answer
and draw proportional bar */
- Mch_GetAndDrawBarNumUsrsWhoHaveChosenAns (MchCod,QstInd,AnsInd,
- NumAnswerersQst,Correct);
- }
+ Mch_GetAndDrawBarNumUsrsWhoHaveChosenAns (MchCod,QstInd,Indexes[NumOpt],
+ NumAnswerersQst,
+ Gbl.Test.Answer.Options[Indexes[NumOpt]].Correct);
fprintf (Gbl.F.Out,"");
@@ -4237,9 +4242,6 @@ static void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod
/***** End table *****/
Tbl_EndTable ();
-
- /***** Free structure that stores the query result *****/
- DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/