Question usages and deferred feedback

Question usages and deferred feedback

by Richard Jones -
Number of replies: 4
Picture of Plugin developers Picture of Testers

When a question is processed under adaptive and immediate feedback, the processed responses are available via the question usages object.  

When an essay question is used, the raw response can also be obtained by adding a submit button to the question form and using method extract_responses.

However, when deferred feedback is used, the response data does not appear in the usages object when a submit button is added to the form.  Where does it go or how do you force the processing?  

I'm currently using plugin module tables to store the results for subsequent review so would like to store them once the question is answered.  I would also like to have the data available to be potentially used for subsequent page branching.

Relevant code is here: 

https://github.com/richardjonesnz/moodle_mod_simplelesson/blob/question_branching/showpage.php

Any pointers gratefully accepted.

Average of ratings: -
In reply to Richard Jones

Re: Question usages and deferred feedback

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

The responses are always stored in the question usage object and related database tables. What are you doing (which methods are you calling) that make you think that is not the case?

I see, you are using $quba->get_response_summary($slot); - well, that is not really 'the response', it is 'a textual summary of the response, for reporting'. The point is that you really have no idea what different question types might be doing, and whether it is sensible to represnt the response as a string (e.g. drag-drop markers). Only the invididual question type can really show the reponse - by rendering the question.

Actually, looking at your code, you seem to be duplicating a lot of the data that the question system already stores for you. If I was writing this code, I would not store most of the information that you put in $answerdata. I would just get the data from the question_usage whenever you need it.


In reply to Tim Hunt

Re: Question usages and deferred feedback

by Richard Jones -
Picture of Plugin developers Picture of Testers

Hi Tim

Thanks for your quick response.  

I'm storing the data within my plugin for reporting and for manual grading of essay questions in a separate process and removing the data from the questions_usages, questions_attempts and associated step tables afterwards (at the end of the activity).  I think that it also makes it easier to implement privacy requirements if I have all the data and none is in the the usages and related tables.

I permit adaptive and immediate behaviours and, when the check button on the form is clicked, the data is transferred into those usage tables, so far so good.   There was a problem with saving essay data so I've added a button to allow that to be saved multiple times.

However, deferred feedback does not offer a button on the form so I've supplied a submit button in the renderer code.

public function render_question_form(
            $actionurl, $options, $slot, $quba,
            $starttime, $qtype, $behaviour) {
        $html = html_writer::start_div('mod_simplelesson_question');
        $headtags = '';
        $headtags .= $quba->render_question_head_html($slot);
        // Start the question form.
        $html .= html_writer::start_tag('form',
                array('method' => 'post', 'action' => $actionurl,
                'enctype' => 'multipart/form-data',
                'accept-charset' => 'utf-8',
                'id' => 'responseform'));
        $this->page->requires->js_init_call('M.core_question_engine.init_form',
        array('#responseform'), false, null);
        $html .= html_writer::start_tag('div');
        $html .= html_writer::empty_tag('input',
                array('type' => 'hidden',
                'name' => 'sesskey', 'value' => sesskey()));
        $html .= html_writer::empty_tag('input',
                array('type' => 'hidden',
                'name' => 'slots', 'value' => $slot));
        $html .= '<input type="hidden" name="scrollpos" value="" />';
        $html .= html_writer::empty_tag('input',
                array('type' => 'hidden',
                'name' => 'starttime', 'value' => $starttime));
        $html .= html_writer::end_tag('div');
        // Output the question. slot = display number.
        $html .= $quba->render_question($slot, $options);
        // If it's an essay question, output a save button.
        // If it's deferred feedback add a save button.
        if ( ($qtype == 'essay') || ($behaviour == 'deferredfeedback') ) {
            $html .= html_writer::start_div(
                    'mod_simplelesson_save_button');
            $html .= $this->output->single_button($actionurl,
                    get_string('saveanswer', 'mod_simplelesson'));
            $html .= html_writer::end_div();
        }
        // Finish the question form.
        $html .= html_writer::start_tag(
                'mod_simplelesson_action_buttons');
        $html .= html_writer::end_tag('div');
        $html .= html_writer::end_tag('form');
        $html .= html_writer::end_div('div');
        return $html;
    }  

This submit button works for the essay question but doesn't cause any usage data to be stored for deferred feedback.  Clearly I'm missing some important processing step. 

I wanted to report the student responses for later review and I had intended to cover the main question types, t/f, multiple choice, fill blanks, matching and essay.  I have not yet thought about D&D and so on.  The original intent was simplification (for teachers) as quiz/lesson already offer pretty comprehensive alternatives.

In reply to Richard Jones

Re: Question usages and deferred feedback

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 a $quba->can_question_finish_during_attempt($slot) method, which is probably a better thing to use rather than hard-coding qtype and behaviour names.

If a question does not finish on its own, then you should probably call $quba->finish_question($slot) to finalise things before you try to extract the data.

Privacy is not a valid reason for not using the question engine to store the data about question attempts. The quiz manges just find. https://github.com/moodle/moodle/blob/master/mod/quiz/classes/privacy/provider.php#L115, https://github.com/moodle/moodle/blob/master/mod/quiz/classes/privacy/provider.php#L135, https://github.com/moodle/moodle/blob/master/mod/quiz/classes/privacy/provider.php#L367, etc.

Average of ratings: Useful (1)