Skip to content
Snippets Groups Projects
Commit d2db440e authored by Chris Sangwin's avatar Chris Sangwin
Browse files

Merge branch 'master' into proof_opt

parents 874bcb67 f39c8c57
No related branches found
No related tags found
No related merge requests found
...@@ -66,7 +66,7 @@ By default points are free to manipulate in the applet, unless you add `__fixed` ...@@ -66,7 +66,7 @@ By default points are free to manipulate in the applet, unless you add `__fixed`
Notes Notes
1. No checking is done that the object in STACK matches one in GeoGebra. If it does not exist it will be created by GeoGebra. 1. No checking is done that the object in STACK matches one in GeoGebra. If it does not exist it will be created by GeoGebra.
2. Currently setting points and values are the only supported objects. Users can set objects, e.g. you could define `g:x^3` and set this in an appletm 2. Currently setting points and values are the only supported objects. Users can set objects, e.g. you could define `g:x^3` and set this in an applet.
3. Angles cannot be set directly, set points instead! 3. Angles cannot be set directly, set points instead!
...@@ -126,7 +126,7 @@ Recall that since the object in `watch="A"` is written in upper case it must be ...@@ -126,7 +126,7 @@ Recall that since the object in `watch="A"` is written in upper case it must be
Then complete the question as follows. Then complete the question as follows.
1. The question expects an in input `A`. In this input, make the model answer `ta1`. This is a list, and has a different name from the watched point.. 1. The question expects an input `A`. In this input, make the model answer `ta1`. This is a list, and has a different name from the watched point..
2. Make sure you set "forbid floats" option in the input to be false, if you want to! 2. Make sure you set "forbid floats" option in the input to be false, if you want to!
3. Complete the default potential response tree `prt1` as `ATAlgEquiv(ntupleify(A), ntupleify(ta1))` 3. Complete the default potential response tree `prt1` as `ATAlgEquiv(ntupleify(A), ntupleify(ta1))`
......
...@@ -50,7 +50,7 @@ In this way, the teacher can record, within the question itself, how they expect ...@@ -50,7 +50,7 @@ In this way, the teacher can record, within the question itself, how they expect
On the question testing page is a "Send to CAS" button. Pressing this sends the question variables and general feedback to a special page which enables more efficient authoring of the feedback in the context of the values of the variables. You still need to copy this by hand into the question edit form when you are satisfied. On the question testing page is a "Send to CAS" button. Pressing this sends the question variables and general feedback to a special page which enables more efficient authoring of the feedback in the context of the values of the variables. You still need to copy this by hand into the question edit form when you are satisfied.
A Moodle administrator can run all of the questions tests within a particular course, or across the whole site by following the links on the STACK admin page. It is useful do to this after upgrading the STACK code on the server to identify any test cases which have changed. A Moodle administrator can run all of the questions tests within a particular course, or across the whole site by following the links on the STACK admin page. It is useful to do this after upgrading the STACK code on the server to identify any test cases which have changed.
Test cases can include a meaningful description of up to 255 characters. This field is a simple string, and is not castext. Test cases can include a meaningful description of up to 255 characters. This field is a simple string, and is not castext.
......
...@@ -98,7 +98,7 @@ Note, STACK only displays matrices with matching parentheses. If you want somet ...@@ -98,7 +98,7 @@ Note, STACK only displays matrices with matching parentheses. If you want somet
\[ f(x) = \left\{ \begin{array}{cc} 1, & x<0 \\ 0, & x\geq 0 \end{array}\right.\] \[ f(x) = \left\{ \begin{array}{cc} 1, & x<0 \\ 0, & x\geq 0 \end{array}\right.\]
then you will have to display the matrix without parentheses and sort out the mismatching parentheses in the CASText at the level of display. then you will have to display the matrix without parentheses and sort out the mismatching parentheses in the CASText at the level of display.
For example, if we have the question variable `f:matrix([4*x+4, x<1],[-x^2-4*x-8, x>=1];` and the castext `\[ f(x) := \left\{ {@(lmxchar:"", f)@} \right. \]` the STACK generates For example, if we have the question variable `f:matrix([4*x+4, x<1],[-x^2-4*x-8, x>=1];` and the castext `\[ f(x) := \left\{ {@(lmxchar:"", f)@} \right. \]` STACK generates
\[ f(x) := \left\{ {\begin{array}{cc} 4\cdot x+4 & x < 1 \\ -x^2-4\cdot x-8 & x\geq 1 \end{array}} \right. \] \[ f(x) := \left\{ {\begin{array}{cc} 4\cdot x+4 & x < 1 \\ -x^2-4\cdot x-8 & x\geq 1 \end{array}} \right. \]
Notice the use of LaTeX `\left\{` to automatically size the parentheses and `\right.` to represent a matching, but invisible closing parentesis. Notice the use of LaTeX `\left\{` to automatically size the parentheses and `\right.` to represent a matching, but invisible closing parentesis.
......
...@@ -18,7 +18,7 @@ If you want to track the development of STACK or report bugs then you should vis ...@@ -18,7 +18,7 @@ If you want to track the development of STACK or report bugs then you should vis
Work towards the next release of STACK is detailed on [Development track](Development_track.md). Work towards the next release of STACK is detailed on [Development track](Development_track.md).
Plans looking futher into the future are described on [Future plans](Future_plans.md). Plans looking further into the future are described on [Future plans](Future_plans.md).
The past development history is documented on [Development history](Development_history.md). The past development history is documented on [Development history](Development_history.md).
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Stateful. If not, see <http://www.gnu.org/licenses/>. // along with Stateful. If not, see <http://www.gnu.org/licenses/>.
namespace qtype_stack;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
// Unit tests to check that the requirements of a related software // Unit tests to check that the requirements of a related software
...@@ -49,7 +51,7 @@ require_once(__DIR__ . '/../stack/cas/evaluatable_object.interfaces.php'); ...@@ -49,7 +51,7 @@ require_once(__DIR__ . '/../stack/cas/evaluatable_object.interfaces.php');
* @group qtype_stateful * @group qtype_stateful
* @group qtype_stack_compatibility * @group qtype_stack_compatibility
*/ */
class api_tests_stateful_test extends qtype_stack_testcase { class api_tests_stateful_test extends \qtype_stack_testcase {
public function test_security_map_path() { public function test_security_map_path() {
$this->assertTrue(file_exists(__DIR__ . '/../stack/cas/security-map.json')); $this->assertTrue(file_exists(__DIR__ . '/../stack/cas/security-map.json'));
...@@ -93,20 +95,20 @@ class api_tests_stateful_test extends qtype_stack_testcase { ...@@ -93,20 +95,20 @@ class api_tests_stateful_test extends qtype_stack_testcase {
$this->assertTrue(method_exists('stack_utils', 'eliminate_strings')); $this->assertTrue(method_exists('stack_utils', 'eliminate_strings'));
$this->assertTrue(method_exists('stack_utils', 'list_to_array')); $this->assertTrue(method_exists('stack_utils', 'list_to_array'));
$this->assertTrue(isset(stack_utils::get_config()->stackmaximaversion)); $this->assertTrue(isset(\stack_utils::get_config()->stackmaximaversion));
$this->assertEquals('"\"foo"', stack_utils::php_string_to_maxima_string('"foo')); $this->assertEquals('"\"foo"', \stack_utils::php_string_to_maxima_string('"foo'));
$this->assertEquals('"foo', stack_utils::maxima_string_to_php_string('"\"foo"')); $this->assertEquals('"foo', \stack_utils::maxima_string_to_php_string('"\"foo"'));
$this->assertEquals('["","",1+""]', stack_utils::eliminate_strings('["foo","bar",1+"baz"]')); $this->assertEquals('["","",1+""]', \stack_utils::eliminate_strings('["foo","bar",1+"baz"]'));
$this->assertEquals(["foo", "bar", "baz"], stack_utils::all_substring_strings('["foo","bar",1+"baz"]')); $this->assertEquals(["foo", "bar", "baz"], \stack_utils::all_substring_strings('["foo","bar",1+"baz"]'));
} }
public function test_maxima_parser_utils() { public function test_maxima_parser_utils() {
$this->assertTrue(method_exists('maxima_parser_utils', 'parse')); $this->assertTrue(method_exists('maxima_parser_utils', 'parse'));
$this->assertTrue(method_exists('maxima_parser_utils', 'variable_usage_finder')); $this->assertTrue(method_exists('maxima_parser_utils', 'variable_usage_finder'));
$ast = maxima_parser_utils::parse('x:y+sqrt(y)'); $ast = \maxima_parser_utils::parse('x:y+sqrt(y)');
$update = ['read' => ['z' => true]]; $update = ['read' => ['z' => true]];
$usage = maxima_parser_utils::variable_usage_finder($ast, $update); $usage = \maxima_parser_utils::variable_usage_finder($ast, $update);
$this->assertEquals(['z' => true, 'y' => true], $usage['read']); $this->assertEquals(['z' => true, 'y' => true], $usage['read']);
$this->assertEquals(['x' => true], $usage['write']); $this->assertEquals(['x' => true], $usage['write']);
$this->assertEquals(['sqrt' => true], $usage['calls']); $this->assertEquals(['sqrt' => true], $usage['calls']);
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace qtype_stack;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
global $CFG; global $CFG;
...@@ -29,22 +31,22 @@ require_once(__DIR__ . '/../edit_stack_form.php'); ...@@ -29,22 +31,22 @@ require_once(__DIR__ . '/../edit_stack_form.php');
* @group qtype_stack * @group qtype_stack
* @covers \qtype_stack_edit_form * @covers \qtype_stack_edit_form
*/ */
class editform_test extends qtype_stack_edit_form { class editform_test extends \qtype_stack_edit_form {
public function __construct($questiontext, $specificfeedback) { public function __construct($questiontext, $specificfeedback) {
global $USER; global $USER;
$syscontext = context_system::instance(); $syscontext = \context_system::instance();
$category = question_make_default_categories(array($syscontext)); $category = question_make_default_categories(array($syscontext));
$fakequestion = new stdClass(); $fakequestion = new \stdClass();
$fakequestion->qtype = 'stack'; $fakequestion->qtype = 'stack';
$fakequestion->category = $category->id; $fakequestion->category = $category->id;
$fakequestion->contextid = $syscontext->id; $fakequestion->contextid = $syscontext->id;
$fakequestion->createdby = $USER->id; $fakequestion->createdby = $USER->id;
$fakequestion->modifiedby = $USER->id; $fakequestion->modifiedby = $USER->id;
$fakequestion->questiontext = $questiontext; $fakequestion->questiontext = $questiontext;
$fakequestion->options = new stdClass(); $fakequestion->options = new \stdClass();
$fakequestion->options->specificfeedback = $specificfeedback; $fakequestion->options->specificfeedback = $specificfeedback;
$fakequestion->formoptions = new stdClass(); $fakequestion->formoptions = new \stdClass();
$fakequestion->formoptions->movecontext = null; $fakequestion->formoptions->movecontext = null;
$fakequestion->formoptions->repeatelements = true; $fakequestion->formoptions->repeatelements = true;
$fakequestion->inputs = null; $fakequestion->inputs = null;
...@@ -52,9 +54,9 @@ class editform_test extends qtype_stack_edit_form { ...@@ -52,9 +54,9 @@ class editform_test extends qtype_stack_edit_form {
if (class_exists('\core_question\local\bank\question_edit_contexts')) { if (class_exists('\core_question\local\bank\question_edit_contexts')) {
$contexts = new \core_question\local\bank\question_edit_contexts($syscontext); $contexts = new \core_question\local\bank\question_edit_contexts($syscontext);
} else { } else {
$contexts = new question_edit_contexts($syscontext); $contexts = new \question_edit_contexts($syscontext);
} }
parent::__construct(new moodle_url('/'), $fakequestion, $category, $contexts); parent::__construct(new \moodle_url('/'), $fakequestion, $category, $contexts);
} }
} }
...@@ -67,31 +69,31 @@ class editform_test extends qtype_stack_edit_form { ...@@ -67,31 +69,31 @@ class editform_test extends qtype_stack_edit_form {
* @group qtype_stack * @group qtype_stack
* @covers \qtype_stack_edit_form * @covers \qtype_stack_edit_form
*/ */
class qtype_stack_edit_form_test extends advanced_testcase { class qtype_stack_edit_form_test extends \advanced_testcase {
protected function get_form($questiontext, $specificfeedback) { protected function get_form($questiontext, $specificfeedback) {
$this->setAdminUser(); $this->setAdminUser();
$this->resetAfterTest(); $this->resetAfterTest();
return new qtype_stack_edit_form_testable($questiontext, $specificfeedback); return new \qtype_stack_edit_form_testable($questiontext, $specificfeedback);
} }
public function test_get_input_names_from_question_text_default() { public function test_get_input_names_from_question_text_default() {
$form = $this->get_form(qtype_stack_edit_form::DEFAULT_QUESTION_TEXT, $form = $this->get_form(\qtype_stack_edit_form::DEFAULT_QUESTION_TEXT,
qtype_stack_edit_form::DEFAULT_SPECIFIC_FEEDBACK); \qtype_stack_edit_form::DEFAULT_SPECIFIC_FEEDBACK);
$qtype = new qtype_stack(); $qtype = new \qtype_stack();
$this->assertEquals(array('ans1' => array(1, 1)), $this->assertEquals(array('ans1' => array(1, 1)),
$qtype->get_input_names_from_question_text(qtype_stack_edit_form::DEFAULT_QUESTION_TEXT)); $qtype->get_input_names_from_question_text(\qtype_stack_edit_form::DEFAULT_QUESTION_TEXT));
} }
public function test_get_prt_names_from_question_default() { public function test_get_prt_names_from_question_default() {
$form = $this->get_form(qtype_stack_edit_form::DEFAULT_QUESTION_TEXT, $form = $this->get_form(\qtype_stack_edit_form::DEFAULT_QUESTION_TEXT,
qtype_stack_edit_form::DEFAULT_SPECIFIC_FEEDBACK); \qtype_stack_edit_form::DEFAULT_SPECIFIC_FEEDBACK);
$qtype = new qtype_stack(); $qtype = new \qtype_stack();
$this->assertEquals(array('prt1' => 1), $this->assertEquals(array('prt1' => 1),
$qtype->get_prt_names_from_question(qtype_stack_edit_form::DEFAULT_QUESTION_TEXT, $qtype->get_prt_names_from_question(\qtype_stack_edit_form::DEFAULT_QUESTION_TEXT,
qtype_stack_edit_form::DEFAULT_SPECIFIC_FEEDBACK)); \qtype_stack_edit_form::DEFAULT_SPECIFIC_FEEDBACK));
} }
} }
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Stack. If not, see <http://www.gnu.org/licenses/>. // along with Stack. If not, see <http://www.gnu.org/licenses/>.
namespace qtype_stack;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
global $CFG; global $CFG;
...@@ -26,7 +28,7 @@ require_once($CFG->dirroot . '/question/type/stack/backup/moodle2/restore_qtype_ ...@@ -26,7 +28,7 @@ require_once($CFG->dirroot . '/question/type/stack/backup/moodle2/restore_qtype_
* @copyright 2017 The Open University * @copyright 2017 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class restore_logic_test extends restore_qtype_stack_plugin { class restore_logic_test extends \restore_qtype_stack_plugin {
private $log = ''; private $log = '';
public function __construct() { public function __construct() {
...@@ -75,7 +77,7 @@ class restore_logic_test extends restore_qtype_stack_plugin { ...@@ -75,7 +77,7 @@ class restore_logic_test extends restore_qtype_stack_plugin {
* @group qtype_stack * @group qtype_stack
* @covers \qtype_stack * @covers \qtype_stack
*/ */
class qtype_stack_restore_logic_testcase extends advanced_testcase { class qtype_stack_restore_logic_testcase extends \advanced_testcase {
public function test_fix_prt_roots() { public function test_fix_prt_roots() {
global $DB; global $DB;
...@@ -93,7 +95,7 @@ class qtype_stack_restore_logic_testcase extends advanced_testcase { ...@@ -93,7 +95,7 @@ class qtype_stack_restore_logic_testcase extends advanced_testcase {
$DB->set_field('qtype_stack_prt_nodes', 'truenextnode', 7, $DB->set_field('qtype_stack_prt_nodes', 'truenextnode', 7,
array('questionid' => $question->id, 'prtname' => 'oddeven', 'nodename' => 0)); array('questionid' => $question->id, 'prtname' => 'oddeven', 'nodename' => 0));
$restoreplugin = new testable_restore_qtype_stack_plugin(); $restoreplugin = new \testable_restore_qtype_stack_plugin();
$restoreplugin->after_execute_question(); $restoreplugin->after_execute_question();
$this->assertStringContainsString('The PRT named "oddeven" is malformed', $restoreplugin->get_log()); $this->assertStringContainsString('The PRT named "oddeven" is malformed', $restoreplugin->get_log());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment