Formula question type (No Stack)

Formula question type (No Stack)

by Miguel Bejarano -
Number of replies: 6

Hi

In a question, in random  variable section I have:

a = {1:10};      b = {1:10};      c = {1:10};      d = {1:10};

OpSign1 = {0:4};     OpSign2 = {0:4};       OpSign3 = {0:4};      OpSign4 = {0:4};     

In variable section: 

Signos = [ " + " , " - " , " * " , " / " ];
Signo1 = Signos[OpSigno1];
Signo2 = Signos[OpSigno2];
Signo3 = Signos[OpSigno3];
Signo4 = Signos[OpSigno4];
Answer = join("", a, Signo1, b, Signo2, c, Signo3, d, Signo4, e) ;


Now. I need a way to have  a numeric answer like    NumericAnswer = value(Answer);

Do you know any way?  Thanks

Average of ratings: -
In reply to Miguel Bejarano

Re: Formula question type (No Stack)

by Dominique Bauer -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers
Hello Miguel,

Perhaps the PHP eval() function could do what you want. However, this function is not available in the Formulas question. Also, it is evaluating PHP code, so there are security caveats about it. You could parse your strings but it is not easy and maybe not even possible with the functions available in the Formulas question. I'm not saying it's impossible, but rather I suggest a simple solution for your specific problem.

Since you only have four operators, there are 24 possible permutations if the four operators are different, which I think is already a good question. So it is quite simple, if a little boring, to define each of the 24 permutations in the variables of the question.

You will find an example at https://moodleformulas.org/course/view.php?id=78&section=61 ↗.


Average of ratings: Useful (1)
In reply to Dominique Bauer

Re: Formula question type (No Stack)

by Miguel Bejarano -

Hi, Dominique.

Positive:  I learned (always) with your ideas and solutions. I never had used fill function and neither shuflle with ranges. Elegant solutions; thanks.


Negative: Sorry; it doesn't solve my specific problem because the problem is not about permutations. For each sign you can get 4 options; so, you have   4 options in firs place, for options in second place ...

The posibilities are  44   

In reply to Miguel Bejarano

Re: Formula question type (No Stack)

by Dominique Bauer -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

Hello Miguel,

If you allow the operators to be repeated, i.e. the operators are not necessarily all different, the number of possible permutations is indeed 44 = 256. With this relatively high number of permutations, it is not efficient to write an expression for each one. In this case, you can parse the expression, which is easy to do (with just 10 lines of code).

See https://moodleformulas.org/course/view.php?id=78&section=61 ↗.


In reply to Dominique Bauer

Re: Formula question type (No Stack)

by Miguel Bejarano -

" ¡ Qué padre ! ", We say in México.  It traslated doesn't have logic:  "What father"; but that means: "I like it", "Beautifull", etc.

Thanks


In reply to Miguel Bejarano

Re: Formula question type (No Stack)

by Miguel Bejarano -
An this is poly2(). It works like poly() but with fractions.







# ----------------- Variables de entrada ---------------------
Variable = "x";
CadenaIniNum = [ -1 , -1 , -4 , 2 , 0 ];
CadenaIniDen = [ 1 , 2 , -2 , 0 , 2 ];
# ----------------- Procedimiento ---------------------

Signos = [ "+" , "-" , ""];
Cadena = "";
CantTerm = len(CadenaIniNum);

# ----- Detecta primer término diferente de 0 -------

PrimerTerm = 0;
for ( i : [0 : 5])
PrimerTerm = (PrimerTerm == 0 && CadenaIniNum[i] 0)? i : PrimerTerm;

