Quiz - each attempt builds on the last

Re: Quiz - each attempt builds on the last

by Tim Hunt -
Number of replies: 10
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Yes, it would be nice if the user interface showed this better. (Actually, I think the problem is the way that state is recorded in the underlying data structures, so it is not easy to change.)

I am pretty sure there is a Moodle Tracker issue about this, but I can't find the number now.

In reply to Tim Hunt

Re: Quiz - each attempt builds on the last

by Peter Malcolm -

Hi Tim,

I am part of a developer community that would also like to see this fix implemented.  I'm right now struggling to figure out how to carry the gradedwrong / gradedright data from mdl_question_attempt_steps from one attempt to the next.  If there is any way to do this in a plugin way, that would be ideal, of course.

I cannot see a tracker issue that exactly matches this issue.  The closest I can find is this:
https://tracker.moodle.org/browse/MDL-49133

Is there an issue that is an exact match?  Or a fix implemented already?

Thanks!

-Peter


Average of ratings: Useful (1)
In reply to Peter Malcolm

Re: Quiz - each attempt builds on the last

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Thank you very much for wanting to work on this.

That is not the right tracker issue. I am fairly sure there is a tracker issue for this. Or, perhaps I am just remembering MDL-34597 which may or may not be the same thing.

The only way to fix this is to do a core change.

To underestand the relevant bits of core code, start from mod/quiz/startattempt.php, and follow the calls -> quiz_start_attempt_built_on_last -> $quba->start_question_based_on($newslot, $oldqa); -> $qa->start_based_on($oldqa); -> $oldqa->get_resume_data() or $this->start($oldqa->behaviour, $oldqa->get_variant(), $oldqa->get_resume_data());

I would guess that get_resume_data might be the right place to add some extra information about the state of the previous attemp.

However, note that this method is also used by quiz regrade, so we may not always want to do that. There might be a whole other approach to this, using $this->quba->set_question_attempt_metadata, which might be better. Have a look at the use of that in MDL-40992. I guess this commit is the main one, sorry it is so big https://github.com/moodle/moodle/commit/5e63b335feb18b24a71a653ba6be9e7bb30d340e#diff-355e6fd0f9a1359961a0edc3b3654eb3

I guess you are unlikely to be at the UK Moodle Moot next week? If you were, we could discuss this.

I am assuming that you have already read https://docs.moodle.org/dev/Overview_of_the_Moodle_question_engine

In reply to Tim Hunt

Re: Quiz - each attempt builds on the last

by Peter Malcolm -

Hi Tim,

I'm in the US, and will not be at the UK Moodle Moot, sadly.

Thank you for the tips.  I've been reviewing the Question Engine documentation, which is a good start.  I was not aware of question attempt metadata -- that looks promising.

In reply to Tim Hunt

Re: Quiz - each attempt builds on the last

by Peter Malcolm -

Hi Tim,

Thanks for the guidance.  I have dug into the idea of metadata, exploring the way it works with the "Redo question" functionality turned on.  It creates an :_originalslot entry in the mdl_question_attempt_step_data table:

id   attemptstepid   name             value
---+---------------+----------------+--------
497  254             :_originalslot   3

I notice that this entry vanishes as soon as I start the next attempt of the quiz.  Is this the built-in behavior of metadata?  I am aiming to have the correctness (incorrect, partiallycorrect, correct) persist from one attempt to the next. Is metadata intended to persist like this?

-Peter

In reply to Peter Malcolm

Re: Quiz - each attempt builds on the last

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Redo question was the first, and so far only, feature implemented that required metadata like this, so I implemented what I needed. However, I think non-persistence is probably OK.

Surely, what you need to do is, when the second attempt is started, add metadata to that newly created attempt about what the state was in the first attempt. This does not require any metadata to be stored in the first attempt. Nor would be be desirable for the metadata to be automatically copied (e.g. from the second attempt to the third attempt.)

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Quiz - each attempt builds on the last

by Peter Malcolm -

Hi Tim,

It looks as though there is a chunk of code that deletes the $quba object, and it's corresponding database data, before rebuilding a brand new (empty) $quba, in mod/quiz/startattempt.php#LINE166-end.  Would a new object, something like $questions_usage_carryover_data, need to be created before the deletion of the first $quba, containing the gradedright / gradedwrong data from DB table mdl_question_attempt_steps, for immediate insertion into the metadata in mdl_question_attempt_step_data for the brand new $quba as it is created?  Am I missing some other place in the code where the two $quba objects (and their corresponding DB data) exist at the same time?  For reference here is the startattempt code:


// Delete any previous preview attempts belonging to this user.
quiz_delete_previews($quizobj->get_quiz(), $USER->id);

$quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
$quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);

// Create the new attempt and initialize the question sessions
$timenow = time(); // Update time now, in case the server is running really slowly.
$attempt = quiz_create_attempt($quizobj, $attemptnumber, $lastattempt, $timenow, $quizobj->is_preview_user());

if (!($quizobj->get_quiz()->attemptonlast && $lastattempt)) {
    $attempt = quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $timenow);
} else {
    $attempt = quiz_start_attempt_built_on_last($quba, $attempt, $lastattempt);
}

$transaction = $DB->start_delegated_transaction();

$attempt = quiz_attempt_save_started($quizobj, $quba, $attempt);

$transaction->allow_commit();

// Redirect to the attempt page.
redirect($quizobj->attempt_url($attempt->id, $page));
Thanks!
In reply to Peter Malcolm

Re: Quiz - each attempt builds on the last

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

It looks as though there is a chunk of code that deletes the $quba object, and it's corresponding database data, before rebuilding a brand new (empty) $quba,

This is false.

At least, that only happens if a teacher is previewing a quiz. To test each attempt builts on last, you need to use a student account.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Quiz - each attempt builds on the last

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Note, there is not yet a Moodle tracker issue for this work, and there probably should be.

In reply to Tim Hunt

Re: Quiz - each attempt builds on the last

by Peter Malcolm -
In reply to Peter Malcolm

Re: Quiz - each attempt builds on the last

by Jahn Vannisselroy -

Hi guys, wondering if there has been any progress on this - or if you know of an alternative way to show students which answers they got right or wrong on a second attempt?

Cheers from NZ.