// swad_test.h: self-assessment tests #ifndef _SWAD_TST #define _SWAD_TST /* SWAD (Shared Workspace At a Distance in Spanish), is a web platform developed at the University of Granada (Spain), and used to support university teaching. This file is part of SWAD core. Copyright (C) 1999-2019 Antonio Caņas Vargas This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ /*****************************************************************************/ /********************************* Headers ***********************************/ /*****************************************************************************/ #include "swad_game.h" /*****************************************************************************/ /***************************** Public constants ******************************/ /*****************************************************************************/ #define Tst_SCORE_MAX 10 // Maximum score of a test (10 in Spain). Must be unsigned! // TODO: Make this configurable by teachers #define Tst_MAX_QUESTIONS_PER_TEST 100 // Absolute maximum number of questions in a test #define Tst_MAX_TAGS_PER_QUESTION 5 #define Tst_MAX_CHARS_TAG (128 - 1) // 127 #define Tst_MAX_BYTES_TAG ((Tst_MAX_CHARS_TAG + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 #define Tst_MAX_OPTIONS_PER_QUESTION 10 #define Tst_MAX_BYTES_INDEXES_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (10 + 1)) #define Tst_MAX_BYTES_ANSWERS_ONE_QST (Tst_MAX_OPTIONS_PER_QUESTION * (10 + 1)) #define Tst_MAX_CHARS_ANSWER_OR_FEEDBACK (1024 - 1) // 1023 #define Tst_MAX_BYTES_ANSWER_OR_FEEDBACK ((Tst_MAX_CHARS_ANSWER_OR_FEEDBACK + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 16383 #define Tst_CONFIG_DEFAULT_MIN_QUESTIONS 1 #define Tst_CONFIG_DEFAULT_DEF_QUESTIONS 20 // Number of questions to be generated by default in a self-assessment test #define Tst_CONFIG_DEFAULT_MAX_QUESTIONS 30 // Maximum number of questions to be generated in a self-assessment test #define Tst_MAX_BYTES_FEEDBACK_TYPE 32 #define Tst_MAX_BYTES_ANSWER_TYPE 32 /*****************************************************************************/ /******************************* Public types ********************************/ /*****************************************************************************/ #define Tst_NUM_OPTIONS_PLUGGABLE 3 typedef enum { Tst_PLUGGABLE_UNKNOWN = 0, Tst_PLUGGABLE_NO = 1, Tst_PLUGGABLE_YES = 2, } Tst_Pluggable_t; typedef enum { Tst_SHOW_TEST_TO_ANSWER, // Showing a test to a student Tst_SHOW_TEST_RESULT, // Showing the assessment of a test Tst_EDIT_TEST, // Editing test questions Tst_SELECT_QUESTIONS_FOR_GAME, // Selecting test questions for a game Tst_SHOW_GAME_TO_ANSWER, // Showing a game to a student Tst_SHOW_GAME_RESULT, // Showing the assessment of a game } Tst_ActionToDoWithQuestions_t; #define Tst_NUM_TYPES_FEEDBACK 5 typedef enum { Tst_FEEDBACK_NOTHING = 0, Tst_FEEDBACK_TOTAL_RESULT = 1, Tst_FEEDBACK_EACH_RESULT = 2, Tst_FEEDBACK_EACH_GOOD_BAD = 3, Tst_FEEDBACK_FULL_FEEDBACK = 4, } Tst_Feedback_t; #define Tst_FEEDBACK_DEFAULT Tst_FEEDBACK_FULL_FEEDBACK struct Tst_Config { Tst_Pluggable_t Pluggable; unsigned Min; // Minimum number of questions unsigned Def; // Default number of questions unsigned Max; // Maximum number of questions unsigned long MinTimeNxtTstPerQst; Tst_Feedback_t Feedback; }; #define Tst_NUM_ANS_TYPES 6 #define Tst_MAX_BYTES_LIST_ANSWER_TYPES (10 + (Tst_NUM_ANS_TYPES - 1) * (1 + 10)) typedef enum { Tst_ANS_INT = 0, Tst_ANS_FLOAT = 1, Tst_ANS_TRUE_FALSE = 2, Tst_ANS_UNIQUE_CHOICE = 3, Tst_ANS_MULTIPLE_CHOICE = 4, Tst_ANS_TEXT = 5, Tst_ANS_ALL = 6, // All/any type of answer } Tst_AnswerType_t; #define Tst_NUM_TYPES_ORDER_QST 5 typedef enum { Tst_ORDER_STEM = 0, Tst_ORDER_NUM_HITS = 1, Tst_ORDER_AVERAGE_SCORE = 2, Tst_ORDER_NUM_HITS_NOT_BLANK = 3, Tst_ORDER_AVERAGE_SCORE_NOT_BLANK = 4, } Tst_QuestionsOrder_t; struct Tst_Stats { unsigned NumCoursesWithQuestions; unsigned NumCoursesWithPluggableQuestions; unsigned NumQsts; float AvgQstsPerCourse; unsigned long NumHits; float AvgHitsPerCourse; float AvgHitsPerQuestion; double TotalScore; double AvgScorePerQuestion; }; /*****************************************************************************/ /***************************** Public prototypes *****************************/ /*****************************************************************************/ void Tst_ShowFormAskTst (void); void Tst_ShowNewTest (void); void Tst_AssessTest (void); void Tst_WriteQstStem (const char *Stem,const char *ClassStem); void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback); void Tst_ShowFormAskEditTsts (void); void Tst_ShowFormAskSelectTstsForGame (long GamCod); void Tst_ListQuestionsToEdit (void); void Tst_ListQuestionsToSelect (void); bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); void Tst_WriteParamEditQst (void); unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle); void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod, const char *Class,bool ShowResult); void Tst_WriteAnsTF (char AnsTF); void Tst_CheckIfNumberOfAnswersIsOne (void); unsigned long Tst_GetTagsQst (long QstCod,MYSQL_RES **mysql_res); void Tst_GetAndWriteTagsQst (long QstCod); void Tst_ShowFormConfig (void); void Tst_EnableTag (void); void Tst_DisableTag (void); void Tst_RenameTag (void); void Tst_GetConfigFromRow (MYSQL_ROW row); bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void); void Tst_ReceiveConfigTst (void); void Tst_ShowFormEditOneQst (void); void Tst_QstConstructor (void); void Tst_QstDestructor (void); int Tst_AllocateTextChoiceAnswer (unsigned NumOpt); Tst_AnswerType_t Tst_ConvertFromStrAnsTypDBToAnsTyp (const char *StrAnsTypeBD); void Tst_ReceiveQst (void); bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void); long Tst_GetIntAnsFromStr (char *Str); double Tst_GetFloatAnsFromStr (char *Str); void Tst_RequestRemoveQst (void); void Tst_RemoveQst (void); void Tst_ChangeShuffleQst (void); void Tst_PutParamQstCod (void); void Tst_InsertOrUpdateQstTagsAnsIntoDB (void); void Tst_FreeTagsList (void); void Tst_GetTestStats (Tst_AnswerType_t AnsType,struct Tst_Stats *Stats); void Tst_SelUsrsToSeeUsrsTestResults (void); void Tst_SelDatesToSeeMyTestResults (void); void Tst_ShowUsrsTestResults (void); void Tst_ShowMyTestResults (void); void Tst_ShowOneTestResult (void); void Tst_RemoveTestResultsMadeByUsrInAllCrss (long UsrCod); void Tst_RemoveTestResultsMadeByUsrInCrs (long UsrCod,long CrsCod); void Tst_RemoveCrsTestResults (long CrsCod); void Tst_RemoveCrsTests (long CrsCod); #endif