maths / moodle-qtype_stack

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

Space around "E" in float number input #1172

Open sangwinc opened 2 months ago

sangwinc commented 2 months ago

From a user:

"One minor issue I've been meaning to contact you about is in regard to scientific notation using E. If a student inadvertently inserts a space on either side of E, for example 5.25 E8 instead of 5.25E8, the value is not correctly read and creates an error in the PRT. (We generally use the setting "Insert stars for implied multiplication and for spaces".) It would be helpful if the parser would ignore spaces on either side of E and allow this input, or provide a specific error message for this situation."

aharjula commented 2 months ago

Well, this is not even that hard. I would not change the parser one bit. Instead, there would be an AST filter that would note (i.e. add errors and invalidate the relevant part of the input) certain patterns and that filter could be added into the filter chain for inputs allowing floats.

Basically, there are a few patterns:

1.1 E11 -> NUMBER(float/integer) *(from fix spaces) IDENTIFIER(starting with E followed with an integer)
1.1 E-11 -> NUMBER(float/integer) *(from fix spaces) IDENTIFIER(E) +/- INTEGER
1.1E 11 -> NUMBER(float/integer) *(from insert stars) IDENTIFIER(E) STAR(from fix spaces) INTEGER
1.1E -11 -> NUMBER(float/integer) *(from insert stars) IDENTIFIER(E) +/- INTEGER
1.1 E 11 ->  NUMBER(float/integer) *(from fix spaces) IDENTIFIER(E) *(from fix spaces) INTEGER
1.1 E -11 ->  NUMBER(float/integer) *(from fix spaces) IDENTIFIER(E) +/- INTEGER   // This is equal to the second case.

The tricky bit is to identify those subtrees when operator precedence may bind some of the relevant terms to something adjacent. For simple number inputs, though, simply dealing with prefix operators should be enough.

christianp commented 2 months ago

Are digits valid at the end of variable names? How would you cope with a1E2, with any combination of spaces between those characters?

aharjula commented 2 months ago

Depending on the insert starts rules, digits may be present in variable names. The obvious example is "assume single char variable names", which would lead to the following due to the forced insertion of that "star":

a1E2 -> identifier(a) *(insert stars) float(1E2)

Other than that, a1E2 in full form is a valid identifier, although by default, it is forbidden due to length. Only spaces in front of numbers would matter here and in our system all those would be fixed by our "insert stars"-logic.

a 1foo2 -> identifier(a) *(fix spaces) integer(1) *(insert stars) identifier (foo2)