Skip to content
Snippets Groups Projects
Commit bbfd080d authored by Tim Hunt's avatar Tim Hunt
Browse files

Fix adaptive scoring.

To match STACK 2.0, the second time you give the same wrong answer,
you are not penalised.
parent 645c477a
No related branches found
No related tags found
No related merge requests found
......@@ -86,7 +86,7 @@ List of bugs follows/TODOs (see also https://github.com/maths/moodle-qtype_stack
3. When validating the editing form, actually evaluate the Maxima code.
4. **DONE** When validating the editing form, ensure there are no @ and $ in the fields that expect Maxima code.
5. Ensure links from the editing form end up at the STACK docs. This is now work in progress, but relies on http://tracker.moodle.org/browse/MDL-34035 getting accepted into Moodle core. In which case we can use this commit: https://github.com/timhunt/moodle-qtype_stack/compare/helplinks.
6. It must be possible to create questions using the dropdown input type. Currently there is no way to input the choices.
6. Hide dropdown input type in the editing form untils there is a way to set the list of choices.
### Testing questions
......@@ -97,10 +97,10 @@ List of bugs follows/TODOs (see also https://github.com/maths/moodle-qtype_stack
5. **DONE** Dropdown input should make sure that only allowed values are submitted. (There is a TODO in the code for this.)
6. **DONE** Dropdown input element needs some unit tests. (There is a TODO in the code for this.)
7. We need to check for and handle CAS errors in get_prt_result and grade_parts_that_can_be_graded. (There is a TODO in the code for this.)
8. Un-comment the throw in the matrix input.
8. **DONE** Un-comment the throw in the matrix input.
9. Unit tests for adative mode score display - and to verify nothing like that appears for other behaviours.
10. Duplicate response detection for PRTs should consider all previous responses.
11. It appears as if the phrase "This submission attracted a penalty of ..." isn't working. It looks like this is the *old* penalty, not the *current*.
10. **DONE** Duplicate response detection for PRTs should consider all previous responses.
11. **DONE** It appears as if the phrase "This submission attracted a penalty of ..." isn't working. It looks like this is the *old* penalty, not the *current*.
### Optimising Maxima
......
......@@ -19,7 +19,7 @@ The following features are in approximate priority order. How to report bugs an
* Refactor answer tests.
1. They should be like inputs. We should return an answer test object, not a controller object.
2. at->get_at_mark() really ought to be at->matches(), since that is how it is used.
* It must be possible to create questions using the dropdown input type. Currently there is no way to input the choices.
## Features to add - round two! ##
......
......@@ -246,6 +246,9 @@ class qtype_stack_question extends question_graded_automatically_with_countback
// Now instantiate the session.
$session->instantiate();
if ($session->get_errors()) {
// We throw an exception here because any problems with the CAS code
// up to this point should have been caught during validation when
// the question was edited or deployed.
throw new stack_exception('qtype_stack_question : CAS error when instantiating the session: ' .
$session->get_errors($this->user_can_edit()));
}
......@@ -344,6 +347,13 @@ class qtype_stack_question extends question_graded_automatically_with_countback
return true;
}
public function is_same_response_for_part($index, array $prevresponse, array $newresponse) {
$previnput = $this->get_prt_input($index, $prevresponse, true);
$newinput = $this->get_prt_input($index, $newresponse, true);
return $this->is_same_prt_input($index, $previnput, $newinput);
}
/**
* Get the results of validating one of the input elements.
* @param string $name the name of one of the input elements.
......
......@@ -83,6 +83,15 @@ class qtype_stack_question_test extends qtype_stack_testcase {
$this->assertFalse($q->is_same_response(array('ans1' => '2'), array('ans1' => '3')));
}
public function test_get_is_same_response_for_part_test3() {
$q = $this->get_test_stack_question('test3');
$q->start_attempt(new question_attempt_step(), 1);
$this->assertTrue($q->is_same_response_for_part('oddeven', array('ans3' => 'x'), array('ans3' => 'x')));
$this->assertTrue($q->is_same_response_for_part('oddeven', array('ans1' => 'x', 'ans3' => 'x'), array('ans1' => 'y', 'ans3' => 'x')));
$this->assertFalse($q->is_same_response_for_part('oddeven', array('ans3' => 'x'), array('ans3' => 'y')));
}
public function test_is_complete_response_test0() {
$q = $this->get_test_stack_question('test0');
$q->start_attempt(new question_attempt_step(), 1);
......
......@@ -255,6 +255,154 @@ class qtype_stack_walkthrough_adaptive_test extends qtype_stack_walkthrough_test
);
}
public function test_test3_repeat_wrong_response_only_penalised_once() {
// The scenario is this: (we use only the ans3 part of test3, leaving the others blank.)
//
// Resp. State Try Raw mark Mark Penalty
// 1. x valid - - - -
// 2. x score X 0.5 0.5 0.1
// 3. x score - - - -
// 4. x+1 valid - - - -
// 5. x+1 score X 0 0.5 0.1
// 6. x valid - - - -
// 7. x score X 0.5 0.5 0.0
// 8. 0 valid - - - -
// 9. 0 score X 1 0.8 0.0
//
// When reading this test, note that check_prt_score checks the score
// returned by get_prt_result, which is the low-level routine that
// calculates the score for the PRT given the response. The
// ...->get_behaviour_var('_tries_oddeven') bit checks to see if the
// behaviour acutally counted this response as a try.
// Create a stack question.
$q = test_question_maker::make_question('stack', 'test3_penalty0_1');
$this->start_attempt_at_question($q, 'adaptive', 4);
// Check the initial state.
$this->check_current_state(question_state::$todo);
$this->check_current_mark(null);
$this->check_prt_score('oddeven', null, null);
$this->assertNull($this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3');
$this->check_output_does_not_contain_input_validation();
$this->check_output_does_not_contain_prt_feedback();
$this->check_output_does_not_contain_stray_placeholders();
$this->check_current_output(
$this->get_does_not_contain_feedback_expectation()
);
// Validate ans3 => 'x'.
$this->process_submission(array('ans3' => 'x', '-submit' => 1));
$this->check_current_mark(null);
$this->check_prt_score('oddeven', null, null);
$this->assertNull($this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x');
$this->check_output_contains_input_validation('ans3');
$this->check_output_does_not_contain_prt_feedback();
$this->check_output_does_not_contain_stray_placeholders();
// Score ans3 => 'x'.
$this->process_submission(array('ans3' => 'x', 'ans3_val' => 'x', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', 0.5, 0.1);
$this->assertEquals(1, $this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x');
$this->check_output_contains_input_validation('ans3');
$this->check_output_contains_prt_feedback('oddeven');
$this->check_output_does_not_contain_stray_placeholders();
// Score ans3 => 'x'. (put it an ans1 to validate, to force the creation of a new step.)
$this->process_submission(array('ans3' => 'x', 'ans3_val' => 'x', 'ans1' => 'x', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', 0.5, 0.1);
$this->assertNull($this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x');
$this->check_output_contains_input_validation('ans3');
$this->check_output_contains_prt_feedback('oddeven');
$this->check_output_does_not_contain_stray_placeholders();
// Validate ans3 => 'x + 1'.
$this->process_submission(array('ans3' => 'x + 1', 'ans3_val' => 'x', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', null, null);
$this->assertNull($this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x + 1');
$this->check_output_contains_input_validation('ans3');
$this->check_output_does_not_contain_prt_feedback();
$this->check_output_does_not_contain_stray_placeholders();
// Score ans3 => 'x + 1'.
$this->process_submission(array('ans3' => 'x + 1', 'ans3_val' => 'x + 1', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', 0, 0.1);
$this->assertEquals(2, $this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x + 1');
$this->check_output_contains_input_validation('ans3');
$this->check_output_contains_prt_feedback('oddeven');
$this->check_output_does_not_contain_stray_placeholders();
// Validate ans3 => 'x'.
$this->process_submission(array('ans3' => 'x', 'ans3_val' => 'x + 1', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', null, null);
$this->assertNull($this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x');
$this->check_output_contains_input_validation('ans3');
$this->check_output_does_not_contain_prt_feedback();
$this->check_output_does_not_contain_stray_placeholders();
// Score ans3 => 'x'.
$this->process_submission(array('ans3' => 'x', 'ans3_val' => 'x', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', 0.5, 0.1);
$this->assertEquals(3, $this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', 'x');
$this->check_output_contains_input_validation('ans3');
$this->check_output_contains_prt_feedback('oddeven');
$this->check_output_does_not_contain_stray_placeholders();
// Validate ans3 => '0'.
$this->process_submission(array('ans3' => '0', 'ans3_val' => 'x', '-submit' => 1));
$this->check_current_mark(0.5);
$this->check_prt_score('oddeven', null, null);
$this->assertNull($this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', '0');
$this->check_output_contains_input_validation('ans3');
$this->check_output_does_not_contain_prt_feedback();
$this->check_output_does_not_contain_stray_placeholders();
// Score ans3 => '0'.
$this->process_submission(array('ans3' => '0', 'ans3_val' => '0', '-submit' => 1));
$this->check_current_mark(0.8);
$this->check_prt_score('oddeven', 1, 0);
$this->assertEquals(4, $this->quba->get_question_attempt($this->slot)->get_last_step()->get_behaviour_var('_tries_oddeven'));
$this->render();
$this->check_output_contains_text_input('ans3', '0');
$this->check_output_contains_input_validation('ans3');
$this->check_output_contains_prt_feedback('oddeven');
$this->check_output_does_not_contain_stray_placeholders();
}
public function test_test3_sumbit_and_finish_before_validating() {
// Create a stack question.
$q = test_question_maker::make_question('stack', 'test3');
......
......@@ -24,14 +24,14 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2012062504;
$plugin->version = 2012070200;
$plugin->requires = 2012061800.00;
$plugin->cron = 0;
$plugin->component = 'qtype_stack';
$plugin->maturity = MATURITY_ALPHA;
$plugin->dependencies = array(
'qbehaviour_adaptivemultipart' => 2012062700,
'qbehaviour_adaptivemultipart' => 2012070200,
'qbehaviour_dfexplicitvaildate' => 2012051600,
'qbehaviour_dfcbmexplicitvaildate' => 2012051600,
);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment