~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to question/behaviour/behaviourbase.php

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
/**
18
 
 * Defines the quetsion behaviour base class
 
18
 * Defines the question behaviour base class
19
19
 *
20
20
 * @package    moodlecore
21
21
 * @subpackage questionbehaviours
40
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
41
 */
42
42
abstract class question_behaviour {
43
 
    /**
44
 
     * Certain behaviours are definitive of a  way that questions can
45
 
     * behave when attempted. For example deferredfeedback model, interactive
46
 
     * model, etc. These are the options that should be listed in the
47
 
     * user-interface. These models should define the class constant
48
 
     * IS_ARCHETYPAL as true. Other models are more implementation details, for
49
 
     * example the informationitem model, or a special subclass like
50
 
     * interactive_adapted_for_my_qtype. These models should IS_ARCHETYPAL as
51
 
     * false.
52
 
     * @var boolean
53
 
     */
54
 
    const IS_ARCHETYPAL = false;
55
43
 
56
44
    /** @var question_attempt the question attempt we are managing. */
57
45
    protected $qa;
 
46
 
58
47
    /** @var question_definition shortcut to $qa->get_question(). */
59
48
    protected $question;
60
49
 
85
74
     *
86
75
     * @param question_definition $question the question.
87
76
     */
88
 
    public function is_compatible_question(question_definition $question) {
89
 
        $requiredclass = $this->required_question_definition_type();
90
 
        return $this->question instanceof $requiredclass;
91
 
    }
92
 
 
93
 
    /**
94
 
     * Most behaviours can only work with {@link question_definition}s
95
 
     * of a particular subtype, or that implement a particular interface.
96
 
     * This method lets the behaviour document that. The type of
97
 
     * question passed to the constructor is then checked against this type.
98
 
     *
99
 
     * @deprecated since 2.2. Please use/override {@link is_compatible_question()} instead.
100
 
     *
101
 
     * @return string class/interface name.
102
 
     */
103
 
    protected function required_question_definition_type() {
104
 
        return 'question_definition';
105
 
    }
 
77
    public abstract function is_compatible_question(question_definition $question);
106
78
 
107
79
    /**
108
80
     * @return string the name of this behaviour. For example the name of
113
85
    }
114
86
 
115
87
    /**
116
 
     * 'Override' this method if there are some display options that do not make
117
 
     * sense 'during the attempt'.
118
 
     * @return array of {@link question_display_options} field names, that are
119
 
     * not relevant to this behaviour before a 'finish' action.
120
 
     */
121
 
    public static function get_unused_display_options() {
122
 
        return array();
123
 
    }
124
 
 
125
 
    /**
126
88
     * Cause the question to be renderered. This gets the appropriate behaviour
127
89
     * renderer using {@link get_renderer()}, and adjusts the display
128
90
     * options using {@link adjust_display_options()} and then calls
198
160
    /**
199
161
     * What is the minimum fraction that can be scored for this question.
200
162
     * Normally this will be based on $this->question->get_min_fraction(),
201
 
     * but may be modified in some way by the model.
 
163
     * but may be modified in some way by the behaviour.
202
164
     *
203
165
     * @return number the minimum fraction when this question is attempted under
204
 
     * this model.
 
166
     * this behaviour.
205
167
     */
206
168
    public function get_min_fraction() {
207
169
        return 0;
208
170
    }
209
171
 
210
172
    /**
211
 
     * Adjust a random guess score for a question using this model. You have to
212
 
     * do this without knowing details of the specific question, or which usage
213
 
     * it is in.
214
 
     * @param number $fraction the random guess score from the question type.
215
 
     * @return number the adjusted fraction.
 
173
     * Return the maximum possible fraction that can be scored for this question.
 
174
     * Normally this will be based on $this->question->get_max_fraction(),
 
175
     * but may be modified in some way by the behaviour.
 
176
     *
 
177
     * @return number the maximum fraction when this question is attempted under
 
178
     * this behaviour.
216
179
     */
217
 