for ( i : [ 0 : 5] ) {

# ------------------ Coeficiente ----------------------
iNum = CadenaIniNum[i];
iDen = (CadenaIniDen[i] == 0)? 1 : CadenaIniDen[i];
iNumAbs = abs(iNum);
iDenAbs = abs(iDen);
MCD = gcd( iNumAbs , iDenAbs);
iNumAbs = iNumAbs / MCD;
iDenAbs = iDenAbs / MCD;
iCadCoefPos = [ "", join("" , iNumAbs) , join("" , "\\frac{", iNumAbs, "}{", iDenAbs, "}") ];
Pos = (iNumAbs == 0)? 0 : ( ( iNumAbs == iDenAbs )? 0: ((iDenAbs == 1)? 1 : 2) );
iCadCoef = iCadCoefPos[Pos];

# ------------------- Signo -------------------------

iSignoPos = (( i = 0) || iNum == 0 )? 2: (( (iNum > 0 && iDen > 0) || (iNum < 0 && iDen < 0) )? 0 : 1);
iSigno = Signos[iSignoPos];

# ------------------ Expresión --------------------------

iExp = CantTerm - i - 1;
iExpresPos = [ "" , Variable, join("", Variable, "^", iExp) ];
Pos = (iNum == 0 || iExp == 0)? 0 : (( iExp == 1)? 1 : 2 ) ;
iExpres = iExpresPos[Pos];
Cadena = join(" ", Cadena, iSigno, iCadCoef , iExpres);
}
In reply to Dominique Bauer

Re: Formula question type (No Stack)

by Miguel Bejarano -

Hi Dominique. This is a new subject but I  think you are the correct person. hope this can result interesting.

I usually concatenate strings to create polynoms. Example:

Answer = join("", a, "/", b, " x^3 + ", c, "/", d, " x^2 + ", e , "/" , f, " x", g , "/", h) ;

So ... frecuently the students see an answer like:

"a possible answer is 0/3 x^3 + 4/4 x^2 + -2/5 x + -1/-8"

I supposse you have the same problem.


Well, I created a code  to generate nice string.    similar to function: poly.         

There are some differences between mine and poly: 

    a) Mine doesn't  generate  HTML style, so it is no very useful to use it in Main Question

    b) Mine considers fractions   

    c) Mine is limited to 5 terms because I didn't know how put     for ( i : [0 :  CantTerm])


I am contacting you because maybe you know a way to create a function to call it, just like function poly().

By the way, I made the code thanks to the last example you sent. It was not only useful to solve my problem, but to teach me how to use the for statement.

I add the code; maybe you want it; maybe someone else does.


---------------------------------------------------------------------------------------------------------------------------



# -----------------   Variables de entrada  ---------------------

Variable = "x";

CadenaIniNum = [ 0 , 1 , 0 , 2 , 4 ];

CadenaIniDen = [ 1 , 1 , -2 , 2 , 2 ];

# -----------------   Procedimiento  ---------------------


Signos = [ "+" , "-" , ""];

Cadena = "";

CantTerm = len(CadenaIniNum);


               #  ----- Detecta primer término diferente de 0 -------


PrimerTerm = 0;

for ( i : [0 : 5]) 

   PrimerTerm = (PrimerTerm == 0 && CadenaIniNum[i] <> 0)? i : PrimerTerm;


for ( i : [ 0 : 5] ) {


                   #  ------------------ Coeficiente ----------------------

      iNum = CadenaIniNum[i]; 

      iDen = (CadenaIniDen[i] == 0)? 1 : CadenaIniDen[i];

      iNumAbs = abs(iNum);

      iDenAbs = abs(iDen);

      MCD = gcd( iNumAbs , iDenAbs);

      iNumAbs = iNumAbs / MCD;

      iDenAbs = iDenAbs / MCD;

      iCadCoefPos = [ "", join("" , iNumAbs) , join("" , iNumAbs, "/", iDenAbs) ];

      Pos = (iNumAbs == 0)? 0 : ( ( iNumAbs == iDenAbs )? 0: ((iDenAbs == 1)? 1 : 2) );

      iCadCoef = iCadCoefPos[Pos];


                    #  ------------------- Signo -------------------------


      iSignoPos = (( i <= PrimerTerm && iNum >= 0) || iNum == 0 )? 2: (( (iNum > 0 && iDen > 0) || (iNum < 0 && iDen < 0) )? 0 : 1);

      iSigno = Signos[iSignoPos];


                    #  ------------------ Expresión  --------------------------


      iExp = CantTerm - i - 1;

      iExpresPos = [ "" , Variable, join("", Variable, "^", iExp) ];

      Pos = (iNum == 0 || iExp == 0)? 0 : (( iExp == 1)? 1 : 2 ) ;

      iExpres = iExpresPos[Pos];

      Cadena = join(" ", Cadena, iSigno, iCadCoef , iExpres);

}

Respuesta = Cadena;