mirror of https://github.com/acanas/swad-core.git
Version19.157
This commit is contained in:
parent
2603e5a906
commit
d8233a0aa8
|
@ -13250,6 +13250,7 @@ INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2010; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2011; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2011; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2012; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2012; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2013; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2013; Hecho
|
||||||
|
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140101' AND ClickTime<'20140201'; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140101' AND ClickTime<'20140201'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140201' AND ClickTime<'20140301'; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140201' AND ClickTime<'20140301'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140301' AND ClickTime<'20140401'; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140301' AND ClickTime<'20140401'; Hecho
|
||||||
|
@ -13259,13 +13260,38 @@ INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140601' AND ClickTime
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140701' AND ClickTime<'20140801'; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140701' AND ClickTime<'20140801'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140801' AND ClickTime<'20140901'; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140801' AND ClickTime<'20140901'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140901' AND ClickTime<'20141001'; Hecho
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20140901' AND ClickTime<'20141001'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20141001' AND ClickTime<'20141101';
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20141001' AND ClickTime<'20141101'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20141101' AND ClickTime<'20141201';
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20141101' AND ClickTime<'20141201'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20141201' AND ClickTime<'20150101';
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20141201' AND ClickTime<'20150101'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2015;
|
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2016;
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150101' AND ClickTime<'20150201'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2017;
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150201' AND ClickTime<'20150301'; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2018;
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150301' AND ClickTime<'20150401'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150401' AND ClickTime<'20150501'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150501' AND ClickTime<'20150601'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150601' AND ClickTime<'20150701'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150701' AND ClickTime<'20150801'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150801' AND ClickTime<'20150901'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20150901' AND ClickTime<'20151001'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20151001' AND ClickTime<'20151101'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20151101' AND ClickTime<'20151201'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20151201' AND ClickTime<'20160101'; Hecho
|
||||||
|
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160101' AND ClickTime<'20160201'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160201' AND ClickTime<'20160301'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160301' AND ClickTime<'20160401'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160401' AND ClickTime<'20160501'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160501' AND ClickTime<'20160601'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160601' AND ClickTime<'20160701'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160701' AND ClickTime<'20160801'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160801' AND ClickTime<'20160901'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20160901' AND ClickTime<'20161001'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20161001' AND ClickTime<'20161101'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20161101' AND ClickTime<'20161201'; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE ClickTime>='20161201' AND ClickTime<'20170101'; Hecho
|
||||||
|
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2017; Hecho
|
||||||
|
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2018; Hecho
|
||||||
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2019;
|
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2019;
|
||||||
# hasta aquí ya hecho en openswad.org, aún no en swad.ugr.es
|
# hasta aquí ya hecho en openswad.org, aún no en swad.ugr.es
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,16 @@
|
||||||
SWAD (Shared Workspace At a Distance),
|
SWAD (Shared Workspace At a Distance),
|
||||||
is a web platform developed at the University of Granada (Spain),
|
is a web platform developed at the University of Granada (Spain),
|
||||||
and used to support university teaching.
|
and used to support university teaching.
|
||||||
|
|
||||||
This file is part of SWAD core.
|
This file is part of SWAD core.
|
||||||
Copyright (C) 1999-2020 Antonio Cañas Vargas
|
Copyright (C) 1999-2020 Antonio Cañas Vargas
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as
|
||||||
published by the Free Software Foundation, either version 3 of the
|
published by the Free Software Foundation, either version 3 of the
|
||||||
License, or (at your option) any later version.
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -497,7 +497,7 @@ 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.156.4 (2020-03-29)"
|
#define Log_PLATFORM_VERSION "SWAD 19.157 (2020-04-01)"
|
||||||
#define CSS_FILE "swad19.146.css"
|
#define CSS_FILE "swad19.146.css"
|
||||||
#define JS_FILE "swad19.153.js"
|
#define JS_FILE "swad19.153.js"
|
||||||
/*
|
/*
|
||||||
|
@ -528,7 +528,8 @@ Param
|
||||||
El examen se muestra en pantalla tomándolo del examen en la base de datos, no del formulario.
|
El examen se muestra en pantalla tomándolo del examen en la base de datos, no del formulario.
|
||||||
Cuando el alumno pulsa en "He terminado" se le pregunta si está seguro y se vuelve a mostrar el examen cogiéndolo de la base de datos.
|
Cuando el alumno pulsa en "He terminado" se le pregunta si está seguro y se vuelve a mostrar el examen cogiéndolo de la base de datos.
|
||||||
|
|
||||||
Version 19.156.5: Mar 29, 2020 Test exam is stored in database when it's generated. (? lines)
|
Version 19.157: Apr 01, 2020 Code refactoring in tests.
|
||||||
|
Test exam is stored in database when it's generated. Not tested. (285023 lines)
|
||||||
Version 19.156.4: Mar 29, 2020 Code refactoring in tests. (284657 lines)
|
Version 19.156.4: Mar 29, 2020 Code refactoring in tests. (284657 lines)
|
||||||
Version 19.156.3: Mar 29, 2020 Code refactoring in tests. (284585 lines)
|
Version 19.156.3: Mar 29, 2020 Code refactoring in tests. (284585 lines)
|
||||||
Version 19.156.2: Mar 29, 2020 Test exam with start date and end date. (284568 lines)
|
Version 19.156.2: Mar 29, 2020 Test exam with start date and end date. (284568 lines)
|
||||||
|
|
18
swad_match.c
18
swad_match.c
|
@ -3956,10 +3956,6 @@ static void Mch_ComputeScore (struct TsR_Result *Result)
|
||||||
{
|
{
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
double ScoreThisQst;
|
|
||||||
bool AnswerIsNotBlank;
|
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION];
|
|
||||||
|
|
||||||
for (NumQst = 0, Result->Score = 0.0;
|
for (NumQst = 0, Result->Score = 0.0;
|
||||||
NumQst < Result->NumQsts;
|
NumQst < Result->NumQsts;
|
||||||
|
@ -3967,20 +3963,14 @@ static void Mch_ComputeScore (struct TsR_Result *Result)
|
||||||
{
|
{
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question);
|
Tst_QstConstructor (&Question);
|
||||||
Question.QstCod = Result->QstCodes[NumQst];
|
Question.QstCod = Result->Questions[NumQst].QstCod;
|
||||||
Question.Answer.Type = Tst_ANS_UNIQUE_CHOICE;
|
Question.Answer.Type = Tst_ANS_UNIQUE_CHOICE;
|
||||||
|
|
||||||
/***** Get correct answers of test question from database *****/
|
/***** Compute score for this answer ******/
|
||||||
Tst_GetCorrectAnswersFromDB (&Question);
|
Tst_ComputeChoiceAnsScore (Result,NumQst,&Question);
|
||||||
|
|
||||||
/***** Compute the score of this question *****/
|
|
||||||
Tst_GetIndexesFromStr (Result->StrIndexes[NumQst],Indexes);
|
|
||||||
Tst_GetAnswersFromStr (Result->StrAnswers[NumQst],AnswersUsr);
|
|
||||||
Tst_ComputeScoreQst (&Question,
|
|
||||||
Indexes,AnswersUsr,&ScoreThisQst,&AnswerIsNotBlank);
|
|
||||||
|
|
||||||
/***** Update total score *****/
|
/***** Update total score *****/
|
||||||
Result->Score += ScoreThisQst;
|
Result->Score += Result->Questions[NumQst].Score;
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor (&Question);
|
Tst_QstDestructor (&Question);
|
||||||
|
|
|
@ -1251,7 +1251,7 @@ void McR_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod,
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/* Get question code (row[0]) */
|
/* Get question code (row[0]) */
|
||||||
if ((Result->QstCodes[NumQst] = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/* Get question index (row[1]) */
|
/* Get question index (row[1]) */
|
||||||
|
@ -1260,24 +1260,24 @@ void McR_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod,
|
||||||
QstInd = (unsigned) LongNum;
|
QstInd = (unsigned) LongNum;
|
||||||
|
|
||||||
/* Get indexes for this question (row[2]) */
|
/* Get indexes for this question (row[2]) */
|
||||||
Str_Copy (Result->StrIndexes[NumQst],row[2],
|
Str_Copy (Result->Questions[NumQst].StrIndexes,row[2],
|
||||||
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 */
|
||||||
Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer);
|
Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer);
|
||||||
if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
|
if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
|
||||||
{
|
{
|
||||||
snprintf (Result->StrAnswers[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
snprintf (Result->Questions[NumQst].StrAnswers,Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
||||||
"%d",UsrAnswer.AnsInd);
|
"%d",UsrAnswer.AnsInd);
|
||||||
Result->NumQstsNotBlank++;
|
Result->NumQstsNotBlank++;
|
||||||
}
|
}
|
||||||
else // UsrAnswer.AnsInd < 0 ==> no answer selected
|
else // UsrAnswer.AnsInd < 0 ==> no answer selected
|
||||||
Result->StrAnswers[NumQst][0] = '\0'; // Empty answer
|
Result->Questions[NumQst].StrAnswers[0] = '\0'; // Empty answer
|
||||||
|
|
||||||
/* Replace each comma by a separator of multiple parameters */
|
/* Replace each comma by a separator of multiple parameters */
|
||||||
/* In database commas are used as separators instead of special chars */
|
/* In database commas are used as separators instead of special chars */
|
||||||
Par_ReplaceCommaBySeparatorMultiple (Result->StrIndexes[NumQst]);
|
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes);
|
||||||
Par_ReplaceCommaBySeparatorMultiple (Result->StrAnswers[NumQst]);
|
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
|
|
|
@ -267,7 +267,7 @@ void Med_GetMediaDataByCod (struct Media *Media)
|
||||||
size_t Length;
|
size_t Length;
|
||||||
|
|
||||||
/***** Get data of a media from database *****/
|
/***** Get data of a media from database *****/
|
||||||
NumRows = DB_QuerySELECT (&mysql_res,"can not get data of a post",
|
NumRows = DB_QuerySELECT (&mysql_res,"can not get media",
|
||||||
"SELECT Type," // row[0]
|
"SELECT Type," // row[0]
|
||||||
"Name," // row[1]
|
"Name," // row[1]
|
||||||
"URL," // row[2]
|
"URL," // row[2]
|
||||||
|
|
2125
swad_test.c
2125
swad_test.c
File diff suppressed because it is too large
Load Diff
20
swad_test.h
20
swad_test.h
|
@ -155,6 +155,12 @@ void Tst_ShowNewTest (void);
|
||||||
void Tst_RequestAssessTest (void);
|
void Tst_RequestAssessTest (void);
|
||||||
void Tst_AssessTest (void);
|
void Tst_AssessTest (void);
|
||||||
|
|
||||||
|
void Tst_ComputeChoiceAnsScore (struct TsR_Result *Result,
|
||||||
|
unsigned NumQst,
|
||||||
|
struct Tst_Question *Question);
|
||||||
|
void Tst_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc.
|
||||||
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
||||||
|
|
||||||
void Tst_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade);
|
void Tst_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade);
|
||||||
double Tst_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade);
|
double Tst_ComputeGrade (unsigned NumQsts,double Score,double MaxGrade);
|
||||||
void Tst_ShowGrade (double Grade,double MaxGrade);
|
void Tst_ShowGrade (double Grade,double MaxGrade);
|
||||||
|
@ -162,11 +168,10 @@ void Tst_ShowGrade (double Grade,double MaxGrade);
|
||||||
void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res);
|
void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res);
|
||||||
|
|
||||||
void Tst_WriteQstAndAnsTestResult (struct UsrData *UsrDat,
|
void Tst_WriteQstAndAnsTestResult (struct UsrData *UsrDat,
|
||||||
const struct TsR_Result *Result,
|
struct TsR_Result *Result,
|
||||||
unsigned NumQst,
|
unsigned NumQst,
|
||||||
MYSQL_ROW row,
|
MYSQL_ROW row,
|
||||||
unsigned Visibility,
|
unsigned Visibility);
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
|
||||||
void Tst_WriteNumQst (unsigned NumQst);
|
void Tst_WriteNumQst (unsigned NumQst);
|
||||||
void Tst_WriteAnswerType (Tst_AnswerType_t AnswerType);
|
void Tst_WriteAnswerType (Tst_AnswerType_t AnswerType);
|
||||||
void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible);
|
void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible);
|
||||||
|
@ -183,18 +188,9 @@ void Tst_WriteParamEditQst (const struct Tst_Test *Test);
|
||||||
unsigned Tst_GetNumAnswersQst (long QstCod);
|
unsigned Tst_GetNumAnswersQst (long QstCod);
|
||||||
void Tst_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
|
void Tst_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
|
||||||
bool Shuffle);
|
bool Shuffle);
|
||||||
void Tst_GetCorrectAnswersFromDB (struct Tst_Question *Question);
|
|
||||||
void Tst_WriteAnswersListing (struct Tst_Question *Question);
|
void Tst_WriteAnswersListing (struct Tst_Question *Question);
|
||||||
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
|
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
|
||||||
void Tst_WriteAnsTF (char AnsTF);
|
void Tst_WriteAnsTF (char AnsTF);
|
||||||
void Tst_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc.
|
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
|
||||||
void Tst_GetAnswersFromStr (const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1],
|
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION]);
|
|
||||||
void Tst_ComputeScoreQst (const struct Tst_Question *Question,
|
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION],
|
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION],
|
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
|
||||||
void Tst_CheckIfNumberOfAnswersIsOne (const struct Tst_Question *Question);
|
void Tst_CheckIfNumberOfAnswersIsOne (const struct Tst_Question *Question);
|
||||||
|
|
||||||
unsigned long Tst_GetTagsQst (long QstCod,MYSQL_RES **mysql_res);
|
unsigned long Tst_GetTagsQst (long QstCod,MYSQL_RES **mysql_res);
|
||||||
|
|
|
@ -168,13 +168,13 @@ void TsR_ShowMyTstResults (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************* Store test result in database *************************/
|
/**************** Create new blank test result in database *******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
long TsR_CreateTestResultInDB (const struct TsR_Result *Result)
|
void TsR_CreateTestResultInDB (struct TsR_Result *Result)
|
||||||
{
|
{
|
||||||
/***** Insert new test result into table *****/
|
/***** Insert new test result into table *****/
|
||||||
return
|
Result->TstCod =
|
||||||
DB_QueryINSERTandReturnCode ("can not create new test result",
|
DB_QueryINSERTandReturnCode ("can not create new test result",
|
||||||
"INSERT INTO tst_exams"
|
"INSERT INTO tst_exams"
|
||||||
" (CrsCod,UsrCod,StartTime,EndTime,NumQsts,AllowTeachers)"
|
" (CrsCod,UsrCod,StartTime,EndTime,NumQsts,AllowTeachers)"
|
||||||
|
@ -191,19 +191,22 @@ long TsR_CreateTestResultInDB (const struct TsR_Result *Result)
|
||||||
/********************* Store test result in database *************************/
|
/********************* Store test result in database *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TsR_StoreScoreOfTestResultInDB (long TstCod,
|
void TsR_UpdateScoreOfTestResultInDB (const struct TsR_Result *Result)
|
||||||
const struct TsR_Result *Result)
|
|
||||||
{
|
{
|
||||||
/***** Update score in test result *****/
|
/***** Update score in test result *****/
|
||||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
DB_QueryUPDATE ("can not update test result",
|
DB_QueryUPDATE ("can not update test result",
|
||||||
"UPDATE tst_exams"
|
"UPDATE tst_exams"
|
||||||
" SET NumQstsNotBlank=%u,"
|
" SET EndTime=NOW(),"
|
||||||
|
"NumQstsNotBlank=%u,"
|
||||||
"Score='%.15lg'"
|
"Score='%.15lg'"
|
||||||
" WHERE TstCod=%ld",
|
" WHERE TstCod=%ld"
|
||||||
|
" AND CrsCod=%ld AND UsrCod=%ld", // Extra checks
|
||||||
Result->NumQstsNotBlank,
|
Result->NumQstsNotBlank,
|
||||||
Result->Score,
|
Result->Score,
|
||||||
TstCod);
|
Result->TstCod,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,7 +850,7 @@ void TsR_ShowOneTstResult (void)
|
||||||
static void TsR_ShowTstTagsPresentInATestResult (long TstCod)
|
static void TsR_ShowTstTagsPresentInATestResult (long TstCod)
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned long NumTags;
|
unsigned NumTags;
|
||||||
|
|
||||||
/***** Get all tags of questions in this test *****/
|
/***** Get all tags of questions in this test *****/
|
||||||
NumTags = (unsigned)
|
NumTags = (unsigned)
|
||||||
|
@ -874,7 +877,7 @@ static void TsR_ShowTstTagsPresentInATestResult (long TstCod)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TsR_ShowTestResult (struct UsrData *UsrDat,
|
void TsR_ShowTestResult (struct UsrData *UsrDat,
|
||||||
const struct TsR_Result *Result,
|
struct TsR_Result *Result,
|
||||||
unsigned Visibility)
|
unsigned Visibility)
|
||||||
{
|
{
|
||||||
extern const char *Txt_Question_modified;
|
extern const char *Txt_Question_modified;
|
||||||
|
@ -882,8 +885,6 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
double ScoreThisQst;
|
|
||||||
bool AnswerIsNotBlank;
|
|
||||||
bool ThisQuestionHasBeenEdited;
|
bool ThisQuestionHasBeenEdited;
|
||||||
time_t EditTimeUTC;
|
time_t EditTimeUTC;
|
||||||
|
|
||||||
|
@ -894,7 +895,7 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
|
||||||
Gbl.RowEvenOdd = NumQst % 2;
|
Gbl.RowEvenOdd = NumQst % 2;
|
||||||
|
|
||||||
/***** Query database *****/
|
/***** Query database *****/
|
||||||
if (Tst_GetOneQuestionByCod (Result->QstCodes[NumQst],&mysql_res)) // Question exists
|
if (Tst_GetOneQuestionByCod (Result->Questions[NumQst].QstCod,&mysql_res)) // Question exists
|
||||||
{
|
{
|
||||||
/***** Get row of the result of the query *****/
|
/***** Get row of the result of the query *****/
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
@ -927,9 +928,7 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
|
||||||
Result,
|
Result,
|
||||||
NumQst,
|
NumQst,
|
||||||
row,
|
row,
|
||||||
Visibility,
|
Visibility);
|
||||||
&ScoreThisQst, // Not used here
|
|
||||||
&AnswerIsNotBlank); // Not used here
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1020,17 +1019,16 @@ static void TsR_GetTestResultDataByTstCod (long TstCod,struct TsR_Result *Result
|
||||||
/************ Store user's answers of an test result into database ***********/
|
/************ Store user's answers of an test result into database ***********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TsR_StoreOneTestResultQstInDB (long TstCod,
|
void TsR_StoreOneTestResultQstInDB (const struct TsR_Result *Result,
|
||||||
const struct TsR_Result *Result,
|
unsigned NumQst)
|
||||||
unsigned NumQst,double ScoreThisQst)
|
|
||||||
{
|
{
|
||||||
char Indexes[Tst_MAX_BYTES_INDEXES_ONE_QST + 1];
|
char StrIndexes[Tst_MAX_BYTES_INDEXES_ONE_QST + 1];
|
||||||
char Answers[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1];
|
char StrAnswers[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1];
|
||||||
|
|
||||||
/***** Replace each separator of multiple parameters by a comma *****/
|
/***** Replace each separator of multiple parameters by a comma *****/
|
||||||
/* In database commas are used as separators instead of special chars */
|
/* In database commas are used as separators instead of special chars */
|
||||||
Par_ReplaceSeparatorMultipleByComma (Result->StrIndexes[NumQst],Indexes);
|
Par_ReplaceSeparatorMultipleByComma (Result->Questions[NumQst].StrIndexes,StrIndexes);
|
||||||
Par_ReplaceSeparatorMultipleByComma (Result->StrAnswers[NumQst],Answers);
|
Par_ReplaceSeparatorMultipleByComma (Result->Questions[NumQst].StrAnswers,StrAnswers);
|
||||||
|
|
||||||
/***** Insert question and user's answers into database *****/
|
/***** Insert question and user's answers into database *****/
|
||||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
|
@ -1039,11 +1037,11 @@ void TsR_StoreOneTestResultQstInDB (long TstCod,
|
||||||
" (TstCod,QstCod,QstInd,Score,Indexes,Answers)"
|
" (TstCod,QstCod,QstInd,Score,Indexes,Answers)"
|
||||||
" VALUES"
|
" VALUES"
|
||||||
" (%ld,%ld,%u,'%.15lg','%s','%s')",
|
" (%ld,%ld,%u,'%.15lg','%s','%s')",
|
||||||
TstCod,Result->QstCodes[NumQst],
|
Result->TstCod,Result->Questions[NumQst].QstCod,
|
||||||
NumQst, // 0, 1, 2, 3...
|
NumQst, // 0, 1, 2, 3...
|
||||||
ScoreThisQst,
|
Result->Questions[NumQst].Score,
|
||||||
Indexes,
|
StrIndexes,
|
||||||
Answers);
|
StrAnswers);
|
||||||
Str_SetDecimalPointToLocal (); // Return to local system
|
Str_SetDecimalPointToLocal (); // Return to local system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,21 +1075,21 @@ static void TsR_GetTestResultQuestionsFromDB (long TstCod,struct TsR_Result *Res
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/* Get question code */
|
/* Get question code */
|
||||||
if ((Result->QstCodes[NumQst] = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/* Get indexes for this question (row[1]) */
|
/* Get indexes for this question (row[1]) */
|
||||||
Str_Copy (Result->StrIndexes[NumQst],row[1],
|
Str_Copy (Result->Questions[NumQst].StrIndexes,row[1],
|
||||||
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
||||||
|
|
||||||
/* Get answers selected by user for this question (row[2]) */
|
/* Get answers selected by user for this question (row[2]) */
|
||||||
Str_Copy (Result->StrAnswers[NumQst],row[2],
|
Str_Copy (Result->Questions[NumQst].StrAnswers,row[2],
|
||||||
Tst_MAX_BYTES_ANSWERS_ONE_QST);
|
Tst_MAX_BYTES_ANSWERS_ONE_QST);
|
||||||
|
|
||||||
/* Replace each comma by a separator of multiple parameters */
|
/* Replace each comma by a separator of multiple parameters */
|
||||||
/* In database commas are used as separators instead of special chars */
|
/* In database commas are used as separators instead of special chars */
|
||||||
Par_ReplaceCommaBySeparatorMultiple (Result->StrIndexes[NumQst]);
|
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes);
|
||||||
Par_ReplaceCommaBySeparatorMultiple (Result->StrAnswers[NumQst]);
|
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
|
|
|
@ -45,16 +45,20 @@
|
||||||
|
|
||||||
struct TsR_Result
|
struct TsR_Result
|
||||||
{
|
{
|
||||||
|
long TstCod; // Exam code
|
||||||
time_t TimeUTC[Dat_NUM_START_END_TIME];
|
time_t TimeUTC[Dat_NUM_START_END_TIME];
|
||||||
unsigned NumQsts;
|
unsigned NumQsts; // Number of questions
|
||||||
unsigned NumQstsNotBlank;
|
unsigned NumQstsNotBlank; // Number of questions not blank
|
||||||
long QstCodes[TstCfg_MAX_QUESTIONS_PER_TEST]; // Codes of the sent/received questions in a test
|
bool AllowTeachers; // Are teachers allowed to see this test result?
|
||||||
char StrIndexes[TstCfg_MAX_QUESTIONS_PER_TEST]
|
double Score; // Total score of the test result
|
||||||
[Tst_MAX_BYTES_INDEXES_ONE_QST + 1]; // 0 1 2 3, 3 0 2 1, etc.
|
struct
|
||||||
char StrAnswers[TstCfg_MAX_QUESTIONS_PER_TEST]
|
{
|
||||||
[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user
|
long QstCod; // Question code
|
||||||
bool AllowTeachers; // Are teachers allowed to see this test result?
|
char StrIndexes[Tst_MAX_BYTES_INDEXES_ONE_QST + 1]; // 0 1 2 3, 3 0 2 1, etc.
|
||||||
double Score; // Total score of the test result
|
char StrAnswers[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user
|
||||||
|
double Score; // Question score
|
||||||
|
bool AnswerIsNotBlank; // Answer not blank?
|
||||||
|
} Questions[TstCfg_MAX_QUESTIONS_PER_TEST];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -64,17 +68,15 @@ struct TsR_Result
|
||||||
void TsR_SelUsrsToViewUsrsTstResults (void);
|
void TsR_SelUsrsToViewUsrsTstResults (void);
|
||||||
void TsR_SelDatesToSeeMyTstResults (void);
|
void TsR_SelDatesToSeeMyTstResults (void);
|
||||||
void TsR_ShowMyTstResults (void);
|
void TsR_ShowMyTstResults (void);
|
||||||
long TsR_CreateTestResultInDB (const struct TsR_Result *Result);
|
void TsR_CreateTestResultInDB (struct TsR_Result *Result);
|
||||||
void TsR_StoreScoreOfTestResultInDB (long TstCod,
|
void TsR_UpdateScoreOfTestResultInDB (const struct TsR_Result *Result);
|
||||||
const struct TsR_Result *Result);
|
|
||||||
void TsR_GetUsrsAndShowTstResults (void);
|
void TsR_GetUsrsAndShowTstResults (void);
|
||||||
void TsR_ShowOneTstResult (void);
|
void TsR_ShowOneTstResult (void);
|
||||||
void TsR_ShowTestResult (struct UsrData *UsrDat,
|
void TsR_ShowTestResult (struct UsrData *UsrDat,
|
||||||
const struct TsR_Result *Result,
|
struct TsR_Result *Result,
|
||||||
unsigned Visibility);
|
unsigned Visibility);
|
||||||
void TsR_StoreOneTestResultQstInDB (long TstCod,
|
void TsR_StoreOneTestResultQstInDB (const struct TsR_Result *Result,
|
||||||
const struct TsR_Result *Result,
|
unsigned NumQst);
|
||||||
unsigned NumQst,double ScoreThisQst);
|
|
||||||
void TsR_RemoveTestResultsMadeByUsrInAllCrss (long UsrCod);
|
void TsR_RemoveTestResultsMadeByUsrInAllCrss (long UsrCod);
|
||||||
void TsR_RemoveTestResultsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
void TsR_RemoveTestResultsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
||||||
void TsR_RemoveCrsTestResults (long CrsCod);
|
void TsR_RemoveCrsTestResults (long CrsCod);
|
||||||
|
|
Loading…
Reference in New Issue