]> git.mjollnir.org Git - moodle.git/commitdiff
First drafts of the Number of errors grading strategy
authorDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 17:43:31 +0000 (17:43 +0000)
committerDavid Mudrak <david.mudrak@gmail.com>
Mon, 4 Jan 2010 17:43:31 +0000 (17:43 +0000)
mod/workshop/grading/noerrors/gradingform.php [new file with mode: 0644]
mod/workshop/grading/noerrors/strategy.php [new file with mode: 0644]
mod/workshop/grading/strategy.php
mod/workshop/lang/en_utf8/workshop.php
mod/workshop/settings.php

diff --git a/mod/workshop/grading/noerrors/gradingform.php b/mod/workshop/grading/noerrors/gradingform.php
new file mode 100644 (file)
index 0000000..a59e469
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+// This file is part of Moodle - http://moodle.org/  
+// 
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * This file defines an mform to edit "Number of errors" grading strategy forms.
+ *
+ * @package   mod-workshop
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(dirname(dirname(dirname(__FILE__))).'/lib.php');   // module library
+require_once(dirname(dirname(__FILE__)).'/gradingform.php');    // parent class definition
+
+
+/**
+ * Class for editing "Number of errors" grading strategy forms.
+ *
+ * @uses moodleform
+ */
+class workshop_edit_noerrors_strategy_form extends workshop_edit_strategy_form {
+
+    /**
+     * Define the elements to be displayed at the form 
+     *
+     * Called by the parent::definition()
+     * 
+     * @access protected
+     * @return void
+     */
+    protected function definition_inner(&$mform) {
+
+        $workshopconfig = get_config('workshop');
+        $weights = workshop_get_dimension_weights();
+
+        $repeated = array();
+        $repeated[] =& $mform->createElement('hidden', 'dimensionid', 0);
+        $repeated[] =& $mform->createElement('header', 'dimension', 
+                                                get_string('dimensionnumbernoerrors', 'workshop', '{no}'));
+        $repeated[] =& $mform->createElement('htmleditor', 'description',
+                                                get_string('dimensiondescription', 'workshop'), array());
+        $repeated[] =& $mform->createElement('text', 'grade0', get_string('noerrorsgrade0', 'workshop'), array('size'=>'15'));
+        $repeated[] =& $mform->createElement('text', 'grade1', get_string('noerrorsgrade1', 'workshop'), array('size'=>'15'));
+        $repeated[] =& $mform->createElement('select', 'weight', get_string('dimensionweight', 'workshop'), $weights);
+        
+        $repeatedoptions = array();
+        $repeatedoptions['description']['type'] = PARAM_CLEANHTML;
+        $repeatedoptions['description']['helpbutton'] = array('dimensiondescription', 
+                                                            get_string('dimensiondescription', 'workshop'), 'workshop');
+        $repeatedoptions['grade0']['type'] = PARAM_TEXT;
+        $repeatedoptions['grade0']['default'] = $workshopconfig->noerrorsgrade0;
+        $repeatedoptions['grade1']['type'] = PARAM_TEXT;
+        $repeatedoptions['grade1']['default'] = $workshopconfig->noerrorsgrade1;
+        $repeatedoptions['weight']['default'] = 1;
+
+        $numofdimensionstoadd   = 2;
+        $numofinitialdimensions = 3;
+        $numofdisplaydimensions = max($this->strategy->get_number_of_dimensions() + $numofdimensionstoadd, 
+                                                                                            $numofinitialdimensions);
+        $numofdisplaydimensions = $this->repeat_elements($repeated, $numofdisplaydimensions,  $repeatedoptions, 
+                                                    'numofdimensions', 'adddimensions', $numofdimensionstoadd,
+                                                    get_string('addmoredimensionsnoerrors', 'workshop', $numofdimensionstoadd)); 
+        $mform->addElement('header', 'mappingheader', get_string('noerrorsgrademapping', 'workshop'));
+        $mform->addElement('static', 'mappinginfo', get_string('noerrorsmaperror', 'workshop'), 
+                                                            get_string('noerrorsmapgrade', 'workshop'));
+        $percents = array();
+        $percents[''] = '';
+        for ($i = 100; $i >= 0; $i--) {
+            $percents[$i] = get_string('percents', 'workshop', $i);
+        }
+        $mform->addElement('static', 'mappingzero', 0, get_string('percents', 'workshop', 100)); 
+        $mform->addElement('hidden', 'map[0]', 100);
+        for ($i = 1; $i <= $numofdisplaydimensions; $i++) {
+            $selects = array();
+            $selects[] =& $mform->createElement('select', "map[$i]", $i, $percents);
+            $selects[] =& $mform->createElement('static', "mapdefault[$i]", '', 
+                                        get_string('percents', 'workshop', floor(100 - $i * 100 / $numofdisplaydimensions)));
+            $mform->addGroup($selects, "grademapping$i", $i, array(' '), false);
+            $mform->setDefault("map[$i]", '');
+        }
+
+    }
+
+
+}
diff --git a/mod/workshop/grading/noerrors/strategy.php b/mod/workshop/grading/noerrors/strategy.php
new file mode 100644 (file)
index 0000000..0c97faf
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+// This file is part of Moodle - http://moodle.org/  
+// 
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * This file defines a class with "Number of errors" grading strategy logic
+ *
+ * @package   mod-workshop
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class
+
+
+/**
+ * "Number of errors" grading strategy logic.
+ */
+class workshop_noerrors_strategy extends workshop_base_strategy {
+
+    public function load_grading_form() {
+        global $DB;
+
+        $dims = $DB->get_records('workshop_forms_' . $this->name, array('workshopid' => $this->workshop->id), 'sort');
+        $maps = $DB->get_records('workshop_forms_noerrors_map', array('workshopid' => $this->workshop->id), 'nonegative');
+        $this->nodimensions = count($dims);
+        return $this->_cook_database_records($dims, $maps);
+    }
+
+
+    /**
+     * Transpones the dimension data from DB so the assessment form editor can be populated by set_data
+     *
+     * Called internally from load_grading_form(). Could be private but keeping protected
+     * for unit testing purposes.
+     * 
+     * @param array $dims Array of raw dimension records as fetched by get_record()
+     * @param array $maps Array of grade mappings 
+     * @return array Object to be used by the mform set_data
+     */
+    protected function _cook_database_records(array $dims, array $maps) {
+
+        $formdata = array();
+
+        // cook dimensions
+        $key = 0;
+        foreach ($dims as $dimension) {
+            $formdata['dimensionid[' . $key . ']']       = $dimension->id;
+            $formdata['description[' . $key . ']']       = $dimension->description;
+            $formdata['descriptionformat[' . $key . ']'] = $dimension->descriptionformat;
+            $formdata['grade0[' . $key . ']']            = $dimension->grade0;
+            $formdata['grade1[' . $key . ']']            = $dimension->grade1;
+            $formdata['weight[' . $key . ']']            = $dimension->weight;
+            $key++;
+        }
+
+        // cook grade mappings
+        foreach ($maps as $map) {
+            $formdata['map[' . $map->nonegative . ']'] = $map->grade;
+        }
+
+        return (object)$formdata;
+    }
+
+
+    /**
+     * Save the definition of a "Number of errors" grading form
+     *
+     * The dimensions data are stored in workshop_forms_noerrors. The data that map the
+     * number of errors to a grade are saved into workshop_forms_noerrors_map.
+     *
+     * @uses $DB
+     * @param object $data Raw data returned by the dimension editor form
+     * @return void
+     */
+    public function save_grading_form(stdClass $data) {
+        global $DB;
+
+        if (!isset($data->strategyname) || ($data->strategyname != $this->name)) {
+            // the workshop strategy has changed since the form was opened for editing
+            throw new moodle_exception('strategyhaschanged', 'workshop');
+        }
+
+        // save the dimensions data
+        $dims = $this->_cook_form_data($data);
+        $todelete = array();
+        foreach ($dims as $record) {
+            if (empty($record->description)) {
+                if (!empty($record->id)) {
+                    // existing record with empty description - to be deleted
+                    $todelete[] = $record->id;
+                }
+                continue;
+            }
+            if (empty($record->id)) {
+                // new field
+                $record->id = $DB->insert_record('workshop_forms_' . $this->name, $record);
+            } else {
+                // exiting field
+                $DB->update_record('workshop_forms_' . $this->name, $record);
+            }
+        }
+        // delete dimensions if the teacher removed the description
+        $DB->delete_records_list('workshop_forms_' . $this->name, 'id', $todelete);
+
+        // re-save the mappings
+        $current  = array();
+        $currentx = $DB->get_records('workshop_forms_noerrors_map', array('workshopid' => $this->workshop->id));
+        foreach ($currentx as $id => $map) {
+            $current[$map->nonegative] = $map->grade;
+        }
+        unset($currentx);
+        $todelete = array();
+        
+        foreach ($data->map as $nonegative => $grade) {
+            if ($nonegative == 0) {
+                // no negative response automatically maps to 100%, do not save such mapping
+                continue;
+            }
+            if (!is_numeric($grade)) {
+                // no grade set for this number of negative responses
+                $todelete[] = $nonegative;
+                continue;
+            }
+            if (isset($current[$nonegative])) {
+                $DB->set_field('workshop_forms_noerrors_map', 'grade', $grade,
+                            array('workshopid' => $this->workshop->id, 'nonegative' => $nonegative));
+            } else {
+                $DB->insert_record('workshop_forms_noerrors_map',
+                            (object)array('workshopid' => $this->workshop->id, 'nonegative' => $nonegative, 'grade' => $grade));
+            }
+        }
+        // clear mappings that are not valid any more
+        if (!empty($todelete)) {
+            list($insql, $params) = $DB->get_in_or_equal($todelete);
+            $insql = 'nonegative ' . $insql . ' OR ';
+        } else {
+            list($insql, $params) = array('', array());
+        }
+        $sql = 'DELETE FROM {workshop_forms_noerrors_map} 
+                WHERE ((' . $insql . 'nonegative > ?) AND (workshopid = ?))';
+        $params[] = count($data->map) - 1;
+        $params[] = $this->workshop->id;
+        if (!$DB->execute($sql, $params)){
+            print_error('err_removegrademappings', 'workshop');
+        }
+    }
+
+
+    /**
+     * Prepares dimensions data returned by mform so they can be saved into database
+     *
+     * It automatically adds some columns into every record. The sorting is 
+     * done by the order of the returned array and starts with 1.
+     * Called internally from save_grading_form() only. Could be private but
+     * keeping protected for unit testing purposes.
+     * 
+     * @param object $raw Raw data returned by mform
+     * @return array Array of objects to be inserted/updated in DB
+     */
+    protected function _cook_form_data(stdClass $raw) {
+
+        $cook = array();
+
+        for ($k = 0; $k < $raw->numofdimensions; $k++) {
+            $cook[$k]                    = new stdClass();
+            $cook[$k]->id                = isset($raw->dimensionid[$k]) ? $raw->dimensionid[$k] : null;
+            $cook[$k]->workshopid        = $this->workshop->id;
+            $cook[$k]->sort              = $k + 1;
+            $cook[$k]->description       = isset($raw->description[$k]) ? $raw->description[$k] : null;
+            $cook[$k]->descriptionformat = FORMAT_HTML;
+            $cook[$k]->grade0            = isset($raw->grade0[$k]) ? $raw->grade0[$k] : null;
+            $cook[$k]->grade1            = isset($raw->grade1[$k]) ? $raw->grade1[$k] : null;
+            $cook[$k]->weight            = isset($raw->weight[$k]) ? $raw->weight[$k] : null;
+        }
+        return $cook;
+    }
+
+
+}
index f769ee573424849d1a5bdc5bcc48799c247c0bf9..da2f2172cd4f2e6493448e783135088c280af320 100644 (file)
@@ -150,7 +150,7 @@ abstract class workshop_base_strategy implements workshop_strategy {
      * By default, the number of loaded dimensions is set by load_grading_form() 
      * 
      * @access public
-     * @return void
+     * @return Array of records
      */
     public function get_number_of_dimensions() {
         return $this->nodimensions;
index f3cc64315f7c149653fdb903ff7c24c77dd43e37..3ff68f25b30c54af12335e24c2ed4a24f3560cbf 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
+$string[''] = '';
 $string[''] = '';
 $string[''] = '';
 $string[''] = '';
@@ -36,6 +59,7 @@ $string[''] = '';
 $string[''] = '';
 $string['accesscontrol'] = 'Access control';
 $string['addmoredimensionsaccumulative'] = 'Blanks for $a more aspects';
+$string['addmoredimensionsnoerrors'] = 'Blanks for $a more assertions';
 $string['agreeassessments'] = 'Assessments must be agreed';
 $string['agreeassessmentsdesc'] = 'Authors may comment assessments of their work and agree/disagree with it';
 $string['anonymity'] = 'Anonymity mode';
@@ -62,14 +86,18 @@ $string['configgrade'] = 'Default maximum grade for submission in workshops';
 $string['configgradinggrade'] = 'Default maximum grade for assessment in workshops';
 $string['configmaxbytes'] = 'Default maximum submission file size for all workshops on the site (subject to course limits and other local settings)';
 $string['confignexassessments'] = 'Default number of examples to be reviewed by a user in the example assessment phase';
+$string['confignoerrorsgrade0'] = 'The default word describing the negative assessment of an assertion in "Number of errors" grading strategy.';
+$string['confignoerrorsgrade1'] = 'The default word describing the positive assessment of an assertion in "Number of errors" grading strategy.';
 $string['confignsassessments'] = 'Default number of allocated submissions to be reviewed by a user in the assessment phase';
 $string['configstrategy'] = 'Default grading strategy for workshops';
 $string['dimensiondescription'] = 'Description';
 $string['dimensionnumberaccumulative'] = 'Aspect $a';
+$string['dimensionnumbernoerrors'] = 'Assertion $a';
 $string['dimensionweight'] = 'Weight';
 $string['editgradingform'] = 'Edit grading form';
 $string['editinggradingform'] = 'Editing grading form';
 $string['editingsubmission'] = 'Editing submission';
+$string['err_removegrademappings'] = 'Unable to remove the unused grade mappings';
 $string['examplesbeforeassessment'] = 'Examples are available after own submission and must be assessed before peer/self assessment phase';
 $string['examplesbeforesubmission'] = 'Examples must be assessed before own submission';
 $string['examplesmode'] = 'Mode of examples assessment';
@@ -87,14 +115,22 @@ $string['modulenameplural'] = 'Workshops';
 $string['modulename'] = 'Workshop';
 $string['nattachments'] = 'Maximum number of submission attachments';
 $string['nexassessments'] = 'Number of required assessments of examples';
+$string['noerrorsgrademapping'] = 'Grade mapping table';
+$string['noerrorsgrade0default'] = 'No';
+$string['noerrorsgrade0'] = 'Word for the error';
+$string['noerrorsgrade1default'] = 'Yes';
+$string['noerrorsgrade1'] = 'Word for the success';
+$string['noerrorsmaperror'] = 'Number of errors is less than or equals';
+$string['noerrorsmapgrade'] = 'Grade for submission';
 $string['nsassessments'] = 'Number of required assessments of other users\' work';
+$string['percents'] = '$a%';
 $string['releasegrades'] = 'Push final grades into the gradebook';
 $string['requirepassword'] = 'Require password';
 $string['saveandclose'] = 'Save and close';
 $string['saveandcontinue'] = 'Save and continue editing';
 $string['strategyaccumulative'] = 'Accumulative grading';
-$string['strategyerrorbanded'] = 'Error banded grading';
 $string['strategy'] = 'Grading strategy';
+$string['strategynoerrors'] = 'Number of errors';
 $string['strategynograding'] = 'No grading';
 $string['strategyrubric'] = 'Rubric grading';
 $string['submissionattachment'] = 'Attachment';
index 24675bf6a71d5f09a145f2a026440ca8b51853eb..7a6f127cb6e370e40fc69a47e8247379fcafa832 100644 (file)
@@ -70,6 +70,14 @@ foreach (workshop_get_comparison_levels() as $code => $level) {
 $settings->add(new admin_setting_configselect('workshop/assessmentcomps', get_string('assessmentcomps', 'workshop'),
                     get_string('configassessmentcomps', 'workshop'), WORKSHOP_COMPARISON_NORMAL, $levels));
 
+$settings->add(new admin_setting_configtext('workshop/noerrorsgrade0', get_string('noerrorsgrade0', 'workshop'), 
+                    get_string('confignoerrorsgrade0', 'workshop'), get_string('noerrorsgrade0default', 'workshop'),
+                    $paramtype=PARAM_TEXT, $size=15));
+
+$settings->add(new admin_setting_configtext('workshop/noerrorsgrade1', get_string('noerrorsgrade1', 'workshop'), 
+                    get_string('confignoerrorsgrade1', 'workshop'), get_string('noerrorsgrade1default', 'workshop'),
+                    $paramtype=PARAM_TEXT, $size=15));
+
 /*
 $settings->add(new admin_setting_configcheckbox('assignment_showrecentsubmissions', get_string('showrecentsubmissions', 'assignment'),
                    get_string('configshowrecentsubmissions', 'assignment'), 1));