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 andtans
is nonzero, then the relative deviation is shown (for use in the true branch of the PRT)
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äßig zu groß."),
/* check of the sign */
if %_snum/%_tnum <0 then return(" Prü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ößenordnung ab. Prü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ß."))
),
[%_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)