fb_number - mkraska/meclib GitHub Wiki

Feedback function for numeric input.

This function performs the following checks with numbers (see fb_unit and fb_vars for other tests):

  • If teacher's answer is zero and student's answer is not, a complaint is issued (absolute value too large). If student's answer is also zero, then zero absolute deviation is indicated.
  • If only student's answer is zero, no comment is made, because the % deviation value would be meaningless.
  • Is the value off by exactly an integer power of 10? This indicates correct mantissa and problems with unit conversion. Mantissa Check
  • is the sign correct? Check of Sign
  • % deviation with one significant digit (e.g. at least 0.01 or 0.3 or 30 deviation)

fb_number(sans, tans, tol) returns the text to be displayed as feedback

fb_numberOK(sans, tans, tol) returns the test result (true or false).

  • sans student's answer,
  • tans teacher's answer,
  • tol relative tolerance for the mantissa. If it is zero and tans is nonzero, then the relative deviation is shown (for use in the true branch of the PRT)

image

Question variables

stack_include("https://raw.githubusercontent.com/mkraska/meclib/main/Maxima/fb_value.mac");

PRT

Put this to the feedback text of the false branch of the first node.

{@fb_number(sans, tans, tol)@}

In the true branch of the first node, use this to suppress the tests and just display the deviation:

{@fb_number(sans, tans, 0)@}

You can use the function for Matrix Feedback to the individual components. Provide labels to specify to which component the feedback applies.

<br>\(x\): {@fb_number(S_A[1,1], A[1,1], 0.005)@}
<br>\(y\): {@fb_number(S_A[2,1], A[2,1], 0.005)@}
<br>\(z\): {@fb_number(S_A[3,1], A[3,1], 0.005)@}

Question variables (Legacy STACK 4.3)

fb_number(%_snum, %_tnum, %_tol) := block([%_oom, %_mnt, %_d],
  /* if tol=0 just indicate deviation */
  if %_tol=0 and %_tnum # 0 then return(sconcat(" Abweichung: ", float( round((%_snum-%_tnum)/abs(%_tnum)*1000)/10) , "%")),
  /* special feedback if teacher's answer is zero */
  if %_tnum+1.0=1.0  then 
     if %_snum+1.0=1.0 then return("Abweichung: 0") 
     else return(" Der Wert ist betragsm&auml;&szlig;ig zu gro&szlig;."),
  /* check of the sign */
  if %_snum/%_tnum <0 then return(" Pr&uuml;fen Sie das Vorzeichen."),
  /* go back if error is less than tolerance */
  if abs((%_snum-%_tnum)/%_tnum) < %_tol then return(sconcat(" Abweichung: ", float( round((%_snum-%_tnum)/abs(%_tnum)*1000)/10) , "%")), 
  /* OoM and mantissa error */
  %_oom: log(abs(%_snum/%_tnum))/log(10),
  %_mnt: 10^( %_oom - round(%_oom)),
  /* Mantissa check */
  if abs(1-%_mnt) <%_tol and abs(%_oom)>0.1 then 
    return(" Die Mantisse stimmt, die Zehnerpotenz weicht aber um mindestens eine Gr&ouml;&szlig;enordnung ab. Pr&uuml;fen Sie Ihre Einheitenumrechnung. ") 
  /* general hint on precision */
  else(
    %_d: float(abs((1-abs(%_snum)/abs(%_tnum)))*100),  /* % Abweichung */
    %_oom:10^round(log(%_d)/log(10.)-0.5),
    %_d: float(round(floor(%_d/%_oom)))*%_oom,
    if %_d>=1 then %_d:round(%_d),
    if abs(%_snum)<abs(%_tnum) then        
        return(sconcat(" Der Betrag ist um mindestens ", %_d , "% zu klein.")) else
        return(sconcat(" Der Betrag ist um mindestens ", %_d , "% zu gro&szlig;."))       
  ), 
[%_snum,%_tnum] );

PRT

Put this to the feedback text of the false branch of the first node.

{@fb_number(sans, tans, tol)@}

In the true branch of the first answer test set the tolerance to zero, otherwise the feedback may be wrong.

{@fb_number(sans, tans, 0)@}

You could pre-calculate the value in the feedback variables, but that doesn not reliably avoid empty checks (with no feedback)