    public static function adjust_random_guess_score($fraction) {
218
 
        return $fraction;
 
180
    public function get_max_fraction() {
 
181
        return $this->question->get_max_fraction();
219
182
    }
220
183
 
221
184
    /**
229
192
            return array();
230
193
        }
231
194
 
232
 
        $vars = array('comment' => PARAM_RAW);
 
195
        $vars = array('comment' => PARAM_RAW, 'commentformat' => PARAM_INT);
233
196
        if ($this->qa->get_max_mark()) {
234
197
            $vars['mark'] = question_attempt::PARAM_MARK;
235
198
            $vars['maxmark'] = PARAM_FLOAT;
318
281
    }
319
282
 
320
283
    /**
321
 
     * @return array subpartid => object with fields
322
 
     *      ->responseclassid matches one of the values returned from
323
 
     *                        quetion_type::get_possible_responses.
324
 
     *      ->response the actual response the student gave to this part, as a string.
325
 
     *      ->fraction the credit awarded for this subpart, may be null.
326
 
     *      returns an empty array if no analysis is possible.
 
284
     * @return question_possible_response[] where keys are subpartid or an empty array if no classification is possible.
327
285
     */
328
286
    public function classify_response() {
329
287
        return $this->question->classify_response($this->qa->get_last_qt_data());
486
444
                            $pendingstep->get_behaviour_var('maxmark');
487
445
            if ($pendingstep->get_behaviour_var('mark') === '') {
488
446
                $fraction = null;
489
 
            } else if ($fraction > 1 || $fraction < $this->qa->get_min_fraction()) {
 
447
            } else if ($fraction > $this->qa->get_max_fraction() || $fraction < $this->qa->get_min_fraction()) {
490
448
                throw new coding_exception('Score out of range when processing ' .
491
449
                        'a manual grading action.', 'Question ' . $this->question->id .
492
450
                                ', slot ' . $this->qa->get_slot() . ', fraction ' . $fraction);
500
458
    }
501
459
 
502
460
    /**
503
 
     * Validate that the manual grade submitted for a particular question is in range.
504
 
     * @param int $qubaid the question_usage id.
505
 
     * @param int $slot the slot number within the usage.
506
 
     * @return bool whether the submitted data is in range.
507
 
     */
508
 
    public static function is_manual_grade_in_range($qubaid, $slot) {
509
 
        $prefix = 'q' . $qubaid . ':' . $slot . '_';
510
 
        $mark = question_utils::optional_param_mark($prefix . '-mark');
511
 
        $maxmark = optional_param($prefix . '-maxmark', null, PARAM_FLOAT);
512
 
        $minfraction = optional_param($prefix . ':minfraction', null, PARAM_FLOAT);
513
 
        return is_null($mark) || ($mark >= $minfraction * $maxmark && $mark <= $maxmark);
514
 
    }
515
 
 
516
 
    /**
517
461
     * @param $comment the comment text to format. If omitted,
518
462
     *      $this->qa->get_manual_comment() is used.
519
463
     * @param $commentformat the format of the comment, one of the FORMAT_... constants.
684
628
 
685
629
/**
686
630
 * This helper class contains the constants and methods required for
687
 
 * manipulating scores for certainly based marking.
 
631
 * manipulating scores for certainty based marking.
688
632
 *
689
633
 * @copyright  2009 The Open University
690
634
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
699
643
    /** @var array list of all the certainty levels. */
700
644
    public static $certainties = array(self::LOW, self::MED, self::HIGH);
701
645
 
702
 
    /**#@+ @var array coefficients used to adjust the fraction based on certainty.. */
703
 
    protected static $factor = array(
704
 
        self::LOW => 0.333333333333333,
705
 
        self::MED => 1.333333333333333,
 
646
    /**#@+ @var array coefficients used to adjust the fraction based on certainty. */
 
647
    protected static $rightscore = array(
 
648
        self::LOW  => 1,
 
649
        self::MED  => 2,
706
650
        self::HIGH => 3,
707
651
    );
708
 
    protected static $offset = array(
709
 
        self::LOW => 0,
710
 
        self::MED => -0.666666666666667,
711
 
        self::HIGH => -2,
 
652
    protected static $wrongscore = array(
 
653
        self::LOW  =>  0,
 
654
        self::MED  => -2,
 
655
        self::HIGH => -6,
 
656
    );
 
657
    /**#@-*/
 
658
 
 
659
    /**#@+ @var array upper and lower limits of the optimal window. */
 
660
    protected static $lowlimit = array(
 
661
        self::LOW  => 0,
 
662
        self::MED  => 0.666666666666667,
 
663
        self::HIGH => 0.8,
 
664
    );
 
665
    protected static $highlimit = array(
 
666
        self::LOW  => 0.666666666666667,
 
667
        self::MED  => 0.8,
 
668
        self::HIGH => 1,
712
669
    );
713
670
    /**#@-*/
714
671
 
721
678
    }
722
679
 
723
680
    /**
724
 
     * Given a fraction, and a certainly, compute the adjusted fraction.
 
681
     * Given a fraction, and a certainty, compute the adjusted fraction.
725
682
     * @param number $fraction the raw fraction for this question.
726
 
     * @param int $certainty one of the certainly level constants.
727
 
     * @return number the adjusted fraction taking the certainly into account.
 
683
     * @param int $certainty one of the certainty level constants.
 
684
     * @return number the adjusted fraction taking the certainty into account.
728
685
     */
729
686
    public static function adjust_fraction($fraction, $certainty) {
730
 
        return self::$offset[$certainty] + self::$factor[$certainty] * $fraction;
 
687
        if ($certainty == -1) {
 
688
            // Certainty -1 has never been used in standard Moodle, but is
 
689
            // used in Tony-Gardiner Medwin's patches to mean 'No idea' which
 
690
            // we intend to implement: MDL-42077. In the mean time, avoid
 
691
            // errors for people who have used TGM's patches.
 
692
            return 0;
 
693
        }
 
694
        if ($fraction <= 0.00000005) {
 
695
            return self::$wrongscore[$certainty];
 
696
        } else {
 
697
            return self::$rightscore[$certainty] * $fraction;
 
698
        }
731
699
    }
732
700
 
733
701
    /**
734
702
     * @param int $certainty one of the LOW/MED/HIGH constants.
735
 
     * @return string a textual desciption of this certainly.
 
703
     * @return string a textual description of this certainty.
736
704
     */
737
705
    public static function get_string($certainty) {
738
706
        return get_string('certainty' . $certainty, 'qbehaviour_deferredcbm');
739
707
    }
740
708
 
 
709
    /**
 
710
     * @param int $certainty one of the LOW/MED/HIGH constants.
 
711
     * @return string a short textual description of this certainty.
 
712
     */
 
713
    public static function get_short_string($certainty) {
 
714
        return get_string('certaintyshort' . $certainty, 'qbehaviour_deferredcbm');
 
715
    }
 
716
 
 
717
    /**
 
718
     * Add information about certainty to a response summary.
 
719
     * @param string $summary the response summary.
 
720
     * @param int $certainty the level of certainty to add.
 
721
     * @return string the summary with information about the certainty added.
 
722
     */
741
723
    public static function summary_with_certainty($summary, $certainty) {
742
724
        if (is_null($certainty)) {
743
725
            return $summary;
744
726
        }
745
 
        return $summary . ' [' . self::get_string($certainty) . ']';
 
727
        return $summary . ' [' . self::get_short_string($certainty) . ']';
 
728
    }
 
729
 
 
730
    /**
 
731
     * @param int $certainty one of the LOW/MED/HIGH constants.
 
732
     * @return float the lower limit of the optimal probability range for this certainty.
 
733
     */
 
734
    public static function optimal_probablility_low($certainty) {
 
735
        return self::$lowlimit[$certainty];
 
736
    }
 
737
 
 
738
    /**
 
739
     * @param int $certainty one of the LOW/MED/HIGH constants.
 
740
     * @return float the upper limit of the optimal probability range for this certainty.
 
741
     */
 
742
    public static function optimal_probablility_high($certainty) {
 
743
        return self::$highlimit[$certainty];
746
744
    }
747
745
}