Version 22.113: May 19, 2023 Check if a rubric is recursive.

This commit is contained in:
acanas 2023-05-19 14:02:23 +02:00
parent 0796f50539
commit a32d962dc3
9 changed files with 173 additions and 11 deletions

View File

@ -629,10 +629,11 @@ TODO: Emilce Barrera Mesa: Podr
TODO: Emilce Barrera Mesa: Mis estudiantes presentan muchas dificultades a la hora de poner la foto porque la plataforma es muy exigente respecto al fondo de la imagen.
*/
#define Log_PLATFORM_VERSION "SWAD 22.112 (2023-05-18)"
#define Log_PLATFORM_VERSION "SWAD 22.113 (2023-05-19)"
#define CSS_FILE "swad22.107.36.css"
#define JS_FILE "swad22.49.js"
/*
Version 22.113: May 19, 2023 Check if a rubric is recursive. (336936 lines)
Version 22.112: May 18, 2023 Code refactoring in options of selectors. (336794 lines)
Version 22.111: May 17, 2023 A project can have more than one rubric in each category. (336691 lines)
Version 22.110.3: May 15, 2023 Changes in rubrics. (336550 lines)

View File

@ -418,6 +418,17 @@ void Err_WrongMatchExit (void)
Err_ShowErrorAndExit ("Wrong match.");
}
/*****************************************************************************/
/************** Write error message when a rubric is recursive ***************/
/*****************************************************************************/
void Err_RecursiveRubric (void)
{
extern const char *Txt_Recursive_rubric;
Ale_ShowAlert (Ale_ERROR,Txt_Recursive_rubric);
}
/*****************************************************************************/
/************** Write error message and exit when wrong ribric ***************/
/*****************************************************************************/

View File

@ -78,6 +78,7 @@ void Err_WrongAnswerTypeExit (void);
void Err_WrongExamSessionExit (void);
void Err_WrongGameExit (void);
void Err_WrongMatchExit (void);
void Err_RecursiveRubric (void);
void Err_WrongRubricExit (void);
void Err_WrongCriterionExit (void);
void Err_WrongCriterionIndexExit (void);

View File

@ -4577,8 +4577,19 @@ static void Prj_ShowRubricsOfType (struct Prj_Projects *Projects,
/* Change color for rubric criteria */
The_ChangeRowColor ();
/* Write criteria of this rubric */
RubCri_ListCriteriaInProject (Projects,Rubric.RubCod,ICanFill);
/* Check if rubric tree is correct */
if (Rub_CheckRubricsTree (Rubric.RubCod,
NULL)) // The stack has not yet been created
/* Write criteria of this rubric */
RubCri_ListCriteriaInProject (Projects,Rubric.RubCod,ICanFill);
else
{
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"8\" class=\"CT %s\"",The_GetColorRows ());
Err_RecursiveRubric ();
HTM_TD_End ();
HTM_TR_End ();
}
/* Change color for next rubric */
The_ChangeRowColor ();

View File

