mirror of https://github.com/acanas/swad-core.git
Version 22.114: May 19, 2023 Check if a rubric is recursive.
This commit is contained in:
parent
a32d962dc3
commit
0bbd73d188
|
@ -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.
|
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.113 (2023-05-19)"
|
#define Log_PLATFORM_VERSION "SWAD 22.114 (2023-05-19)"
|
||||||
#define CSS_FILE "swad22.107.36.css"
|
#define CSS_FILE "swad22.107.36.css"
|
||||||
#define JS_FILE "swad22.49.js"
|
#define JS_FILE "swad22.49.js"
|
||||||
/*
|
/*
|
||||||
|
Version 22.114: May 19, 2023 Check if a rubric is recursive. (336984 lines)
|
||||||
Version 22.113: May 19, 2023 Check if a rubric is recursive. (336936 lines)
|
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.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.111: May 17, 2023 A project can have more than one rubric in each category. (336691 lines)
|
||||||
|
|
|
@ -4577,19 +4577,8 @@ static void Prj_ShowRubricsOfType (struct Prj_Projects *Projects,
|
||||||
/* Change color for rubric criteria */
|
/* Change color for rubric criteria */
|
||||||
The_ChangeRowColor ();
|
The_ChangeRowColor ();
|
||||||
|
|
||||||
/* Check if rubric tree is correct */
|
|
||||||
if (Rub_CheckRubricsTree (Rubric.RubCod,
|
|
||||||
NULL)) // The stack has not yet been created
|
|
||||||
/* Write criteria of this rubric */
|
/* Write criteria of this rubric */
|
||||||
RubCri_ListCriteriaInProject (Projects,Rubric.RubCod,ICanFill);
|
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 */
|
/* Change color for next rubric */
|
||||||
The_ChangeRowColor ();
|
The_ChangeRowColor ();
|
||||||
|
|
|
@ -345,6 +345,7 @@ void Rub_ShowOnlyOneRubric (struct Rub_Rubrics *Rubrics)
|
||||||
{
|
{
|
||||||
extern const char *Hlp_ASSESSMENT_Rubrics;
|
extern const char *Hlp_ASSESSMENT_Rubrics;
|
||||||
extern const char *Txt_Rubric;
|
extern const char *Txt_Rubric;
|
||||||
|
struct Node *TOS = NULL;
|
||||||
|
|
||||||
/***** Begin box *****/
|
/***** Begin box *****/
|
||||||
Box_BoxBegin (NULL,Rubrics->Rubric.Title[0] ? Rubrics->Rubric.Title :
|
Box_BoxBegin (NULL,Rubrics->Rubric.Title[0] ? Rubrics->Rubric.Title :
|
||||||
|
@ -357,8 +358,7 @@ void Rub_ShowOnlyOneRubric (struct Rub_Rubrics *Rubrics)
|
||||||
true); // Show only this rubric
|
true); // Show only this rubric
|
||||||
|
|
||||||
/***** Check if rubric tree is correct *****/
|
/***** Check if rubric tree is correct *****/
|
||||||
if (!Rub_CheckRubricsTree (Rubrics->Rubric.RubCod,
|
if (Rub_CheckIfRecursiveTree (Rubrics->Rubric.RubCod,&TOS))
|
||||||
NULL)) // The stack has not yet been created
|
|
||||||
Err_RecursiveRubric ();
|
Err_RecursiveRubric ();
|
||||||
|
|
||||||
/***** Write criteria of this rubric *****/
|
/***** Write criteria of this rubric *****/
|
||||||
|
@ -788,6 +788,7 @@ void Rub_PutFormsOneRubric (struct Rub_Rubrics *Rubrics,
|
||||||
[Rub_EXISTING_RUBRIC] = &Hlp_ASSESSMENT_Rubrics_edit_rubric,
|
[Rub_EXISTING_RUBRIC] = &Hlp_ASSESSMENT_Rubrics_edit_rubric,
|
||||||
[Rub_NEW_RUBRIC ] = &Hlp_ASSESSMENT_Rubrics_new_rubric,
|
[Rub_NEW_RUBRIC ] = &Hlp_ASSESSMENT_Rubrics_new_rubric,
|
||||||
};
|
};
|
||||||
|
struct Node *TOS = NULL;
|
||||||
|
|
||||||
/***** Begin box *****/
|
/***** Begin box *****/
|
||||||
Box_BoxBegin (NULL,
|
Box_BoxBegin (NULL,
|
||||||
|
@ -800,8 +801,7 @@ void Rub_PutFormsOneRubric (struct Rub_Rubrics *Rubrics,
|
||||||
Rub_PutFormEditionRubric (Rubrics,ExistingNewRubric);
|
Rub_PutFormEditionRubric (Rubrics,ExistingNewRubric);
|
||||||
|
|
||||||
/***** Check if rubric tree is correct *****/
|
/***** Check if rubric tree is correct *****/
|
||||||
if (!Rub_CheckRubricsTree (Rubrics->Rubric.RubCod,
|
if (Rub_CheckIfRecursiveTree (Rubrics->Rubric.RubCod,&TOS))
|
||||||
NULL)) // The stack has not yet been created
|
|
||||||
Err_RecursiveRubric ();
|
Err_RecursiveRubric ();
|
||||||
|
|
||||||
/***** Show list of criteria inside box *****/
|
/***** Show list of criteria inside box *****/
|
||||||
|
@ -1026,7 +1026,7 @@ static void Rub_UpdateRubric (struct Rub_Rubric *Rubric)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********** Recursive function to compute the score of a criterion ***********/
|
/********** Recursive function to compute the score of a criterion ***********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// Return true if tree is ok, or false if infinite recursion
|
// Return true if rubric tree is recursive
|
||||||
/* Tree Stack
|
/* Tree Stack
|
||||||
_______ ______
|
_______ ______
|
||||||
| Rub 1 | TOS (Top Of Stack)____\|___5__|
|
| Rub 1 | TOS (Top Of Stack)____\|___5__|
|
||||||
|
@ -1061,51 +1061,35 @@ Handwritten Handwritten |_______| Handwritten
|
||||||
/ | \
|
/ | \
|
||||||
Handwritten Handwritten Handwritten
|
Handwritten Handwritten Handwritten
|
||||||
*/
|
*/
|
||||||
|
bool Rub_CheckIfRecursiveTree (long RubCod,struct Node **TOS)
|
||||||
bool Rub_CheckRubricsTree (long RubCod,struct Node *TOS)
|
|
||||||
{
|
{
|
||||||
struct Node *Node;
|
bool RecursiveTree;
|
||||||
bool TreeOk;
|
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned NumCriteria;
|
unsigned NumCriteria;
|
||||||
unsigned NumCriterion;
|
unsigned NumCriterion;
|
||||||
struct RubCri_Criterion Criterion;
|
struct RubCri_Criterion Criterion;
|
||||||
|
|
||||||
/***** Check that rubric is not yet in the stack *****/
|
/***** Check that rubric is not yet in the stack *****/
|
||||||
for (Node = TOS, TreeOk = true;
|
RecursiveTree = Rub_FindRubCodInStack (*TOS,RubCod);
|
||||||
Node && TreeOk;
|
|
||||||
Node = Node->Prev)
|
|
||||||
if (Node->RubCod == RubCod)
|
|
||||||
TreeOk = false;
|
|
||||||
|
|
||||||
if (TreeOk)
|
if (!RecursiveTree)
|
||||||
{
|
{
|
||||||
/***** Push rubric code in stack *****/
|
/***** Push rubric code in stack *****/
|
||||||
/* Save current top of stack */
|
Rub_PushRubCod (TOS,RubCod);
|
||||||
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... */
|
/* For each criteria in this rubric... */
|
||||||
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
|
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
|
||||||
for (NumCriterion = 0;
|
for (NumCriterion = 0;
|
||||||
NumCriterion < NumCriteria && TreeOk;
|
NumCriterion < NumCriteria;
|
||||||
NumCriterion++)
|
NumCriterion++)
|
||||||
{
|
{
|
||||||
/* Get criterion data */
|
/* Get criterion data */
|
||||||
RubCri_GetCriterionDataFromRow (mysql_res,&Criterion);
|
RubCri_GetCriterionDataFromRow (mysql_res,&Criterion);
|
||||||
|
|
||||||
switch (Criterion.Link.Type)
|
if (Criterion.Link.Type == Rsc_RUBRIC)
|
||||||
|
if (Rub_CheckIfRecursiveTree (Criterion.Link.Cod,TOS))
|
||||||
{
|
{
|
||||||
case Rsc_RUBRIC:
|
RecursiveTree = true;
|
||||||
if (!Rub_CheckRubricsTree (Criterion.Link.Cod,TOS))
|
|
||||||
TreeOk = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1114,10 +1098,10 @@ bool Rub_CheckRubricsTree (long RubCod,struct Node *TOS)
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
/***** Pop rubric code from stack *****/
|
/***** Pop rubric code from stack *****/
|
||||||
free (TOS);
|
Rub_PopRubCod (TOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TreeOk;
|
return RecursiveTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -78,7 +78,7 @@ void Rub_PutFormsOneRubric (struct Rub_Rubrics *Rubrics,
|
||||||
|
|
||||||
void Rub_ReceiveFormRubric (void);
|
void Rub_ReceiveFormRubric (void);
|
||||||
|
|
||||||
bool Rub_CheckRubricsTree (long RubCod,struct Node *TOS);
|
bool Rub_CheckIfRecursiveTree (long RubCod,struct Node **TOS);
|
||||||
|
|
||||||
//-------------------------------- Figures ------------------------------------
|
//-------------------------------- Figures ------------------------------------
|
||||||
void Rub_GetAndShowRubricsStats (void);
|
void Rub_GetAndShowRubricsStats (void);
|
||||||
|
|
|
@ -109,6 +109,7 @@ static void RubCri_ListOneOrMoreCriteriaForEdition (struct Rub_Rubrics *Rubrics,
|
||||||
unsigned NumCriteria,
|
unsigned NumCriteria,
|
||||||
MYSQL_RES *mysql_res);
|
MYSQL_RES *mysql_res);
|
||||||
static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects,
|
static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects,
|
||||||
|
struct Node **TOS,
|
||||||
bool ICanFill,
|
bool ICanFill,
|
||||||
unsigned NumCriteria,
|
unsigned NumCriteria,
|
||||||
MYSQL_RES *mysql_res);
|
MYSQL_RES *mysql_res);
|
||||||
|
@ -121,8 +122,8 @@ static void RubCri_WriteWeight (const struct RubCri_Criterion *Criterion);
|
||||||
static void RubCri_WriteTotalLabel (unsigned ColSpan);
|
static void RubCri_WriteTotalLabel (unsigned ColSpan);
|
||||||
static void RubCri_WriteTotalValue (double Total);
|
static void RubCri_WriteTotalValue (double Total);
|
||||||
|
|
||||||
static double RubCri_ComputeScore (long PrjCod,
|
static bool RubCri_ComputeRubricScore (long PrjCod,struct Node **TOS,long RubCod,
|
||||||
const struct RubCri_Criterion *Criterion);
|
double *RubricScore);
|
||||||
|
|
||||||
static void RubCri_PutTableHeadingForCriteria (RubCri_PutColumnForIcons_t PutColumnForIcons,
|
static void RubCri_PutTableHeadingForCriteria (RubCri_PutColumnForIcons_t PutColumnForIcons,
|
||||||
RubCri_PutColumnsForScore_t PutColumnsForScore);
|
RubCri_PutColumnsForScore_t PutColumnsForScore);
|
||||||
|
@ -574,15 +575,25 @@ void RubCri_ListCriteriaInProject (struct Prj_Projects *Projects,long RubCod,
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned NumCriteria;
|
unsigned NumCriteria;
|
||||||
|
struct Node *TOS;
|
||||||
|
|
||||||
/***** Get data of rubric criteria from database *****/
|
/***** Get data of rubric criteria from database *****/
|
||||||
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
|
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
|
||||||
|
|
||||||
/***** Show table with rubric criteria *****/
|
/***** Show table with rubric criteria *****/
|
||||||
if (NumCriteria)
|
if (NumCriteria)
|
||||||
RubCri_ListOneOrMoreCriteriaInProject (Projects,ICanFill,
|
{
|
||||||
|
/* Push rubric code in stack */
|
||||||
|
Rub_PushRubCod (&TOS,RubCod);
|
||||||
|
|
||||||
|
/* List rubric criteria */
|
||||||
|
RubCri_ListOneOrMoreCriteriaInProject (Projects,&TOS,ICanFill,
|
||||||
NumCriteria,mysql_res);
|
NumCriteria,mysql_res);
|
||||||
|
|
||||||
|
/* Pop rubric code from stack */
|
||||||
|
Rub_PopRubCod (&TOS);
|
||||||
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
}
|
}
|
||||||
|
@ -795,6 +806,7 @@ static void RubCri_ListOneOrMoreCriteriaForEdition (struct Rub_Rubrics *Rubrics,
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects,
|
static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects,
|
||||||
|
struct Node **TOS,
|
||||||
bool ICanFill,
|
bool ICanFill,
|
||||||
unsigned NumCriteria,
|
unsigned NumCriteria,
|
||||||
MYSQL_RES *mysql_res)
|
MYSQL_RES *mysql_res)
|
||||||
|
@ -803,7 +815,7 @@ static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects
|
||||||
struct RubCri_Criterion Criterion;
|
struct RubCri_Criterion Criterion;
|
||||||
unsigned NumCriterion;
|
unsigned NumCriterion;
|
||||||
char *Anchor;
|
char *Anchor;
|
||||||
double Score;
|
double CriterionScore;
|
||||||
double WeightedScore;
|
double WeightedScore;
|
||||||
double SumOfWeights = 0.0;
|
double SumOfWeights = 0.0;
|
||||||
double SumOfScores = 0.0;
|
double SumOfScores = 0.0;
|
||||||
|
@ -820,13 +832,6 @@ static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects
|
||||||
{
|
{
|
||||||
/***** Get criterion data *****/
|
/***** Get criterion data *****/
|
||||||
RubCri_GetCriterionDataFromRow (mysql_res,&Criterion);
|
RubCri_GetCriterionDataFromRow (mysql_res,&Criterion);
|
||||||
SumOfWeights += Criterion.Weight;
|
|
||||||
|
|
||||||
/***** Compute score *****/
|
|
||||||
Score = RubCri_ComputeScore (Projects->Prj.PrjCod,&Criterion);
|
|
||||||
WeightedScore = Score * Criterion.Weight;
|
|
||||||
SumOfScores += Score;
|
|
||||||
WeightedSum += WeightedScore;
|
|
||||||
|
|
||||||
/***** Build anchor string *****/
|
/***** Build anchor string *****/
|
||||||
Frm_SetAnchorStr (Criterion.CriCod,&Anchor);
|
Frm_SetAnchorStr (Criterion.CriCod,&Anchor);
|
||||||
|
@ -849,6 +854,7 @@ static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects
|
||||||
switch (Criterion.Link.Type)
|
switch (Criterion.Link.Type)
|
||||||
{
|
{
|
||||||
case Rsc_NONE:
|
case Rsc_NONE:
|
||||||
|
CriterionScore = Prj_DB_GetScore (Projects->Prj.PrjCod,Criterion.CriCod);
|
||||||
if (ICanFill)
|
if (ICanFill)
|
||||||
{
|
{
|
||||||
Frm_BeginFormAnchor (ActChgPrjSco,Anchor);
|
Frm_BeginFormAnchor (ActChgPrjSco,Anchor);
|
||||||
|
@ -858,7 +864,7 @@ static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects
|
||||||
Criterion.Values[RubCri_MIN],
|
Criterion.Values[RubCri_MIN],
|
||||||
Criterion.Values[RubCri_MAX],
|
Criterion.Values[RubCri_MAX],
|
||||||
RubCri_SCORE_STEP,
|
RubCri_SCORE_STEP,
|
||||||
Score,
|
CriterionScore,
|
||||||
HTM_SUBMIT_ON_CHANGE,false,
|
HTM_SUBMIT_ON_CHANGE,false,
|
||||||
" class=\"INPUT_FLOAT INPUT_%s\""
|
" class=\"INPUT_FLOAT INPUT_%s\""
|
||||||
" required=\"required\"",
|
" required=\"required\"",
|
||||||
|
@ -866,10 +872,15 @@ static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects
|
||||||
Frm_EndForm ();
|
Frm_EndForm ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
HTM_Double2Decimals (Score);
|
HTM_Double2Decimals (CriterionScore);
|
||||||
break;
|
break;
|
||||||
case Rsc_RUBRIC:
|
case Rsc_RUBRIC:
|
||||||
HTM_Double2Decimals (Score);
|
if (RubCri_ComputeRubricScore (Projects->Prj.PrjCod,TOS,
|
||||||
|
Criterion.Link.Cod,
|
||||||
|
&CriterionScore))
|
||||||
|
Err_RecursiveRubric ();
|
||||||
|
else
|
||||||
|
HTM_Double2Decimals (CriterionScore);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Err_NoPermission ();
|
Err_NoPermission ();
|
||||||
|
@ -881,11 +892,17 @@ static void RubCri_ListOneOrMoreCriteriaInProject (struct Prj_Projects *Projects
|
||||||
HTM_TD_Begin ("class=\"RT DAT_%s %s\"",
|
HTM_TD_Begin ("class=\"RT DAT_%s %s\"",
|
||||||
The_GetSuffix (),
|
The_GetSuffix (),
|
||||||
The_GetColorRows ());
|
The_GetColorRows ());
|
||||||
|
WeightedScore = CriterionScore * Criterion.Weight;
|
||||||
HTM_Double2Decimals (WeightedScore);
|
HTM_Double2Decimals (WeightedScore);
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/***** End row *****/
|
/***** End row *****/
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
/***** Update totals *****/
|
||||||
|
SumOfWeights += Criterion.Weight;
|
||||||
|
SumOfScores += CriterionScore;
|
||||||
|
WeightedSum += WeightedScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Write total row *****/
|
/***** Write total row *****/
|
||||||
|
@ -989,50 +1006,119 @@ static void RubCri_WriteTotalValue (double Total)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********** Recursive function to compute the score of a criterion ***********/
|
/********** Recursive function to compute the score of a criterion ***********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
// Return true if rubric tree is recursive
|
||||||
|
|
||||||
static double RubCri_ComputeScore (long PrjCod,
|
static bool RubCri_ComputeRubricScore (long PrjCod,struct Node **TOS,long RubCod,
|
||||||
const struct RubCri_Criterion *Criterion)
|
double *RubricScore)
|
||||||
{
|
{
|
||||||
|
bool RecursiveTree;
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned NumCriteria;
|
unsigned NumCriteria;
|
||||||
unsigned NumCriterion;
|
unsigned NumCriterion;
|
||||||
struct RubCri_Criterion CriterionChild;
|
struct RubCri_Criterion Criterion;
|
||||||
double ScoreChild;
|
double CriterionScore;
|
||||||
double Score;
|
|
||||||
|
|
||||||
switch (Criterion->Link.Type)
|
/***** Initialize rubric score *****/
|
||||||
|
*RubricScore = 0.0;
|
||||||
|
|
||||||
|
/***** Check that rubric is not yet in the stack *****/
|
||||||
|
RecursiveTree = Rub_FindRubCodInStack (*TOS,RubCod);
|
||||||
|
|
||||||
|
if (!RecursiveTree)
|
||||||
{
|
{
|
||||||
case Rsc_NONE:
|
/***** Push rubric code in stack *****/
|
||||||
Score = Prj_DB_GetScore (PrjCod,Criterion->CriCod);
|
Rub_PushRubCod (TOS,RubCod);
|
||||||
break;
|
|
||||||
case Rsc_RUBRIC:
|
|
||||||
Score = 0.0;
|
|
||||||
|
|
||||||
/***** Get data of rubric criteria from database *****/
|
/***** Get data of rubric criteria from database *****/
|
||||||
NumCriteria = Rub_DB_GetCriteria (&mysql_res,Criterion->Link.Cod);
|
NumCriteria = Rub_DB_GetCriteria (&mysql_res,RubCod);
|
||||||
for (NumCriterion = 0;
|
for (NumCriterion = 0;
|
||||||
NumCriterion < NumCriteria;
|
NumCriterion < NumCriteria;
|
||||||
NumCriterion++)
|
NumCriterion++)
|
||||||
{
|
{
|
||||||
/***** Get criterion data *****/
|
/***** Get criterion data *****/
|
||||||
RubCri_GetCriterionDataFromRow (mysql_res,&CriterionChild);
|
RubCri_GetCriterionDataFromRow (mysql_res,&Criterion);
|
||||||
|
|
||||||
|
/* Get/compute criterion score */
|
||||||
|
CriterionScore = 0.0;
|
||||||
|
switch (Criterion.Link.Type)
|
||||||
|
{
|
||||||
|
case Rsc_NONE:
|
||||||
|
CriterionScore = Prj_DB_GetScore (PrjCod,Criterion.CriCod);
|
||||||
|
break;
|
||||||
|
case Rsc_RUBRIC:
|
||||||
|
if (RubCri_ComputeRubricScore (PrjCod,TOS,Criterion.Link.Cod,
|
||||||
|
&CriterionScore))
|
||||||
|
RecursiveTree = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/***** Compute score of this criterion in the child rubric *****/
|
/***** Compute score of this criterion in the child rubric *****/
|
||||||
ScoreChild = RubCri_ComputeScore (PrjCod,&CriterionChild);
|
*RubricScore += Criterion.Weight * CriterionScore; // Update weighted sum
|
||||||
|
|
||||||
/***** Update weighted sum *****/
|
|
||||||
Score += CriterionChild.Weight * ScoreChild;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
break;
|
|
||||||
default:
|
/***** Pop rubric code from stack *****/
|
||||||
Score = 0.0;
|
Rub_PopRubCod (TOS);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Score;
|
return RecursiveTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********************** Push/pop rubric code in stack ************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Rub_PushRubCod (struct Node **TOS,long RubCod)
|
||||||
|
{
|
||||||
|
struct Node *Node;
|
||||||
|
|
||||||
|
/***** 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; // Link to previous top of stack
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rub_PopRubCod (struct Node **TOS)
|
||||||
|
{
|
||||||
|
struct Node *Node;
|
||||||
|
|
||||||
|
if (*TOS)
|
||||||
|
{
|
||||||
|
/***** Save current top of stack *****/
|
||||||
|
Node = (*TOS)->Prev;
|
||||||
|
|
||||||
|
/***** Free current top of stack node *****/
|
||||||
|
free (*TOS);
|
||||||
|
|
||||||
|
/***** Assign new top of stack *****/
|
||||||
|
*TOS = Node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************ Find rubric code in stack **************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
// Return true if found
|
||||||
|
|
||||||
|
bool Rub_FindRubCodInStack (const struct Node *TOS,long RubCod)
|
||||||
|
{
|
||||||
|
while (TOS)
|
||||||
|
{
|
||||||
|
if (TOS->RubCod == RubCod)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
TOS = TOS->Prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -47,6 +47,10 @@ void RubCri_ListCriteriaForEdition (struct Rub_Rubrics *Rubrics);
|
||||||
void RubCri_ListCriteriaInProject (struct Prj_Projects *Projects,long RubCod,
|
void RubCri_ListCriteriaInProject (struct Prj_Projects *Projects,long RubCod,
|
||||||
bool ICanFill);
|
bool ICanFill);
|
||||||
|
|
||||||
|
void Rub_PushRubCod (struct Node **TOS,long RubCod);
|
||||||
|
void Rub_PopRubCod (struct Node **TOS);
|
||||||
|
bool Rub_FindRubCodInStack (const struct Node *TOS,long RubCod);
|
||||||
|
|
||||||
double RubCri_GetParScore (void);
|
double RubCri_GetParScore (void);
|
||||||
|
|
||||||
void RubCri_GetCriterionDataFromRow (MYSQL_RES *mysql_res,
|
void RubCri_GetCriterionDataFromRow (MYSQL_RES *mysql_res,
|
||||||
|
|
Loading…
Reference in New Issue