Skip to content

Commit

Permalink
Merge branch 'proof-builder' of https://github.com/maths/moodle-qtype…
Browse files Browse the repository at this point in the history
…_stack into proof-builder
  • Loading branch information
smmercuri committed Nov 7, 2023
2 parents b8ee5e5 + 41e2e54 commit 8a53c1f
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 48 deletions.
4 changes: 2 additions & 2 deletions corsscripts/stacksortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export const stack_sortable = class {
} else {
this.userOptions = Object.assign(this.defaultOptions, options);
};
// do not allow a user to replace ghostClass or group
// Do not allow a user to replace ghostClass or group.
this.options = Object.assign(this.userOptions, {ghostClass: "list-group-item-info", group: "shared"});
}

generate_available(proofSteps) {
for (const key in this.state.available) {
let li = document.createElement("li");
Expand Down
11 changes: 11 additions & 0 deletions doc/en/Authoring/Parsons.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ Additional display options including `height` and `width` may also be passed to
};
[[/parsons]]
````

## Adding plots to a Parson's block

TODO: confirm if we can embed HTML. If so, then the following should work.

Since HTML can be embedded into strings dragged within a Parson's block, images can be included with the HTML `<img>` tags as normal.

STACK-generated [plots](../Plots/index.md) cannot be included just using `{@plot(x^2,[x,-1,1])@}` as might be expected. This is because of the _order_ of evaluation. The full URL of the image is only created in the (complex) chain of events after the value has been substituted into the Javascript code. Instead, to embed STACK-generated images evaluate a static string using the Maxima `castext` function, and then use the value of `s1` in the Parson's block. For example.

s1:castext("{@plot(x^2,[x,-1,1],[size,250,250])@}");

7 changes: 4 additions & 3 deletions doc/en/Developer/Development_track.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ Create a working Parson's block
A. All functionality to be JSON strings (as in Sam's code)
B. Block to accept and produce Maxima proof expressions

1. How can we embed cas content into strings? E.g. `{@plot(x^2,[x,-2,2])@}`.
2. Allow teachers to define strings in the question variables, e.g. `{# stackjson_stringify(proof_steps) #}`

Parson's options

1. use once or re-use strings
Expand All @@ -52,6 +49,10 @@ Parson's options
4. create templates from the start for different proof types
5. restrict blocks to fixed number of steps

Future work.

1. Embed plots into strings draggable blocks: e.g. `"{@plot(x^2,[x,-1,1],[size,250,250])@}"`.
Note, this doesn't work, even defining a variable such as `s1:castext("{@plot(x^2,[x,-1,1],[size,250,250])@}");` and using this.

TODO:

Expand Down
52 changes: 17 additions & 35 deletions doc/en/Topics/Parsons.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ Notes

The following is a minimal Parson's question where there student is expected to create a list in one and only one order.

## Question variables

Define the following question variables:

````
stack_include("contribl://prooflib.mac");
ta:proof("assume","defn_rat","defn_rat2","defn_log","defn_log2","alg","alg_int","contra","conc");
````

The optional library `prooflib.mac` contain many useful functions for dealing with student's answers which represent proofs.

## Question text

The example question text below contains a Parson's block. Within the header of the Parson's block, ensure that `input="inputvar"` is included, where `inputvar` is the identifier of the input, for example `input="ans1"` as below. A minimal working example for the proof that _\(\log_2(3)\) is irrational_ is achieved by placing the following in the _Question text_ field:
Expand Down Expand Up @@ -72,15 +83,6 @@ Notes:

## Potential response tree: prt1

Define the following question variables:

````
stack_include("contribl://prooflib.mac");
ta:proof("assume","defn_rat","defn_rat2","defn_log","defn_log2","alg","alg_int","contra","conc");
````

The optional library `prooflib.mac` contain many useful functions for dealing with student's answers which represent proofs.

Define the feedback variables:

````
Expand All @@ -93,8 +95,6 @@ Then you can set up the potential response tree to be `ATAlgEquiv(sa,ta)` to con

# Parson's question with block order options

TODO! To get this following example to work we need to sort out `{# stackjson_stringify(proof_steps) #}` in the Parson's block.

The following Parson's question is an _if and only if_ proof, containing two blocks in order.

The input is unchanged from the above example. For the question variables use
Expand Down Expand Up @@ -135,29 +135,6 @@ The complete question text is
<p>[[input:ans1]] [[validation:ans1]]</p>
````

FOR NOW

````
<p>Let \(n\in\mathbb{N}\). Show that \(n\) is odd if and only if \(n^2\) is odd. </p>
[[parsons input="ans1"]]
{
"assodd": "Assume that \\(n\\) is odd.",
"defn_odd": "Then there exists an \\(m\\in\\mathbb{Z}\\) such that \\(n=2m+1\\).",
"alg_odd": "\\[ n^2 = (2m+1)^2 = 2(2m^2+2m)+1.\\]",
"def_M_odd": "Define \\(M=2m^2+2m\\in\\mathbb{Z}\\) then \\(n^2=2M+1\\).",
"conc_odd": "Hence \\(n^2\\) is odd.",
"contrapos": "We reformulate \"\\(n^2\\) is odd \\(\\Rightarrow \\) \\(n\\) is odd \" as the contrapositive.",
"assnotodd": "Assume that \\(n\\) is not odd.",
"even": "Then \\(n\\) is even, and so there exists an \\(m\\in\\mathbb{Z}\\) such that \\(n=2m\\).",
"alg_even": "\\[ n^2 = (2m)^2 = 2(2m^2).\\]",
"def_M_even": "Define \\(M=2m^2\\in\\mathbb{Z}\\) then \\(n^2=2M\\).",
"conc_even": "Hence \\(n^2\\) is even."
};
[[/parsons ]]
<p>[[input:ans1]] [[validation:ans1]]</p>
````

Notice the function `stackjson_stringify` turns the variable `proof_steps` into a JSON object.

Notice in this example the teacher's proof is nested. This can be seen if we use numerical keys, not string keys and define
Expand Down Expand Up @@ -188,4 +165,9 @@ Notice this proof has two sub-proofs, which can occur in any order. Therefore w
<td><div class="proof">{@ev(tad[2], map(lambda([ex], ex=dispproof_para), proof_types))@}</div></td>
</tr></table>
Can you see the differences between these proofs?
````
````

## Polish and tidy the question.

You should hide the inputs from students with CSS after testing, e.g. `<p style="display:none">...</p>`.

4 changes: 2 additions & 2 deletions stack/input/string/string.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public function get_teacher_answer_display($value, $display) {
return '';
}

$value = stack_utils::maxima_string_to_php_string($value);
return stack_string('teacheranswershow', array('value' => '<code>'.$value.'</code>', 'display' => $display));
$display = stack_utils::maxima_string_strip_mbox($display);
return stack_string('teacheranswershow_disp', array('display' => $display));
}

/**
Expand Down
17 changes: 17 additions & 0 deletions stack/utils.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ public static function php_string_to_maxima_string($string) {
$converted = str_replace("\"", "\\\"", $converted);
return '"' . $converted . '"';
}

/**
* Converts a PHP string object containing a Maxima string as presented by the grind command to a PHP string object.
* @param a string that contains ""-quotes around the content.
Expand All @@ -792,6 +793,22 @@ public static function maxima_string_to_php_string($string) {
return substr($converted, 1, -1);
}

/**
* Remove redundant "mbox" environments from Latex equations strings containing just strings.
* @param a string that contains ""-quotes around the content.
* @return a string without those quotes.
*/
public static function maxima_string_strip_mbox($string) {
$converted = trim($string);
if (substr($converted, 0, 2) == '\(' || substr($converted, 0, 2) == '\[') {
$converted = substr($converted, 2, -2);
}
if (substr(trim($converted), 0, 6) == '\mbox{') {
return substr(trim($converted), 6, -1);
}
return $string;
}

/**
* Translate some strings from Maxima.
* @param string $string
Expand Down
8 changes: 2 additions & 6 deletions tests/input_string_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ public function test_render_hello_world() {
.'style="width: 13.6em" autocapitalize="none" spellcheck="false" class="maxima-string" value="0" />',
$el->render(new stack_input_state(stack_input::VALID, array('0'), '', '', '', '', ''),
'stack1__ans1', false, null));
$this->assertEquals('The answer <span class="filter_mathjaxloader_equation"><span class="nolink">' .
'\( \\mbox{Hello world} \)</span></span>, which can be typed as <code>Hello world</code>, ' .
'would be correct.',
$this->assertEquals('The answer Hello world would be correct.',
$el->get_teacher_answer_display('"Hello world"', '\\mbox{Hello world}'));
}

Expand All @@ -72,9 +70,7 @@ public function test_validate_string_input() {
$this->assertEquals(stack_input::VALID, $state->status);
$this->assertEquals('"Hello world"', $state->contentsmodified);
$this->assertEquals('\[ \mbox{Hello world} \]', $state->contentsdisplayed);
$this->assertEquals('The answer <span class="filter_mathjaxloader_equation">' .
'<span class="nolink">\[ \[ \mbox{Hello world} \]</span></span> \), ' .
'which can be typed as <code>Hello world</code>, would be correct.',
$this->assertEquals('The answer Hello world would be correct.',
$el->get_teacher_answer_display($state->contentsmodified, $state->contentsdisplayed));
}

Expand Down

0 comments on commit 8a53c1f

Please sign in to comment.