maths / moodle-qtype_stack

Stack question type for Moodle
GNU General Public License v3.0
138 stars 147 forks source link

texput within a function doesn't apply to student answer validation #1133

Closed LukeLongworth closed 4 days ago

LukeLongworth commented 3 months ago

I feel like I've been posting a lot of niche issues the last few weeks!

I'm using STACK 4.4.6.

I'm working on updating vectorcalculus.mac in the contrib folder at the moment, and am wanting to include some functions that can override the tex display of differentials. To me, it feels silly that derivatives display as $ \frac{\mathrm{d}y}{\mathrm{d}x} $, but the native differential operator del(x) will display as $ d(x) $ rather than $ \mathrm{d}x $ or $ \mathrm{d}(x) $. Similarly, when students type in differentials using the obvious option dx, it would be nice if it would display as $ \mathrm{d}x $ rather than $ dx $.

These are easily fixed using texput, so I wrote this function: stack_strip_del():= texput(del, lambda([ex], sconcat("\\mathrm{d}",tex1(first(ex))))); with the hope that teachers who include this library can just include the line stack_strip_del(); in the question variables and all will be well. This works fine for anything printed in the question text, but doesn't seem to impact the validation of student answers, which still display as $ d(x) $. This problem is fixed if I simply include the line texput(del, lambda([ex], sconcat("\\mathrm{d}",tex1(first(ex))))); in the question variables absent of any function wrapping. Oddly, if I put the above line into a block (or just inside a set of parentheses) then the problem reappears.

When exploring this issue I discovered that running stack_reset_vars(true); also does not reach the student validation. If I run that line of code and include {@listofvars([e,pi,i])@} in my question text, it correctly states that the list of variables is [e, pi, i], but then if I put simplify(e^(pi*i)) into the answer box, it tells me that my answer is -1, and does not recognise that my answer has any variables in it. I assume that the insertion of e = %e might happen entirely separately from stack_reset_vars but these issues felt similar enough that I thought I would mention it.

Is there something about appropriate use of texput that I am misunderstanding?

aharjula commented 3 months ago

This is a place where certain design decisions come to bite us. Basically, originally the validation-context contained absolutely nothing from the question-variables, primarily to ensure that the student cannot be exposed to any of the variables relevant to the grading like ta.... Then we wanted to tune the context a bit and allow texput rules, but we still wanted to not include everything else so those (and some other things) were simply plucked out of the question-variables with a simple rule that picked only those statements that are pure texput-calls, that works about as well as one can expect as it means that you need to define any functionality inside the statement and cannot share it over multiple such things as all things outside that particular picket part are left behind.

There are some ideas for better author side control of what exactly gets lifted to the validation-context and maybe it would be worth discussing it in this Zulip thread.

aharjula commented 3 months ago

Basically, currently texput only works when present in question-variables without any logical or other wrapping and is self contained with no references to other parts of the question-variables so selectively activating those rules with a function-call is not possible.

Also in some sense we might not want it to be possible, as we want to keep the validation-context small and thus would wish that only things that are to be used get loaded into it and that we would not end up with a massive common preamble that everyone loads to every place.

sangwinc commented 2 months ago

@LukeLongworth I think you can get a lot done with lambda functions within texput. That's the only option for now I'm afraid!

There are examples in the docs here: https://docs.stack-assessment.org/en/Authoring/Variables/#context-variables

sangwinc commented 2 months ago

Your example texput(del, lambda([ex], sconcat("\\mathrm{d}",tex1(first(ex))))); does work in the validation feedback on my system and I've fixed the reset vars. I hope this was everything?

aharjula commented 2 months ago

Chris, I think you are missing the point here. It is not interesting whether this works as it has worked for a long time:

texput(del, lambda([ex], sconcat("\\mathrm{d}",tex1(first(ex)))));

What people might want is for this to work:

if something then texput(del, lambda([ex], sconcat("\\mathrm{d}",tex1(first(ex)))));

Or some function-based logic for running those texputs, or even not having to play with a lamda within that single statement, i.e., people might want this to work as well:

foo: lambda([ex], sconcat("\\mathrm{d}",tex1(first(ex))));
texput(del, foo);

The solution I mentioned in the Zulip thread was that authors should somehow be able to pick the parts of the question variables that will be included in validation (preamble/context) instead of the current plucking of these that just happen to follow some pattern.

The current non-context-aware picking of those parts from the variables just does not work when one wants to do complicated things like those changes to e in that Zulip thread. What we really need is a way to somehow selectively lift author-chosen things from the variables. And while previously I though it might require some specially named functions I have thought this through and actually think that we could simply have a specific comment:

... here be texput rules and declares ....
... maybe some random parameters relevant to those rules ...
/* STACK preamble ends */
... here we do maths to calculate the values we don't want to leak to the student

Basically, if we see that comment there then we consider everything before that as "preamble". For backwards compatibility we also include the old specially picked ones in it.

sangwinc commented 1 week ago

Email discussions have re-visited the idea of a "preamble" in the question variables, as code which is always executed (question variables, inputs, prts).

sangwinc commented 1 week ago

This functionality should merge/replace the fix to issue #1207.