@ -356,6 +356,11 @@ void Rub_ShowOnlyOneRubric (struct Rub_Rubrics *Rubrics)
Rub_ShowRubricMainData (Rubrics,
true); // Show only this rubric
/***** Check if rubric tree is correct *****/
if (!Rub_CheckRubricsTree (Rubrics->Rubric.RubCod,
NULL)) // The stack has not yet been created
Err_RecursiveRubric ();
/***** Write criteria of this rubric *****/
RubCri_ListCriteriaForSeeing (Rubrics);
@ -794,6 +799,11 @@ void Rub_PutFormsOneRubric (struct Rub_Rubrics *Rubrics,
/***** Put form to create/edit a rubric *****/
Rub_PutFormEditionRubric (Rubrics,ExistingNewRubric);
/***** Check if rubric tree is correct *****/
if (!Rub_CheckRubricsTree (Rubrics->Rubric.RubCod,
NULL)) // The stack has not yet been created
Err_RecursiveRubric ();
/***** Show list of criteria inside box *****/
if (ExistingNewRubric == Rub_EXISTING_RUBRIC)
RubCri_ListCriteriaForEdition (Rubrics);
@ -1013,6 +1023,103 @@ static void Rub_UpdateRubric (struct Rub_Rubric *Rubric)
Ale_ShowAlert (Ale_SUCCESS,Txt_The_rubric_has_been_modified);
}
/*****************************************************************************/
/********** Recursive function to compute the score of a criterion ***********/
/*****************************************************************************/
// Return true if tree is ok, or false if infinite recursion
/* Tree Stack
_______ ______
| Rub 1 | TOS (Top Of Stack)____\|___5__|
|_______| /|_Prev_|
/|\ _____/
/ | \ / ______
/ | \ \_\|___4__|
/ | \ /|_Prev_|
/ ___|___ \ _____/
/ | Rub 2 | \ / ______
Handwritten |_______| Handwritten \_\|___2__|
/|\ /|_Prev_|
/ | \ _____/
/ | \ / ______
/ | \ \_\|___1__|
/ | \ /|_NULL_|
_______/ | \_______
| Rub 3 | | | Rub 4 |
|_______|Handwritten|_______|
/ /|\
/ / | \
/ / | \
/ / | \
/ / ___|___ \
/ / | Rub 5 | \
Handwritten Handwritten |_______| Handwritten
/|\
/ | \
/ | \
/ | \
/ | \
/ | \
Handwritten Handwritten Handwritten
*/
bool Rub_CheckRubricsTree (long RubCod,struct Node *TOS)
{
struct Node *Node;
bool TreeOk;
MYSQL_RES *mysql_res;
unsigned NumCriteria;
unsigned NumCriterion;
struct RubCri_Criterion Criterion;
/***** Check that rubric is not yet in the stack *****/
for (Node = TOS, TreeOk = true;
Node && TreeOk;
Node = Node->Prev)
if (Node->RubCod == RubCod)
TreeOk = false;
if (TreeOk)
{
/***** Push rubric code in stack *****/
/* Save current top of stack */
Node = TOS;
/* Create top of stack node */
if ((TOS = malloc (sizeof (struct Node))) == NULL)
Err_NotEnoughMemoryExit ();
TOS->RubCod = RubCod;
TOS->Prev = Node;
/* For each criteria in this rubric... */
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
for (NumCriterion = 0;
NumCriterion < NumCriteria && TreeOk;
NumCriterion++)
{
/* Get criterion data */
RubCri_GetCriterionDataFromRow (mysql_res,&Criterion);
switch (Criterion.Link.Type)
{
case Rsc_RUBRIC:
if (!Rub_CheckRubricsTree (Criterion.Link.Cod,TOS))
TreeOk = false;
break;
default:
break;
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Pop rubric code from stack *****/
free (TOS);
}
return TreeOk;
}
/*****************************************************************************/
/************************** Show stats about rubrics *************************/
/*****************************************************************************/

View File

@ -37,6 +37,12 @@
#define RubCri_AFTER_LAST_CRITERION ((unsigned)((1UL << 31) - 1)) // 2^31 - 1, don't change this number because it is used in database
struct Node
{
long RubCod;
struct Node *Prev;
};
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
@ -72,6 +78,8 @@ void Rub_PutFormsOneRubric (struct Rub_Rubrics *Rubrics,
void Rub_ReceiveFormRubric (void);
bool Rub_CheckRubricsTree (long RubCod,struct Node *TOS);
//-------------------------------- Figures ------------------------------------
void Rub_GetAndShowRubricsStats (void);

View File

@ -120,12 +120,10 @@ static void RubCri_WriteMinimumMaximum (const struct RubCri_Criterion *Criterion
static void RubCri_WriteWeight (const struct RubCri_Criterion *Criterion);
static void RubCri_WriteTotalLabel (unsigned ColSpan);
static void RubCri_WriteTotalValue (double Total);
static double RubCri_ComputeScore (long PrjCod,
const struct RubCri_Criterion *Criterion);
static void RubCri_GetCriterionDataFromRow (MYSQL_RES *mysql_res,
struct RubCri_Criterion *Criterion);
static void RubCri_PutTableHeadingForCriteria (RubCri_PutColumnForIcons_t PutColumnForIcons,
RubCri_PutColumnsForScore_t PutColumnsForScore);
@ -995,7 +993,6 @@ static void RubCri_WriteTotalValue (double Total)
static double RubCri_ComputeScore (long PrjCod,
const struct RubCri_Criterion *Criterion)
{
long RubCod;
MYSQL_RES *mysql_res;
unsigned NumCriteria;
unsigned NumCriterion;
@ -1010,10 +1007,9 @@ static double RubCri_ComputeScore (long PrjCod,
break;
case Rsc_RUBRIC:
Score = 0.0;
RubCod = Criterion->Link.Cod;
/***** Get data of rubric criteria from database *****/
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
NumCriteria = Rub_DB_GetCriteria (&mysql_res,Criterion->Link.Cod);
for (NumCriterion = 0;
NumCriterion < NumCriteria;
NumCriterion++)
@ -1056,8 +1052,8 @@ double RubCri_GetParScore (void)
/************************** Get rubric criteria data *************************/
/*****************************************************************************/
static void RubCri_GetCriterionDataFromRow (MYSQL_RES *mysql_res,
struct RubCri_Criterion *Criterion)
void RubCri_GetCriterionDataFromRow (MYSQL_RES *mysql_res,
struct RubCri_Criterion *Criterion)
{
MYSQL_ROW row;
RubCri_ValueRange_t ValueRange;

View File

@ -46,8 +46,12 @@ void RubCri_ListCriteriaForSeeing (const struct Rub_Rubrics *Rubrics);
void RubCri_ListCriteriaForEdition (struct Rub_Rubrics *Rubrics);
void RubCri_ListCriteriaInProject (struct Prj_Projects *Projects,long RubCod,
bool ICanFill);
double RubCri_GetParScore (void);
void RubCri_GetCriterionDataFromRow (MYSQL_RES *mysql_res,
struct RubCri_Criterion *Criterion);
void RubCri_ResetCriterion (struct RubCri_Criterion *Criterion);
void RubCri_ReqRemCriterion (void);

View File

@ -32920,6 +32920,29 @@ const char *Txt_Recipients =
"Recipients"; // Çeviri lazim!
#endif
const char *Txt_Recursive_rubric =
#if L==1 // ca
"R&uacute;brica recursiva";
#elif L==2 // de
"Rekursive Rubrik";
#elif L==3 // en
"Recursive rubric";
#elif L==4 // es
"R&uacute;brica recursiva";
#elif L==5 // fr
"Rubrique r&eacute;cursive";
#elif L==6 // gn
"R&uacute;brica recursiva";
#elif L==7 // it
"Rubrica ricorsiva";
#elif L==8 // pl
"Rubryka rekurencyjna";
#elif L==9 // pt
"Rubrica recursiva";
#elif L==10 // tr
"&Ouml;zyinelemeli de&gbreve;erlendirme listesi";
#endif
const char *Txt_Register =
#if L==1 // ca
"Inscriure";