MDL-27649 support question variants as a first-class concept in the question engine.

This commit is contained in:
Tim Hunt 2011-05-25 23:46:08 +01:00
parent f55192bf08
commit 1da821bbde
46 changed files with 283 additions and 98 deletions

View File

@ -1347,8 +1347,9 @@
<FIELD NAME="questionusageid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Foreign key, references question_usages.id" PREVIOUS="id" NEXT="slot"/>
<FIELD NAME="slot" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Used to number the questions in one attempt sequentially." PREVIOUS="questionusageid" NEXT="behaviour"/>
<FIELD NAME="behaviour" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The name of the question behaviour that is managing this question attempt." PREVIOUS="slot" NEXT="questionid"/>
<FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The id of the question being attempted. Foreign key references question.id." PREVIOUS="behaviour" NEXT="maxmark"/>
<FIELD NAME="maxmark" TYPE="number" LENGTH="12" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" DECIMALS="7" COMMENT="The grade this question is marked out of in this attempt." PREVIOUS="questionid" NEXT="minfraction"/>
<FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The id of the question being attempted. Foreign key references question.id." PREVIOUS="behaviour" NEXT="variant"/>
<FIELD NAME="variant" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The variant of the qusetion being used." PREVIOUS="questionid" NEXT="maxmark"/>
<FIELD NAME="maxmark" TYPE="number" LENGTH="12" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" DECIMALS="7" COMMENT="The grade this question is marked out of in this attempt." PREVIOUS="variant" NEXT="minfraction"/>
<FIELD NAME="minfraction" TYPE="number" LENGTH="12" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" DECIMALS="7" COMMENT="Some questions can award negative marks. This indicates the most negative mark that can be awarded, on the faction scale where the maximum positive mark is 1." PREVIOUS="maxmark" NEXT="flagged"/>
<FIELD NAME="flagged" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether this question has been flagged within the attempt." PREVIOUS="minfraction" NEXT="questionsummary"/>
<FIELD NAME="questionsummary" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" COMMENT="If this question uses randomisation, it should set this field to summarise what random version the student actually saw. This is a human-readable textual summary of the student's response which might, for example, be used in a report." PREVIOUS="flagged" NEXT="rightanswer"/>

View File

@ -6414,6 +6414,21 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
upgrade_main_savepoint(true, 2011051212);
}
if ($oldversion < 2011051213) {
// Define field variant to be added to question_attempts
$table = new xmldb_table('question_attempts');
$field = new xmldb_field('variant', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED,
XMLDB_NOTNULL, null, 1, 'questionid');
// Launch add field component
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached
upgrade_main_savepoint(true, 2011051213);
}
return true;
}

View File

@ -503,6 +503,7 @@ function local_qeupgradehelper_generate_unit_test($questionsessionid, $namesuffi
echo "
'behaviour' => '{$quiz->preferredbehaviour}',
'questionid' => {$question->id},
'variant' => 1,
'maxmark' => {$question->maxmark},
'minfraction' => 0,
'flagged' => 0,

View File

@ -145,7 +145,7 @@ if (!($quiz->attemptonlast && $lastattempt)) {
}
// Start all the quetsions.
$quba->start_all_questions(time(), null);
$quba->start_all_questions(null, time(), null);
// Update attempt layout.
$newlayout = array();

View File

@ -334,9 +334,10 @@ abstract class question_behaviour {
*
* @param question_attempt_step $step the first step of the
* question_attempt being started.
* @param int $variant which variant of the question to use.
*/
public function init_first_step(question_attempt_step $step) {
$this->question->start_attempt($step);
public function init_first_step(question_attempt_step $step, $variant) {
$this->question->start_attempt($step, $variant);
}
/**

View File

@ -138,8 +138,8 @@ class qbehaviour_interactive extends question_behaviour_with_save {
}
}
public function init_first_step(question_attempt_step $step) {
parent::init_first_step($step);
public function init_first_step(question_attempt_step $step, $variant) {
parent::init_first_step($step, $variant);
$step->set_behaviour_var('_triesleft', count($this->question->hints) + 1);
}

View File

@ -53,7 +53,7 @@ class qbehaviour_missing extends question_behaviour {
return '';
}
public function init_first_step(question_attempt_step $step) {
public function init_first_step(question_attempt_step $step, $variant) {
throw new coding_exception('The behaviour used for this question is not available. ' .
'No processing is possible.');
}

View File

@ -42,7 +42,7 @@ class qbehaviour_missing_test extends UnitTestCase {
$qa = new question_attempt(test_question_maker::make_a_truefalse_question(), 0);
$behaviour = new qbehaviour_missing($qa, 'deferredfeedback');
$this->expectException();
$behaviour->init_first_step(new question_attempt_step(array()));
$behaviour->init_first_step(new question_attempt_step(array()), 1);
}
public function test_missing_cannot_process() {
@ -62,15 +62,15 @@ class qbehaviour_missing_test extends UnitTestCase {
public function test_render_missing() {
$records = testing_db_record_builder::build_db_records(array(
array('id', 'questionattemptid', 'contextid', 'questionusageid', 'slot',
'behaviour', 'questionid', 'maxmark', 'minfraction', 'flagged',
'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'flagged',
'questionsummary', 'rightanswer', 'responsesummary',
'timemodified', 'attemptstepid', 'sequencenumber', 'state', 'fraction',
'timecreated', 'userid', 'name', 'value'),
array(1, 1, 123, 1, 1, 'strangeunknown', -1, 2.0000000, 0.0000000, 0, '', '', '',
array(1, 1, 123, 1, 1, 'strangeunknown', -1, 1, 2.0000000, 0.0000000, 0, '', '', '',
1256233790, 1, 0, 'todo', null, 1256233700, 1, '_order', '1,2,3'),
array(2, 1, 123, 1, 1, 'strangeunknown', -1, 2.0000000, 0.0000000, 0, '', '', '',
array(2, 1, 123, 1, 1, 'strangeunknown', -1, 1, 2.0000000, 0.0000000, 0, '', '', '',
1256233790, 2, 1, 'complete', 0.50, 1256233705, 1, '-submit', '1'),
array(3, 1, 123, 1, 1, 'strangeunknown', -1, 2.0000000, 0.0000000, 0, '', '', '',
array(3, 1, 123, 1, 1, 'strangeunknown', -1, 1, 2.0000000, 0.0000000, 0, '', '', '',
1256233790, 2, 1, 'complete', 0.50, 1256233705, 1, 'choice0', '1'),
));

View File

@ -84,6 +84,7 @@ class question_engine_data_mapper {
$record->slot = $qa->get_slot();
$record->behaviour = $qa->get_behaviour_name();
$record->questionid = $qa->get_question()->id;
$record->variant = $qa->get_variant();
$record->maxmark = $qa->get_max_mark();
$record->minfraction = $qa->get_min_fraction();
$record->flagged = $qa->is_flagged();
@ -180,6 +181,7 @@ SELECT
qa.slot,
qa.behaviour,
qa.questionid,
qa.variant,
qa.maxmark,
qa.minfraction,
qa.flagged,
@ -236,6 +238,7 @@ SELECT
qa.slot,
qa.behaviour,
qa.questionid,
qa.variant,
qa.maxmark,
qa.minfraction,
qa.flagged,
@ -291,6 +294,7 @@ SELECT
qa.slot,
qa.behaviour,
qa.questionid,
qa.variant,
qa.maxmark,
qa.minfraction,
qa.flagged,
@ -549,6 +553,7 @@ SELECT
qa.slot,
qa.behaviour,
qa.questionid,
qa.variant,
qa.maxmark,
qa.minfraction,
qa.flagged,
@ -819,6 +824,7 @@ ORDER BY
{$alias}qa.slot,
{$alias}qa.behaviour,
{$alias}qa.questionid,
{$alias}qa.variant,
{$alias}qa.maxmark,
{$alias}qa.minfraction,
{$alias}qa.flagged,

View File

@ -760,3 +760,33 @@ abstract class question_utils {
self::$tens[$number / 10 % 10] . self::$units[$number % 10];
}
}
/**
* The interface for strategies for controlling which variant of each question is used.
*
* @copyright 2010 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface question_variant_selection_strategy {
/**
* @param int $maxvariants the num
* @param string $seed data that can be used to controls how the variant is selected
* in a semi-random way.
* @return int the variant to use, a number betweeb 1 and $maxvariants inclusive.
*/
public function choose_variant($maxvariants, $seed);
}
/**
* A {@link question_variant_selection_strategy} that is completely random.
*
* @copyright 2010 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class question_variant_random_strategy implements question_variant_selection_strategy {
public function choose_variant($maxvariants, $seed) {
return rand(1, $maxvariants);
}
}

View File

@ -84,6 +84,9 @@ class question_attempt {
/** @var question_definition the question this is an attempt at. */
protected $question;
/** @var int which variant of the question to use. */
protected $variant;
/** @var number the maximum mark that can be scored at this question. */
protected $maxmark;
@ -162,6 +165,14 @@ class question_attempt {
return $this->question;
}
/**
* Get the variant of the question being used in a given slot.
* @return int the variant number.
*/
public function get_variant() {
return $this->variant;
}
/**
* Set the number used to identify this question_attempt within the usage.
* For internal use only.
@ -735,6 +746,16 @@ class question_attempt {
$this->observer->notify_step_added($step, $this, key($this->steps));
}
/**
* Use a strategy to pick a variant.
* @param question_variant_selection_strategy $variantstrategy a strategy.
* @return int the selected variant.
*/
public function select_variant(question_variant_selection_strategy $variantstrategy) {
return $variantstrategy->choose_variant($this->get_question()->get_num_variants(),
$this->get_question()->get_variants_selection_seed());
}
/**
* Start this question attempt.
*
@ -743,12 +764,17 @@ class question_attempt {
*
* @param string|question_behaviour $preferredbehaviour the name of the
* desired archetypal behaviour, or an actual model instance.
* @param int $variant the variant of the question to start. Between 1 and
* $this->get_question()->get_num_variants() inclusive.
* @param array $submitteddata optional, used when re-starting to keep the same initial state.
* @param int $timestamp optional, the timstamp to record for this action. Defaults to now.
* @param int $userid optional, the user to attribute this action to. Defaults to the current user.
*/
public function start($preferredbehaviour, $submitteddata = array(), $timestamp = null, $userid = null) {
public function start($preferredbehaviour, $variant, $submitteddata = array(),
$timestamp = null, $userid = null) {
// Initialise the behaviour.
$this->variant = $variant;
if (is_string($preferredbehaviour)) {
$this->behaviour =
$this->question->make_behaviour($this, $preferredbehaviour);
@ -766,7 +792,7 @@ class question_attempt {
if ($submitteddata) {
$this->question->apply_attempt_state($firststep);
} else {
$this->behaviour->init_first_step($firststep);
$this->behaviour->init_first_step($firststep, $variant);
}
$this->add_step($firststep);
@ -786,7 +812,7 @@ class question_attempt {
* defines the starting point.
*/
public function start_based_on(question_attempt $oldqa) {
$this->start($oldqa->behaviour, $oldqa->get_resume_data());
$this->start($oldqa->behaviour, $oldqa->get_variant(), $oldqa->get_resume_data());
}
/**
@ -1013,7 +1039,7 @@ class question_attempt {
foreach ($oldqa->get_step_iterator() as $step) {
if ($first) {
$first = false;
$this->start($oldqa->behaviour, $step->get_all_data(),
$this->start($oldqa->behaviour, $oldqa->get_variant(), $step->get_all_data(),
$step->get_timecreated(), $step->get_user_id());
} else {
$this->process_action($step->get_submitted_data(),
@ -1109,6 +1135,7 @@ class question_attempt {
null, $record->maxmark + 0);
$qa->set_database_id($record->questionattemptid);
$qa->set_number_in_usage($record->slot);
$qa->variant = $record->variant + 0;
$qa->minfraction = $record->minfraction + 0;
$qa->set_flagged($record->flagged);
$qa->questionsummary = $record->questionsummary;
@ -1194,7 +1221,7 @@ class question_attempt_with_restricted_history extends question_attempt {
public function process_action($submitteddata, $timestamp = null, $userid = null) {
coding_exception('Cannot modify a question_attempt_with_restricted_history.');
}
public function start($preferredbehaviour, $submitteddata = array(), $timestamp = null, $userid = null) {
public function start($preferredbehaviour, $variant, $submitteddata = array(), $timestamp = null, $userid = null) {
coding_exception('Cannot modify a question_attempt_with_restricted_history.');
}

View File

@ -101,6 +101,10 @@ class question_attempt_step {
*/
public function __construct($data = array(), $timecreated = null, $userid = null) {
global $USER;
if (!is_array($data)) {
echo format_backtrace(debug_backtrace());
}
$this->state = question_state::$unprocessed;
$this->data = $data;
if (is_null($timecreated)) {

View File

@ -407,24 +407,55 @@ class question_usage_by_activity {
return $this->get_question_attempt($slot)->get_field_prefix();
}
/**
* Get the number of variants available for the question in this slot.
* @param int $slot the number used to identify this question within this usage.
* @return int the number of variants available.
*/
public function get_num_variants($slot) {
return $this->get_question_attempt($slot)->get_question()->get_num_variants();
}
/**
* Get the variant of the question being used in a given slot.
* @param int $slot the number used to identify this question within this usage.
* @return int the variant of this question that is being used.
*/
public function get_variant($slot) {
return $this->get_question_attempt($slot)->get_variant();
}
/**
* Start the attempt at a question that has been added to this usage.
* @param int $slot the number used to identify this question within this usage.
* @param int $variant which variant of the question to use. Must be between
* 1 and ->get_num_variants($slot) inclusive. If not give, a variant is
* chosen at random.
*/
public function start_question($slot) {
public function start_question($slot, $variant = null) {
if (is_null($variant)) {
$variant = rand(1, $this->get_num_variants($slot));
}
$qa = $this->get_question_attempt($slot);
$qa->start($this->preferredbehaviour);
$qa->start($this->preferredbehaviour, $variant);
$this->observer->notify_attempt_modified($qa);
}
/**
* Start the attempt at all questions that has been added to this usage.
* @param question_variant_selection_strategy how to pick which variant of each question to use.
* @param int $timestamp optional, the timstamp to record for this action. Defaults to now.
* @param int $userid optional, the user to attribute this action to. Defaults to the current user.
*/
public function start_all_questions($timestamp = null, $userid = null) {
public function start_all_questions(question_variant_selection_strategy $variantstrategy = null,
$timestamp = null, $userid = null) {
if (is_null($variantstrategy)) {
$variantstrategy = new question_variant_random_strategy();
}
foreach ($this->questionattempts as $qa) {
$qa->start($this->preferredbehaviour);
$qa->start($this->preferredbehaviour, $qa->select_variant($variantstrategy));
$this->observer->notify_attempt_modified($qa);
}
}

View File

@ -263,18 +263,18 @@ class question_attempt_db_test extends data_loading_method_test_base {
public function test_load() {
$records = testing_db_record_builder::build_db_records(array(
array('id', 'questionattemptid', 'contextid', 'questionusageid', 'slot',
'behaviour', 'questionid', 'maxmark', 'minfraction', 'flagged',
'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
'attemptstepid', 'sequencenumber', 'state', 'fraction',
'timecreated', 'userid', 'name', 'value'),
array(1, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null),
array(2, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 2, 1, 'complete', null, 1256233705, 1, 'answer', '1'),
array(3, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 1, '', '', '', 1256233790, 3, 2, 'complete', null, 1256233710, 1, 'answer', '0'),
array(4, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 4, 3, 'complete', null, 1256233715, 1, 'answer', '1'),
array(5, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 5, 4, 'gradedright', 1.0000000, 1256233720, 1, '-finish', '1'),
array(6, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-comment', 'Not good enough!'),
array(7, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-mark', '1'),
array(8, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-maxmark', '2'),
'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'flagged',
'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
'attemptstepid', 'sequencenumber', 'state', 'fraction',
'timecreated', 'userid', 'name', 'value'),
array(1, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null),
array(2, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 2, 1, 'complete', null, 1256233705, 1, 'answer', '1'),
array(3, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1, '', '', '', 1256233790, 3, 2, 'complete', null, 1256233710, 1, 'answer', '0'),
array(4, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 4, 3, 'complete', null, 1256233715, 1, 'answer', '1'),
array(5, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 5, 4, 'gradedright', 1.0000000, 1256233720, 1, '-finish', '1'),
array(6, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-comment', 'Not good enough!'),
array(7, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-mark', '1'),
array(8, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-maxmark', '2'),
));
$question = test_question_maker::make_a_truefalse_question();
@ -336,11 +336,11 @@ class question_attempt_db_test extends data_loading_method_test_base {
public function test_load_missing_question() {
$records = testing_db_record_builder::build_db_records(array(
array('id', 'questionattemptid', 'contextid', 'questionusageid', 'slot',
'behaviour', 'questionid', 'maxmark', 'minfraction', 'flagged',
'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
'attemptstepid', 'sequencenumber', 'state', 'fraction',
'timecreated', 'userid', 'name', 'value'),
array(1, 1, 123, 1, 1, 'deferredfeedback', -1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null),
'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'flagged',
'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
'attemptstepid', 'sequencenumber', 'state', 'fraction',
'timecreated', 'userid', 'name', 'value'),
array(1, 1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo', null, 1256233700, 1, null, null),
));
question_bank::start_unit_test();

View File

@ -131,6 +131,7 @@ abstract class question_behaviour_attempt_updater {
$qa = new stdClass();
$qa->questionid = $this->question->id;
$qa->variant = 1;
$qa->behaviour = $this->behaviour_name();
$qa->questionsummary = $this->qtypeupdater->question_summary($this->question);
$qa->rightanswer = $this->qtypeupdater->right_answer($this->question);

View File

@ -200,6 +200,7 @@ class qtype_calculated_attempt_upgrader_test extends question_attempt_upgrader_t
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 18,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -422,6 +423,7 @@ Remember to type a unit.',
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 18,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -651,6 +653,7 @@ Remember to type a unit.',
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 18,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,

View File

@ -50,9 +50,9 @@ class qtype_calculated_question extends qtype_numerical_question
*/
public $synchronised;
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
qtype_calculated_question_helper::start_attempt($this, $step);
parent::start_attempt($step);
parent::start_attempt($step, $variant);
}
public function apply_attempt_state(question_attempt_step $step) {

View File

@ -55,7 +55,7 @@ class qtype_calculated_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array(0, question_state::$gradedwrong),
@ -66,7 +66,7 @@ class qtype_calculated_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array('answer' => $values['a'] + $values['b']),
@ -75,7 +75,7 @@ class qtype_calculated_question_test extends UnitTestCase {
public function test_get_question_summary() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$qsummary = $question->get_question_summary();
@ -84,7 +84,7 @@ class qtype_calculated_question_test extends UnitTestCase {
public function test_summarise_response() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual('3.1', $question->summarise_response(array('answer' => '3.1')));
@ -92,7 +92,7 @@ class qtype_calculated_question_test extends UnitTestCase {
public function test_classify_response() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array(

View File

@ -227,6 +227,7 @@ class qtype_calculatedmulti_attempt_upgrader_test extends question_attempt_upgra
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 17,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -460,6 +461,7 @@ class qtype_calculatedmulti_attempt_upgrader_test extends question_attempt_upgra
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 17,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -737,6 +739,7 @@ class qtype_calculatedmulti_attempt_upgrader_test extends question_attempt_upgra
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 17,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,

View File

@ -51,7 +51,7 @@ class qtype_calculatedmulti_single_question extends qtype_multichoice_single_que
*/
public $synchronised;
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
qtype_calculated_question_helper::start_attempt($this, $step);
parent::start_attempt($step);
}
@ -88,9 +88,9 @@ class qtype_calculatedmulti_multi_question extends qtype_multichoice_multi_quest
*/
public $synchronised;
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
qtype_calculated_question_helper::start_attempt($this, $step);
parent::start_attempt($step);
parent::start_attempt($step, $variant);
}
public function apply_attempt_state(question_attempt_step $step) {

View File

@ -55,7 +55,7 @@ class qtype_calculatedmulti_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array(0, question_state::$gradedwrong),
@ -66,7 +66,7 @@ class qtype_calculatedmulti_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array('answer' => $values['a'] + $values['b']),
@ -75,7 +75,7 @@ class qtype_calculatedmulti_question_test extends UnitTestCase {
public function test_get_question_summary() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$qsummary = $question->get_question_summary();
@ -84,7 +84,7 @@ class qtype_calculatedmulti_question_test extends UnitTestCase {
public function test_summarise_response() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual('3.1', $question->summarise_response(array('answer' => '3.1')));
@ -92,7 +92,7 @@ class qtype_calculatedmulti_question_test extends UnitTestCase {
public function test_classify_response() {
$question = test_question_maker::make_question('calculated');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array(

View File

@ -191,6 +191,7 @@ class qtype_calculatedsimple_attempt_upgrader_test extends question_attempt_upgr
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 16,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -400,6 +401,7 @@ class qtype_calculatedsimple_attempt_upgrader_test extends question_attempt_upgr
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 16,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -601,6 +603,7 @@ class qtype_calculatedsimple_attempt_upgrader_test extends question_attempt_upgr
$expectedqa = (object) array(
'behaviour' => 'adaptive',
'questionid' => 16,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,

View File

@ -55,7 +55,7 @@ class qtype_calculatedsimple_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array(0, question_state::$gradedwrong),
@ -66,7 +66,7 @@ class qtype_calculatedsimple_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array('answer' => $values['a'] + $values['b']),
@ -75,7 +75,7 @@ class qtype_calculatedsimple_question_test extends UnitTestCase {
public function test_get_question_summary() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$qsummary = $question->get_question_summary();
@ -84,7 +84,7 @@ class qtype_calculatedsimple_question_test extends UnitTestCase {
public function test_summarise_response() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual('3.1', $question->summarise_response(array('answer' => '3.1')));
@ -92,7 +92,7 @@ class qtype_calculatedsimple_question_test extends UnitTestCase {
public function test_classify_response() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$values = $question->vs->get_values();
$this->assertEqual(array(

View File

@ -153,6 +153,7 @@ class qtype_description_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'informationitem',
'questionid' => 4940,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -298,6 +299,7 @@ class qtype_description_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'informationitem',
'questionid' => 8492,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,
@ -433,6 +435,7 @@ class qtype_description_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'informationitem',
'questionid' => 8719,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,

View File

@ -214,6 +214,7 @@ class qtype_essay_attempt_upgrader_test extends question_attempt_upgrader_test_b
$expectedqa = (object) array(
'behaviour' => 'manualgraded',
'questionid' => 90056,
'variant' => 1,
'maxmark' => 2,
'minfraction' => 0,
'flagged' => 0,
@ -412,6 +413,7 @@ class qtype_essay_attempt_upgrader_test extends question_attempt_upgrader_test_b
$expectedqa = (object) array(
'behaviour' => 'manualgraded',
'questionid' => 3729,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,
@ -539,6 +541,7 @@ class qtype_essay_attempt_upgrader_test extends question_attempt_upgrader_test_b
$expectedqa = (object) array(
'behaviour' => 'manualgraded',
'questionid' => 3729,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,

View File

@ -226,6 +226,7 @@ class qtype_match_attempt_upgrader_test extends question_attempt_upgrader_test_b
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 695,
'variant' => 1,
'maxmark' => 3,
'minfraction' => 0,
'flagged' => 0,
@ -442,6 +443,7 @@ class qtype_match_attempt_upgrader_test extends question_attempt_upgrader_test_b
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 738,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -705,6 +707,7 @@ class qtype_match_attempt_upgrader_test extends question_attempt_upgrader_test_b
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 11135,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,

View File

@ -56,7 +56,7 @@ class qtype_match_question extends question_graded_automatically_with_countback
/** @var array shuffled choice indexes. */
protected $choiceorder;
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
$this->stemorder = array_keys($this->stems);
if ($this->shufflestems) {
shuffle($this->stemorder);

View File

@ -39,7 +39,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_get_expected_data() {
$question = test_question_maker::make_a_matching_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array('sub0' => PARAM_INT, 'sub1' => PARAM_INT,
'sub2' => PARAM_INT, 'sub3' => PARAM_INT), $question->get_expected_data());
@ -47,7 +47,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_is_complete_response() {
$question = test_question_maker::make_a_matching_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertFalse($question->is_complete_response(array()));
$this->assertFalse($question->is_complete_response(
@ -59,7 +59,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_is_gradable_response() {
$question = test_question_maker::make_a_matching_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertFalse($question->is_gradable_response(array()));
$this->assertFalse($question->is_gradable_response(
@ -73,7 +73,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_is_same_response() {
$question = test_question_maker::make_a_matching_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertTrue($question->is_same_response(
array(),
@ -99,7 +99,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_a_matching_question();
$question->shufflestems = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$choiceorder = $question->get_choice_order();
$orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
@ -119,7 +119,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_a_matching_question();
$question->shufflestems = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$choiceorder = $question->get_choice_order();
$orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
@ -131,7 +131,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_get_question_summary() {
$match = test_question_maker::make_a_matching_question();
$match->start_attempt(new question_attempt_step());
$match->start_attempt(new question_attempt_step(), 1);
$qsummary = $match->get_question_summary();
$this->assertPattern('/' . preg_quote($match->questiontext) . '/', $qsummary);
foreach ($match->stems as $stem) {
@ -145,7 +145,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_summarise_response() {
$match = test_question_maker::make_a_matching_question();
$match->shufflestems = false;
$match->start_attempt(new question_attempt_step());
$match->start_attempt(new question_attempt_step(), 1);
$summary = $match->summarise_response(array('sub0' => 2, 'sub1' => 1));
@ -155,7 +155,7 @@ class qtype_match_question_test extends UnitTestCase {
public function test_classify_response() {
$match = test_question_maker::make_a_matching_question();
$match->shufflestems = false;
$match->start_attempt(new question_attempt_step());
$match->start_attempt(new question_attempt_step(), 1);
$choiceorder = $match->get_choice_order();
$orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));

View File

@ -76,7 +76,7 @@ class qtype_missingtype_question extends question_definition
return array();
}
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
throw new coding_exception('This question is of a type that is not installed ' .
'on your system. No processing is possible.');
}

View File

@ -201,6 +201,7 @@ class qtype_multianswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'adaptivenopenalty',
'questionid' => 28,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -392,6 +393,7 @@ class qtype_multianswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'adaptivenopenalty',
'questionid' => 28,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -598,6 +600,7 @@ class qtype_multianswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'adaptivenopenalty',
'questionid' => 28,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -1266,6 +1269,7 @@ class qtype_multianswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'adaptivenopenalty',
'questionid' => 19,
'variant' => 1,
'maxmark' => 13.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -1939,6 +1943,7 @@ b) What grade would you give it? _____',
$expectedqa = (object) array(
'behaviour' => 'adaptivenopenalty',
'questionid' => 19,
'variant' => 1,
'maxmark' => 13.0000000,
'minfraction' => 0,
'flagged' => 0,
@ -2632,6 +2637,7 @@ b) What grade would you give it? _____',
$expectedqa = (object) array(
'behaviour' => 'adaptivenopenalty',
'questionid' => 19,
'variant' => 1,
'maxmark' => 13.0000000,
'minfraction' => 0,
'flagged' => 0,

View File

@ -65,9 +65,9 @@ class qtype_multianswer_question extends question_graded_automatically {
return new question_attempt_step_subquestion_adapter($step, 'sub' . $i . '_');
}
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
foreach ($this->subquestions as $i => $subq) {
$subq->start_attempt($this->get_substep($step, $i));
$subq->start_attempt($this->get_substep($step, $i), $variant);
}
}

View File

@ -65,7 +65,7 @@ class qtype_multianswer_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_question('multianswer');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$rightchoice = $question->subquestions[2]->get_correct_response();
@ -81,7 +81,7 @@ class qtype_multianswer_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_question('multianswer');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$rightchoice = $question->subquestions[2]->get_correct_response();
@ -95,7 +95,7 @@ class qtype_multianswer_question_test extends UnitTestCase {
// Bit of a hack to make testing easier.
$question->subquestions[2]->shuffleanswers = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$qsummary = $question->get_question_summary();
$this->assertEqual('Complete this opening line of verse: "The _____ and the ' .
@ -104,7 +104,7 @@ class qtype_multianswer_question_test extends UnitTestCase {
public function test_summarise_response() {
$question = test_question_maker::make_question('multianswer');
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$rightchoice = $question->subquestions[2]->get_correct_response();

View File

@ -235,6 +235,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 2,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -410,6 +411,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 72,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -604,6 +606,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 218,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -826,6 +829,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 2855,
'variant' => 1,
'maxmark' => 5,
'minfraction' => 0,
'flagged' => 0,
@ -983,6 +987,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 72,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -1176,6 +1181,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 179,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -1413,6 +1419,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 26132,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,
@ -1644,6 +1651,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 60137,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -1872,6 +1880,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 163,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -2084,6 +2093,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 89040,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -2298,6 +2308,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 3863,
'variant' => 1,
'maxmark' => 5,
'minfraction' => 0,
'flagged' => 0,
@ -2506,6 +2517,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 247,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,
@ -2716,6 +2728,7 @@ public function test_multichoice_deferredfeedback_qsession140() {
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 242,
'variant' => 1,
'maxmark' => 0,
'minfraction' => 0,
'flagged' => 0,

View File

@ -54,7 +54,7 @@ abstract class qtype_multichoice_base extends question_graded_automatically {
protected $order = null;
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
$this->order = array_keys($this->answers);
if ($this->shuffleanswers) {
shuffle($this->order);

View File

@ -61,7 +61,7 @@ class qtype_multichoice_single_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_a_multichoice_single_question();
$question->shuffleanswers = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(1, question_state::$gradedright),
$question->grade_response(array('answer' => 0)));
@ -94,7 +94,7 @@ class qtype_multichoice_single_question_test extends UnitTestCase {
16 => new question_answer(16, '6', -1, '', FORMAT_HTML),
);
$mc->start_attempt(new question_attempt_step());
$mc->start_attempt(new question_attempt_step(), 1);
list($grade, $state) = $mc->grade_response(
array('choice0' => 1, 'choice2' => 1, 'choice4' => 1));
@ -105,7 +105,7 @@ class qtype_multichoice_single_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_a_multichoice_single_question();
$question->shuffleanswers = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array('answer' => 0),
$question->get_correct_response());
@ -114,7 +114,7 @@ class qtype_multichoice_single_question_test extends UnitTestCase {
public function test_summarise_response() {
$mc = test_question_maker::make_a_multichoice_single_question();
$mc->shuffleanswers = false;
$mc->start_attempt(new question_attempt_step());
$mc->start_attempt(new question_attempt_step(), 1);
$summary = $mc->summarise_response(array('answer' => 0),
test_question_maker::get_a_qa($mc));
@ -125,7 +125,7 @@ class qtype_multichoice_single_question_test extends UnitTestCase {
public function test_classify_response() {
$mc = test_question_maker::make_a_multichoice_single_question();
$mc->shuffleanswers = false;
$mc->start_attempt(new question_attempt_step());
$mc->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
$mc->id => new question_classified_response(14, 'B', -0.3333333),
@ -148,7 +148,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_get_expected_data() {
$question = test_question_maker::make_a_multichoice_multi_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array('choice0' => PARAM_BOOL, 'choice1' => PARAM_BOOL,
'choice2' => PARAM_BOOL, 'choice3' => PARAM_BOOL), $question->get_expected_data());
@ -156,7 +156,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_is_complete_response() {
$question = test_question_maker::make_a_multichoice_multi_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertFalse($question->is_complete_response(array()));
$this->assertFalse($question->is_complete_response(
@ -168,7 +168,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_is_gradable_response() {
$question = test_question_maker::make_a_multichoice_multi_question();
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertFalse($question->is_gradable_response(array()));
$this->assertFalse($question->is_gradable_response(
@ -181,7 +181,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_grading() {
$question = test_question_maker::make_a_multichoice_multi_question();
$question->shuffleanswers = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(1, question_state::$gradedright),
$question->grade_response(array('choice0' => '1', 'choice2' => '1')));
@ -197,7 +197,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_get_correct_response() {
$question = test_question_maker::make_a_multichoice_multi_question();
$question->shuffleanswers = false;
$question->start_attempt(new question_attempt_step());
$question->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array('choice0' => '1', 'choice2' => '1'),
$question->get_correct_response());
@ -205,7 +205,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_get_question_summary() {
$mc = test_question_maker::make_a_multichoice_single_question();
$mc->start_attempt(new question_attempt_step());
$mc->start_attempt(new question_attempt_step(), 1);
$qsummary = $mc->get_question_summary();
@ -218,7 +218,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_summarise_response() {
$mc = test_question_maker::make_a_multichoice_multi_question();
$mc->shuffleanswers = false;
$mc->start_attempt(new question_attempt_step());
$mc->start_attempt(new question_attempt_step(), 1);
$summary = $mc->summarise_response(array('choice1' => 1, 'choice2' => 1),
test_question_maker::get_a_qa($mc));
@ -229,7 +229,7 @@ class qtype_multichoice_multi_question_test extends UnitTestCase {
public function test_classify_response() {
$mc = test_question_maker::make_a_multichoice_multi_question();
$mc->shuffleanswers = false;
$mc->start_attempt(new question_attempt_step());
$mc->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
13 => new question_classified_response(13, 'A', 0.5),

View File

@ -225,6 +225,7 @@ class qtype_numerical_attempt_upgrader_test extends question_attempt_upgrader_te
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 4165,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -421,6 +422,7 @@ class qtype_numerical_attempt_upgrader_test extends question_attempt_upgrader_te
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 15,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,

View File

@ -57,7 +57,7 @@ class qtype_numerical_question extends question_graded_automatically {
return $expected;
}
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
$step->set_qt_var('_separators',
$this->ap->get_point() . '$' . $this->ap->get_separator());
}

View File

@ -27,6 +27,8 @@
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/numerical/question.php');
/**
* The numerical question type class.

View File

@ -174,7 +174,7 @@ class qtype_numerical_question_test extends UnitTestCase {
public function test_classify_response() {
$num = test_question_maker::make_question('numerical');
$num->start_attempt(new question_attempt_step());
$num->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
new question_classified_response(15, '3.1', 0.0)),
@ -192,7 +192,7 @@ class qtype_numerical_question_test extends UnitTestCase {
public function test_classify_response_unit() {
$num = test_question_maker::make_question('numerical', 'unit');
$num->start_attempt(new question_attempt_step());
$num->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
new question_classified_response(13, '1.25', 0.5)),
@ -219,7 +219,7 @@ class qtype_numerical_question_test extends UnitTestCase {
public function test_classify_response_currency() {
$num = test_question_maker::make_question('numerical', 'currency');
$num->start_attempt(new question_attempt_step());
$num->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
new question_classified_response(14, '$100', 0)),

View File

@ -157,8 +157,10 @@ abstract class question_definition {
*
* @param question_attempt_step The first step of the {@link question_attempt}
* being started. Can be used to store state.
* @param int $varant which variant of this question to start. Will be between
* 1 and {@link get_num_variants()} inclusive.
*/
public function start_attempt(question_attempt_step $step) {
public function start_attempt(question_attempt_step $step, $variant) {
}
/**
@ -190,6 +192,21 @@ abstract class question_definition {
return $this->html_to_text($this->questiontext, $this->questiontextformat);
}
/**
* @return int the number of vaiants that this question has.
*/
public function get_num_variants() {
return 1;
}
/**
* @return string that can be used to seed the pseudo-random selection of a
* variant.
*/
public function get_variants_selection_seed() {
return $this->stamp;
}
/**
* Some questions can return a negative mark if the student gets it wrong.
*

View File

@ -228,6 +228,7 @@ class qtype_random_attempt_upgrader_test extends question_attempt_upgrader_test_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 34999,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -468,6 +469,7 @@ class qtype_random_attempt_upgrader_test extends question_attempt_upgrader_test_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 98355,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -745,6 +747,7 @@ class qtype_random_attempt_upgrader_test extends question_attempt_upgrader_test_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 83248,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -941,6 +944,7 @@ class qtype_random_attempt_upgrader_test extends question_attempt_upgrader_test_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 14,
'variant' => 1,
'maxmark' => 1.0000000,
'minfraction' => 0,
'flagged' => 0,

View File

@ -209,6 +209,7 @@ class qtype_shortanswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 4239,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -390,6 +391,7 @@ class qtype_shortanswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 10216,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -589,6 +591,7 @@ class qtype_shortanswer_attempt_upgrader_test extends question_attempt_upgrader_
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 4184,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,

View File

@ -159,7 +159,7 @@ class qtype_shortanswer_question_test extends UnitTestCase {
public function test_classify_response() {
$sa = test_question_maker::make_a_shortanswer_question();
$sa->start_attempt(new question_attempt_step());
$sa->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
new question_classified_response(13, 'frog', 1.0)),

View File

@ -189,6 +189,7 @@ class qtype_truefalse_attempt_upgrader_test extends question_attempt_upgrader_te
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 3865,
'variant' => 1,
'maxmark' => 5,
'minfraction' => 0,
'flagged' => 0,
@ -375,6 +376,7 @@ class qtype_truefalse_attempt_upgrader_test extends question_attempt_upgrader_te
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 9062,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,
@ -543,6 +545,7 @@ class qtype_truefalse_attempt_upgrader_test extends question_attempt_upgrader_te
$expectedqa = (object) array(
'behaviour' => 'deferredfeedback',
'questionid' => 111,
'variant' => 1,
'maxmark' => 1,
'minfraction' => 0,
'flagged' => 0,

View File

@ -92,7 +92,7 @@ class qtype_truefalse_question_test extends UnitTestCase {
public function test_classify_response() {
$tf = test_question_maker::make_a_truefalse_question();
$tf->start_attempt(new question_attempt_step());
$tf->start_attempt(new question_attempt_step(), 1);
$this->assertEqual(array(
$tf->id => new question_classified_response(

View File

@ -30,7 +30,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2011051212.00; // YYYYMMDD = weekly release date of this DEV branch
$version = 2011051213.00; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes