Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Grades: Difference between revisions

From MoodleDocs
m (Text replacement - "class="nicetable"" to "class="wikitable"")
 
(258 intermediate revisions by 17 users not shown)
Line 1: Line 1:
>>Still under construction<<
{{Work in progress}}


[http://moodle.org/mod/forum/discuss.php?d=69223 There is an ongoing discussion about this spec here]
== Executive Summary ==


== Executive Summary ==
This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see [[Gradebook_improvements]]


The gradebook mechanisms must be rebuilt to:
The gradebook mechanisms must be rebuilt to:


# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.
# '''Improve performance and scalability''' - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing special-purpose reports analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.
# '''Improve flexibility''' - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing [[Gradebook Report Tutorial |special-purpose reports]] analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.
# '''Allow rubrics for outcomes (aka standards,competencies,goals)''' - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.
# '''Implement an event-oriented architecture''' - Such an architecture allows all parts of Moodle to interact with the gradebook, but particularly gradebook plugins can react instantly to grading events throughout the system.
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.
# '''Allow arbitrary columns and derived columns''' - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.
# '''Implement limited public API''' - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.


== Glossary ==
== Glossary ==


Here is a list of terms used in the gradebook and its closely associated Moodle elements. It contains terms used in development and in its user interface. We hope this will help to reduce confusion with generic terms that may be used elsewhere in Moodle. Please add to this glossary as needed.
Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.


{| border="1" cellpadding="2" cellspacing="0"
{| class="wikitable"
|'''Term'''
!Term
|'''Definition'''
!Definition
|-
|-
|Activity
|Activity
|An activity module (e.g. quiz, assignment etc...)
|An instance of an activity module [[Category:Modules|Module]] (e.g. a single quiz, assignment etc...)
|-
|-
|Calculation
|Calculation
|A formula used to calculate grades, based (optionally) on other grade items.
|A formula used to calculate grades, based (optionally) on other grade items. Not the same as [[Calculated_question_type|Calculated question types]].
|-
|-
|Category
|Category
|A set of Grade Items. A category also has its own grade, which may be an aggregation of the grades stored by its child grade items, or an arbitrary grade. There is no limit to the level of nesting of categories (a Category may belong to another Category). However, each Grade Item may belong to only 1 (one) Category.
|A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category.
|-
|Course completion
|The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.
|-
|Grade
|A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.
|-
|[[Gradebook|Gradebook]]
|A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.
|-
|-
|Grade Item
|Grade Item
|An entity representing a specific score/grade. It may be drawn directly from an Activity, calculated from other Grade Items, or even arbitrarily determined. A Grade Item holds the following data:
|A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.
#Optional links to Category, Scale and Outcome
|-
#Rules for upper and lower limits, and weighting
|[[Grades#Locked_grades|Grade Locks]]
#Info pushed in by the Activity (if Grade Item comes from an Activity)
|See linked section of this page
|-
|-
|History
|History
|The gradebook as its own type of log, which keeps a History of all changes made to grades.
|The gradebook has its own type of log, which keeps a History of all changes made to grades.
|-
|-
|Outcome
|[[Outcomes|Outcome]]
|A grade isn't always the best indication of a person's mastery of the subject matter. Outcomes are specific descriptions of what a person is expected to be able to do or understand at the completion of the activity/course. They are usually given at the beginning of the course to help learners to stay focused on the learning experience instead of just the grades. Another term for Outcome is ''Competency''.
|[[Outcomes|Outcomes]] are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are ''Competencies'' and ''Goals''. See some [[Outcomes_examples|Examples]].
|-
|-
|Scale
|[[Scales|Scale]]
|
|A scale is a set of responses from which the teacher can choose one.  eg  Very cool, Cool, Fairly cool, Not very cool, Not cool
|-
|Letter Grades
|Special representation of grade values similar to scales.  Letters are configured in course contexts or above and are defined by lower boundary.  eg  A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)
 
|}
|}


Line 49: Line 62:
=== grade_items ===
=== grade_items ===


This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes or numerical grades), then there will be a corresponding multiple number of rows in this table.
This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.
 
idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations.  It is the same as the idnumber in course_modules.
 


{| border="1" cellpadding="2" cellspacing="0"
{| border="1" cellpadding="2" cellspacing="0"
Line 60: Line 76:
|int(10)   
|int(10)   
|
|
|autoincrementing  
|autoincrementing  
|-
|-
Line 66: Line 81:
|int(10)   
|int(10)   
|
|
|The course this item is part of  
|The course this item is part of  
|-
|-
Line 72: Line 86:
|int(10)   
|int(10)   
|<center>NULL</center>  
|<center>NULL</center>  
|(optional) the category group this item belongs to  
|the category group this item belongs to  
|-
|-
|itemname  
|itemname  
|varchar(255)  
|varchar(255)  
|
|<center>NULL</center>
|The name of this item (pushed in by the module or entered by user)  
|The name of this item (pushed in by the module)  
|-
|-
|itemtype  
|'''itemtype'''
|varchar(30)  
|varchar(30)  
|
|
|'mod', 'blocks', 'manual', 'course', 'category' etc  
|'mod', 'blocks', 'import', 'calculated' etc  
|-
|-
|itemmodule   
|itemmodule   
|varchar(30)   
|varchar(30)   
|
|<center>NULL</center>
|'forum', 'quiz', 'csv', etc  
|'forum', 'quiz', 'csv', etc  
|-
|-
|iteminstance  
|iteminstance  
|int(10)  
|int(10)  
|
|<center>NULL</center>
|id of the item module  
|id of the item module  
|-
|-
Line 105: Line 115:
|iteminfo  
|iteminfo  
|text  
|text  
|
|<center>NULL</center>
|Info and notes about this item XXX  
|Info and notes about this item XXX  
|-
|-
|idnumber  
|'''idnumber'''
|varchar(255)  
|varchar(255)  
|<center>NULL</center>  
|<center>NULL</center>  
|Arbitrary idnumber provided by the module responsible  
|Arbitrary idnumber provided by the module responsible (optional and course unique)
|-
|-
|gradetype  
|calculation
|text
|<center>NULL</center>
|Spreadsheet-type formula used to process the raw grades into final grades
|-
|'''gradetype'''
|int(4)  
|int(4)  
|<center>0</center>  
|<center>1</center>  
|0 = value, 1 = scale, 2 = text  
|0 = none, 1 = value, 2 = scale, 3 = text  
|-
|-
|grademax  
|grademax  
|float(11,10)  
|float(10,5)  
|<center>100</center>  
|<center>100</center>  
|What is the maximum allowable grade?  
|What is the maximum allowable grade?  
|-
|-
|grademin  
|grademin  
|float(11,10)  
|float(10,5)  
|<center>0</center>  
|<center>0</center>  
|What is the minimum allowable grade?  
|What is the minimum allowable grade?  
Line 137: Line 151:
|int(10)  
|int(10)  
|<center>NULL</center>  
|<center>NULL</center>  
|If this grade is related to an outcome, which one is it?  
|If this is outcome item, which outcome is it?  
|-
|-
|gradepass
|gradepass
|float(11,10)  
|float(10,5)  
|<center>0</center>  
|<center>0</center>  
|What grade is needed to pass?  grademin < gradepass <= grademax
|What grade is needed to pass?  grademin <= gradepass <= grademax
|-
|-
|multfactor  
|multfactor  
|float(11,10)  
|float(10,5)  
|<center>1.0</center>  
|<center>1.0</center>  
|Multiply all grades by this  
|Multiply all raw grades from activities by this  
|-
|-
|plusfactor   
|plusfactor   
|float(11,10)  
|float(10,5)
|<center>0.0</center>
|Add this to all raw grades from activities by this
|-
|aggregationcoef 
|float(10,5)  
|<center>0.0</center>  
|<center>0.0</center>  
|Add this to all grades  
|Weight applied to all grades in this grade item during aggregation with other grade items.
|-
|-
|sortorder  
|sortorder  
|int(10)   
|int(10)   
|<center>0</center>  
|<center>0</center>  
|Sorting order of the columns  
|Sorting order of the columns (pre-order walk of the grading tree)
|-
|display
|int(10) 
|<center>0</center>
|Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)
|-
|-
|hidden  
|hidden  
|int(10)  
|int(10)  
|<center>0</center>  
|<center>0</center>  
|1 is hidden, > 1 is a date to hide until (prevents viewing)  
|1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades)  
|-
|-
|locked  
|'''locked'''
|int(10)  
|int(10)  
|<center>0</center>  
|<center>0</center>  
|1 is locked, > 1 is a date to lock until (prevents update)  
|0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)
 
|-
|'''locktime'''
|int(10)  
|<center>0</center>
|0 no auto locking, > 0 is a date to lock grade item and final grades after automatically
|-
|-
|needsupdate  
|'''needsupdate'''
|int(10)  
|int(10)  
|<center>0</center>  
|<center>0</center>  
|If this flag is set, then the whole column will be recalculated
|If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.
 
|-
|-
|timecreated  
|timecreated  
Line 180: Line 207:
|
|
|The first time this grade_item was created
|The first time this grade_item was created
|-
|-
|timemodified  
|timemodified  
Line 190: Line 216:
=== grade_categories ===
=== grade_categories ===


This table keeps information about categories, used for grouping items.
This table keeps information about categories, used for grouping items.  An associated grade_item will be maintained for each category to store the aggregate data.


{| border="1" cellpadding="2" cellspacing="0"
{| border="1" cellpadding="2" cellspacing="0"
Line 201: Line 227:
|int(10)   
|int(10)   
|
|
|autoincrementing  
|autoincrementing  
|-
|-
Line 207: Line 232:
|int(10)   
|int(10)   
|
|
|The course this grade category is part of  
|The course this grade category is part of  
|-
|-
|'''categoryid'''  
|'''parent'''  
|int(10)  
|int(10)  
|<center>NULL</center>  
|<center>NULL</center>  
|Categories can be hierarchical   
|Parent grade_category (hierarchical)
|-
|depth
|int(10)
|<center>0</center>
|How deep is this category from the highest level (1,2,3)
|-
|path
|varchar(255)
|
|Shows the path as /1/2/3/  
|-
|-
|fullname  
|fullname  
|varchar(255)  
|varchar(255)  
|
|
|The name of this grade category  
|The name of this grade category  
|-
|-
Line 236: Line 269:
|Drop the X lowest items  
|Drop the X lowest items  
|-
|-
|multfactor
|aggregateonlygraded
|float(11,10)
|int(1)  
|<center>1.0</center>
|<center>0</center>  
|multiply total grade by this
|Aggregate only existing grades
|-
|plusfactor 
|float(11,10)  
|<center>0.0</center>  
|add this to total grade
|-
|-
|gradepass
|aggregateoutcomes
|float(11,10)  
|int(1)  
|<center>0</center>  
|<center>0</center>  
|What final grade needs to be achieved to pass this item?
|Aggregate otcomes together with normal items
|-
|-
|hidden
|aggregatesubcats
|int(10)  
|int(1)  
|<center>0</center>  
|<center>0</center>  
|1 is hidden, > 1 is a date to hide until
|Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals
|}
 
=== grade_calculations ===
 
This table describes the calculated grade_items in more details.
 
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''
|-
|'''id'''
|int(10) 
|
|autoincrementing
|-
|'''itemid'''
|int(10) 
|
|The grade_item this relates to
|-
|'''calculation'''
|text
|<center>NULL</center>
|Formula describing how to derive this grade from other items, referring to them using [idnumber] ... eg something like:sin(square([XXXXX])) + [YYYY]
|-
|-
|timecreated
|timecreated
|int(10)  
|int(10)  
|
|
|the time this calculation was first created  
|The first time this grade_category was created
|-
|-
|timemodified
|timemodified  
|int(10)  
|int(10)  
|
|
|the time this calculation was last modified  
|The last time this grade_category was modified
|-
|-
|'''usermodified'''
|hidden
|int(10)  
|int(1)  
|<center>0</center>
|
|
|the userid of the person who last modified this calculation
|}


|}
=== grade_grades ===


=== grade_grades_raw ===
This table keeps individual grades for each user and each item.  The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity!  All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item.  The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.


This table keeps individual grades for each user and each item, exactly as imported or submitted by modules. The grademax/min and scaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled for the grade_grades_final table.
Note that the finalgrade for a scale-based item may be non-integer!  It needs to be rounded on display.


{| border="1" cellpadding="2" cellspacing="0"
{| border="1" cellpadding="2" cellspacing="0"
Line 324: Line 327:
|The user who this grade is for  
|The user who this grade is for  
|-
|-
|gradevalue 
|rawgrade
|float(11,10)  
|float(11,10)  
|<center>NULL</center>  
|<center>NULL</center>  
|If the grade is a float value (or has been converted to one)
|The raw grade that came into the system
|-
|gradescale
|int(10)
|<center>NULL</center>
|If the grade is a scale value
|-
|-
|grademax
|rawgrademax
|float(11,10)  
|float(11,10)  
|<center>100</center>  
|<center>100</center>  
|The maximum allowable grade when this was created  
|The maximum allowable grade when this was created  
|-
|-
|grademin
|rawgrademin
|float(11,10)  
|float(11,10)  
|<center>0</center>  
|<center>0</center>  
|The maximum allowable grade when this was created  
|The minimum allowable grade when this was created  
|-
|-
|'''scaleid'''  
|'''rawscaleid'''  
|int(10)  
|int(10)  
|<center>NULL</center>  
|<center>NULL</center>  
|If this grade is based on a scale, which one was it?  
|If this grade is based on a scale, which one was it?  
|-
|timecreated
|int(10)
|
|the time this grade was first created
|-
|timemodified
|int(10)
|
|the time this grade was last modified
|-
|-
|'''usermodified'''
|'''usermodified'''
|int(10)  
|int(10)  
|
|<center>NULL</center>
|the userid of the person who last modified this grade
|the userid of the person who last modified the raw grade value
|}
 
=== grade_grades_final ===
 
This table keeps individual grades for each user and each item/category– they have undergone all scaling and other calculations, and are ready for display. This table is effectively a cache and values are rebuilt whenever source values change. The gradevalue or gradescale values are all normalised to the max/min or scaleid as defined in the grade_item table.
 
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''
|-
|-
|'''id'''
|finalgrade
|int(10) 
|
|autoincrementing
|-
|'''columnid'''
|int(10) 
|
|'''itemid or categoryid'''
|-
|'''columntype'''
|enum
|
|'category' or 'item'
|-
|'''userid'''
|int(10)
|
|The user who this grade is for
|-
|gradevalue 
|float(11,10)  
|float(11,10)  
|<center>NULL</center>  
|<center>NULL</center>  
|If the grade is a float value (or has been converted to one)
|The final grade (cached) after all calculations are made. Overriden grades are also stored here.
|-
|hidden
|int(10)
|<center>0</center>
|0 is not hidden, 1 is hide always, > 1 is a date to hide until
|-
|-
|gradescale
|'''locked'''
|int(10)  
|int(10)  
|<center>NULL</center>  
|<center>0</center>  
|If the grade is a scale value
|0 is not locked, > 0 when was the grade locked
|-
|-
|hidden
|'''locktime'''
|int(10)  
|int(10)  
|<center>0</center>  
|<center>0</center>  
|1 is hidden, > 1 is a date to hide until
|0 is never, > 0 is a date to lock the final grade after automatically
|-
|-
|exported  
|exported  
|int(10)  
|int(10)  
|<center>0</center>  
|<center>0</center>  
|0 is not exported, > 1 is the last exported date  
|0 is not exported, > 0 is the last exported date  
|-
|-
|timecreated
|excluded
|int(10)  
|int(10)  
|
|<center>0</center>
|the time this grade was first created
|grade excluded from aggregation, > 0 is the last excluded date
|-
|-
|timemodified
|overridden
|int(10)  
|int(10)  
|
|<center>0</center>
|the time this grade was last modified
|0 is not overridden, > 0 is the last overridden date
|-
|-
|'''usermodified'''
|feedback
|int(10)
|text
|NULL
|<center>NULL</center>
|the userid of the person who last modified this grade
|Manual feedback from the teacher. Could be a code like 'mi'.  
|}
 
=== grade_grades_text ===
 
This table keeps additional textual information about each individual grade, whether it be automatically generated from the module or entered manually by the teacher. It's here separate from the all-numeric grade_grades for database efficiency reasons.
 
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''
|-
|-
|'''id'''
|feedbackformat
|int(10)
|int(10)
|
|<center>0</center>
|Text format for feedback
|autoincrementing
|-
|'''gradesid'''
|int(10) 
|
|The exact grade in grade_grades this corresponds to
|-
|-
|information  
|information  
|text  
|text  
|<center>NULL</center>  
|<center>NULL</center>  
|Further information like forum rating distribution 4/5/7/0/1  
|not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)
|-
|-
|feedback
|informationformat
|text
|int(10)
|<center>NULL</center>  
|<center>0</center>  
|Manual feedback from the teacher. Could be a code like 'mi'.
|Text format for information
|-
|-
|timecreated
|timecreated
|int(10)  
|int(10)  
|
|
|temporary hack - the date of submission in activity if any, new field expected in 2.0
|the time these entry was first created
|-
|-
|timemodified
|timemodified
|int(10)  
|int(10)  
|
|
|temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0
|the time this entry was last updated
|-
|'''usermodified'''
|int(10)
|
|the userid of the person who last modified this entry
|}
|}


=== grade_outcomes ===
=== grade_outcomes ===


This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2)
This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2).  For more info about these see [[Outcomes]].


{| border="1" cellpadding="2" cellspacing="0"
{| border="1" cellpadding="2" cellspacing="0"
Line 521: Line 457:
|
|
|The recommended scale for this outcome.   
|The recommended scale for this outcome.   
 
|-
|description
|text
|<center>NULL</center>
|The full description of the outcome (usually 1 sentence)
|-
|descriptionformat
|int(2)
|0
|
|-
|-
|timecreated
|timecreated
Line 537: Line 482:
|'''usermodified'''
|'''usermodified'''
|int(10)  
|int(10)  
|<center>NULL</center>
|the userid of the person who last modified this outcome
|}
=== grade_outcomes_courses ===
An intersection table used to make standard outcomes available to courses.
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''
|-
|'''id'''
|int(10) 
|
|
|the userid of the person who last modified this outcome
|autoincrementing
 
|-
|'''courseid'''
|int(10)
|
|The id of the course being assigned the outcome
 
|-
|'''outcomeid'''
|int(10) 
|
|The id of the outcome being assigned to the course
|}
|}


=== grade_history ===
=== grade_import_newitem ===
 
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''
 
|-
|'''id'''
|int(10) 
|
|autoincrementing
 
|-
|itemname
|varchar(255)
|
|new grade item name


This table keeps track of grade changes. Using this it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use this table for that, rather than storing this information in the main Moodle log.
|-
|importcode
|int(10)  
|
|import batch code for identification
 
|-
|importer
|int(10)  
|
|user importing the data
|}


Note we use itemid and userid as a key rather than grade_grade id, just in case one of the things we want to log here is the deletion of a grade entirely.
=== grade_import_values ===


{| border="1" cellpadding="2" cellspacing="0"
{| border="1" cellpadding="2" cellspacing="0"
Line 562: Line 564:
|'''itemid'''  
|'''itemid'''  
|int(10)   
|int(10)   
|
|NULL
|The grade_item the grade is from
|if set, this points to existing grade_items id


|-
|-
|'''userid'''
|newgradeitem
|int(10)
|int(10)
|NULL
|*TODO* Document
|-
|'''userid'''
|int(10) 
|
|
|The user that the grade belongs to
|*TODO* Document


|-
|-
|oldgrade
|finalgrade
|float
|float(10,5) 
|NULL
|NULL
|The original grade before the change
|raw grade value


|-
|-
|newgrade
|feedback
|float
|text
|NULL
|NULL
|The new grade after the change
|*TODO* Document


|-
|-
|note
|importcode
|text
|int(10) 
|
|similar to backup_code, a unique batch code for identifying one batch of imports
 
|-
|importer
|int(10) 
|NULL
|NULL
|An optional note about why this change was made
|*TODO* Document
|}
 
=== History tables ===
 
These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time.  It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:
 
#grade_categories_history
#grade_grades_history
#grade_items_history
#grade_outcomes_history
 
Each of them has the same DB structure as their matching table (e.g. grade_categories), with 4 extra fields:
 
 
 
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''


|-
|-
|howmodified
|action
|int(10) 
|0
|The action that lead to the change being recorded (insert, update, delete)
 
|-
|'''oldid'''
|int(10) 
|
|The id of the record being changed or inserted (PK of the main table, not the history table)
 
|-
|source
|varchar(255)
|varchar(255)
|manual
|NULL
|What caused the modification? manual/module/import/...
|The module from which the action originated
 
|-
|loggeduser
|int(10) 
|NULL
|The userid of the person who performed the action.
|}
 
=== grade_letters ===
 
{| border="1" cellpadding="2" cellspacing="0"
|'''Field'''
|'''Type'''
|'''Default'''
|'''Info'''


|-
|-
|'''usermodified'''
|'''id'''  
|int(10) 
|
|autoincrementing
 
|-
|contextid
|int(10)
|int(10)
|
|
|The user id of the person who made the change
|What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)


|-
|-
|timemodified
|lowerboundary
|int(10)  
|float(10,5)
|
|The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.
 
|-
|letter
|varchar(255) 
|
|
|The exact time this change was made
|The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..)
|}
|}


== Overview of module communication ==
== Overview of module communication ==


Modules will often store internal copies of grades for calculations or for showing grades to students etc, but these are ''purely'' internal. The gradebook system will never access these directly.
Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades.  


A new feature in Moodle 1.9 is a simple [[Events|event handler]]. The new gradebook will be the first feature in Moodle to take advantage of events, and all communication between the gradebook and the modules will take place via event messages.  See [[Events]] for full details.
The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API.
 
Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php


There are two ways that data is transferred between the module and the gradebook:


;'''1. Modules post grade events''' : Whenever a new grade is created, the module should post a grading event so that the gradebook can pick it up. As long as that column in the gradebook is not “locked” then the new grades will be entered (overwriting any existing ones).
;'''2. Gradebook posts grade events''' :Whenever a grade is altered in the gradebook (for example, a teacher may want to change an assignment grade), then an event is posted so that the module can pick it up. If the module implements this “reverse” function then the internal grade in the module can be changed.


=== Backward compatibility with Moodle 1.8 and earlier ===
=== Backward compatibility with Moodle 1.8 and earlier ===


:For backward compatibility with old third-party modules, we will add a new function called grades_grab_grades() to admin/cron.php to search all mod/xxx/lib.php files for functions named xxx_grades().  
Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.


:These legacy functions will be called to extract all the grades for all the activities in each course. Once the data is extracted, the moodle_event_post() function can be called to initiate an event as usual and copy/upgrade the data in the gradebook tables.
Modules are responsible to push existing grades into gradebook during upgrade.


:A similar function will be added to new modules to trigger a “mass copy” of all the existing grades into the new gradebook. This will be useful during the upgrade from 1.8 as well as being available in the normal gradebook interface to “refresh” a column from primary data.
==API for communication with modules/blocks==


== Core API functions ==
Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.


Even though most of the communication will take place via events, there are a few core functions in lib/gradelib.php that will be useful for modules:
===grade_get_grades()===


===grade_get_items()===
grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)


eg grade_get_items($courseid, $itemname=NULL, $itemtype=NULL, $itemmodule=NULL, $iteminstance=NULL, $itemnumber=NULL, $idnumber=NULL)
Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.


For extracting all the information about what grading items are attached to something.  For example, an assignment may want to retrieve all the grade_items for itself, and get three outcome scales in return.  This will affect the grading interface.
===grade_get_outcomes()===


===grade_create_item()===
grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)


To create a new grade_item in case it doesn't exist.  This function would be called when a module is created or updated, for example, to ensure grade_item entries exist.  It's not essential though - if grades are being added later and a matching grade_item doesn't exist yet, the gradebook will create them on the fly.
Returns list of outcomes used in course together with current outcomes for this user.


===grade_create_category()===
===grade_is_locked()===


eg grade_create_category(fullname, array of items, aggregation, etc ...)
grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)
For a given set of items, create a category to group them together (if one doesn't exist yet).  Modules may want to do this when they are created.  However, the ultimate control is in the gradebook interface itself.


===grade_is_locked($itemtype, $itemmodule, $itemteminstance, $userid=NULL)===
This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade.
([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])


This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or notThis is a combination of the actual settings in the grade tables and a check on moodle/course:editgradeswhenlocked. If it's locked to the current use then the module can print a nice message or prevent editing in the module. ([http://moodle.org/mod/forum/discuss.php?d=69223#p311329 info])
===grade_update()===
 
grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)
 
Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.
 
Returns:
 
* GRADE_UPDATE_OK = 0
* GRADE_UPDATE_FAILED = 1
* GRADE_UPDATE_MULTIPLE = 2
* GRADE_UPDATE_ITEM_LOCKED = 4
* GRADE_UPDATE_ITEM_DELETED = GRADE_UPDATE_ITEM_DELETED
 
===grade_update_outcomes()===
 
grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)
 
Updates outcomes of a given user. Manual outcomes cannot be updated.
 
== Private gradebook API ==
Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.
 
The following 3 functions are all in /lib/gradelib.php
 
===grade_regrade_final_grades()===
 
grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)
 
Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).
 
===grade_verify_idnumber()===
 
grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)
 
Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.
 
===remove_course_grades()===
 
remove_course_grades($courseid, $showfeedback)
 
Remove all grade related course data - history is kept
 
===grade_update_mod_grades()===
grade_update_mod_grades($modinstance, $userid=0)
 
Force full update of module grades in central gradebook.  Invokes $modinstance->modname.'_grade_item_update' and $modinstance->modname.'_update_grades' on mods implementing those methods.
 
TODO: add description of the other methods and classes + simple usage examples + querylib.php description


== Dealing with multiple grades  ==
== Dealing with multiple grades  ==


Modules will often produce several grade items. This may be several attempts, say, like the quiz module, or more commonly, ratings based on several outcomes. It is '''up to the module''' whether these grades are aggregated BEFORE sending to the gradebook as a single number, or are sent in raw form to the gradebook.  
Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.


Pre-aggregration makes the most sense for a quiz, say, which already implements algorithms to calculate a single number for each student. In such a case there will only be one grade item from a particular quiz.
Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.


For anything that uses outcomes with grades against multiple rubrics (such as an assignment), it would make the most sense to just pass all the results through to the gradebook as individual grade items.
If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See [[Outcomes]] for more details.


If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). This is simply done by checking/creating the category whenever a second item from the same instance is being added. All the grading items will by default appear separate in the gradebook GUI, but can be easily “combined” by choosing an aggregation algorithm from a list (such as “Sum, Mean, Median, etc ...), plus “Keep X high, Drop X Low” together with scaling/shifting via the Multiplication and Plus factors etc.
TODO: this may still be changed


== Calculated grade items  ==
== Calculated grade items  ==


A calculated grade item can operate on any arbitrary other items. It is not connected to any particular module.  
Categories or manual items maybe calculated using spreadsheet-like formulas.  Formulas may reference other items from the same course only using Id numbers in double square brackets.


The calculated values are re-calculated and stored in the grade_grades_final table whenever any of the values in the source items is changed. To avoid doing this for every grade_post event, we just set the “needsupdate” field on the relevant calculated grade item columns, then recalculate those columns at the next display time and reset the flag.
eg:  <nowiki>= MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0</nowiki>
 
== Regrading / updating of final grades ==
 
TODO: describe needsupdate flag and incremental updates
 
== Adjustment of raw grades ==
Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.


== Displaying the grades to ordinary participants  ==
== Displaying the grades to ordinary participants  ==


The module takes responsibility for displaying grades within the module (to a student, say). Normally they would use internal tables to do so. However, there is a grade_get_grades() function available for modules to query the core gradebook for grades (if required).
The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.


For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the “singleuser” report which only shows their own grades and has very few configuration options.
For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the ''User report'' report which only shows their own grades and has very few configuration options.


== Locked grades  ==
== Locked grades  ==


Both whole columns and individual grades can be locked in the gradebook, via the "locked" field.  Teachers may want to do this to prevent further changes from the modules, or from other teachers.  When a grade is locked, any grading events that might affect that grade are ignored.  When the graded is unlocked, an "unlock" event is triggered, which allows a module to handle it by sending the latest new grades back.
Both whole columns and individual grades can be locked in the gradebook, via the ''locked'' field.  Teachers may want to do this to prevent further changes from the modules, or from other teachers.  When a grade is locked, any changes that might affect that grade are ignored.  When the graded is unlocked, activities are asked to resend the latest grades.


In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.
In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.


== Manually modified grades ==
There is also an option to lock grade or item after some specified date.
 
== Overridden grades ==
 
Grades can be manually modified (overridden) in the gradebook.  When this is done the entered value is always used instead of the aggregated, calculated or activity grade.
 
Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.
 
The need to improve how the module expresses that a grade has been overridden will be reduced by the new [https://docs.moodle.org/en/Development:Grading_interface_2.0 grading interface]
 
== Hidden grades and categories ==


Grades can be manually modified (overriden) in the gradebook.  When this is done to grade_items derived from a module's grades, and the new value is different from the original one, then the field will automatically be given a locked status (it can of course be unlocked immediately if one wishes).  This is to prevent new grading events from changing the manually entered values unexpectedly.
Grades and categories can be hidden in the gradebook or the "categories and items" screen.  When a category is hidden all the grade items within it are automatically hidden as well.  When a category is un-hidden then all the grade items within it are un-hidden.


== Clean up after old activities ==
The teacher always sees totals calculated from all relevant items (hidden or un-hidden)


By default columns (grade items) will remain in the gradebook even when activities are deleted. A manual 'clean-up' button can delete old columns if required.
(Features below were added in 1.9.8 and 2.0)


When you click the 'Clean up' button, it shows you a list of columns that should be deleted, with a checkbox next to each one (on by default, but you can turn it off if you want to keep that column still) and then another button click to really delete the marked columns.
When a grade is shown its parent category will also be shown if it was hidden.   MDL-21367


Otherwise there will be a site option to do this automatically whenever activities are deleted.
The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0).  The user and overview report each have a setting to choose between:
 
# Hide any totals that are dependent on a hidden item (show a hyphen there)  [DEFAULT]
# Display totals excluding the hidden items
# Display full totals including the hidden items (may allow students to back-calculate hidden grades)


== Logging ==
== Logging ==


As well as datestamps and userids in the tables, all grading events will be logged in case an audit needs to be made.
All grading related changes maybe logged in history tables.


== Security Issues ==
== Security Issues ==
Line 700: Line 841:
==Overall grade==
==Overall grade==


Having an overall grade handy allows us to know exactly when a course is "finished". Exactly how do we specify the "overall" grade?  It's a special case, and might not always be just the sum.
Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.
 
The best solution is probably to have a special calculated column (grade_item) for every course that can not be deleted.  It's made special because the itemtype is 'total' (one per course). The calculation formula should be updated automatically whenever grade_items are changed in that course to be the "sum" of all the grade_items in the course.
 
However, if the calculation is edited manually then we should lock the calculation formula.  We could do this by setting the iteminfo field to something.  Clearing the calculation to an empty string could force it back to an automatic calculation formula.
 
== Metacourses ==
 
All grades in sub-courses should also be viewable from a metacourse.


== Report plugins ==
== Report plugins ==
All the main interface of the gradebook will be implemented as report plugins. Each plugin is fully responsible for defining the interface between the header and footer. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.
All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.


Each report will need to define one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the student interface can be a totally separate report plugin.
Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.


This allows for the widest flexibility and safety in how grades are presented.
This allows for the widest flexibility and safety in how grades are presented.
Line 721: Line 854:


Some snippets of functionality:
Some snippets of functionality:
{{Moodle 1.9}}
Overall it's a grid, with participant names down one side and grade items along the top.


Overall it's a grid, with student names down one side and grade items along the top.
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means.  
 
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.
 
Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means.


“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.
“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.


Textual notes can be added to each grade for more info. These show up to students as well. Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).
Textual notes can be added to each grade for more info. These show up to participants as well.


A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.
A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.


All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately.  This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while students just see their own grade or whatever the quiz is set to show.
All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately.  This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.


User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc).   
User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc).   
Line 746: Line 877:
At the bottom of each column is a row with the mean course score.  If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets.  eg 56% (11).  When the report is paged, these means are still for the whole course/group (not the page!)
At the bottom of each column is a row with the mean course score.  If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets.  eg 56% (11).  When the report is paged, these means are still for the whole course/group (not the page!)


=== Default student interface ===
{{Moodle 2.0}}
This interface will be what students see by default:


Some snippets of functionality:
Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.


Invert the grid to show one item per row, with the total/average at the bottom.
Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).


Use second/third columns to show categories.
See the [http://qa.moodle.net/grade/report/grader/index.php?id=2 QA testing site] for a live demo of this report.


Include ranking score in another column.
=== Default participant interface ===
This interface will be what participants see by default:


Include class mean scores in a final column for comparison.
Some snippets of functionality:


No editing functionality.
*Invert the grid to show one item per row, with the total/average at the bottom.
*Use second/third columns to show categories.
*Include ranking score in another column.
*Show feedback
*Show percentage
*No editing functionality.


== Export plugins ==
See the [http://qa.moodle.net/grade/report/user/index.php?id=2 QA testing site] for a live demo of this report.


The API for these is extremely simple.  Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface.  This file can accept parameters that produce a subset of the grades:
=== Outcomes report ===
This simple informational report displays all the outcomes used by the course, with the following information:


* courseid
*Outcome name
* groupid
*Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course
* categoryid
*Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.
* itemid
*Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)
* userid
*Average: For each activity using the outcome, the average score is shown.
*Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)


The index.php can choose to simply dump something (eg an Excel spreadsheet) and return, or it can show an interface for further options and selections.  Ideally even if it dumps something it should also show some feedback about what was exported to make it easier to double check what was sent, but this is up to the plugin to implement.
=== Overview report ===
Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.


Further if the plugin contains a lib.php and an xyz_visible() function then the gradebook can check this function to make sure the current user can see/use the plugin (eg by checking access permissions).  If this function returns false then the export method won't appear in the main gradebook interfaces.
== Export plugins ==


The export plugins are a "full" Moodle plugin, so it can have tables, cron functions, event handlers, capabilities etcFor example, an export plugin might not even have a GUI (ie xyz_visible() is always false and/or index.php doesn't exist) - it might operate solely off cron or event triggers.
The API for these is extremely simpleEach export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.


== Import plugins ==
== Import plugins ==
Line 783: Line 922:
The index.php will show an interface for further options and selections.
The index.php will show an interface for further options and selections.


Further if the plugin contains a lib.php and an xyz_visible() function then the gradebook can check this function to make sure the current user can see/use the plugin.  If this function returns false then the import method won't appear in the main gradebook interfaces.
Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.
 
The import plugins are a "full" Moodle plugin, so it can have tables, cron functions, event handlers, capabilities etc.  For example, an import plugin might not even have a GUI (ie xyz_visible() is always false and/or index.php doesn't exist) - it might operate solely off cron or event triggers.
 
The entire import must be treated as one operation.  If it fails, then no records should be imported and the database is unchanged.


Some sample import plugins are:
Some sample import plugins are:
Line 793: Line 928:
===Import from CSV===
===Import from CSV===


Accepts an upload of (or URL to) a CSV file.  Multiple options describe how to process the file, which columns to add etc.  These should be sticky, and retained via user preferences to make future imports easier.
Accepts an upload of (or URL to) a CSV file.  Multiple options describe how to process the file, which columns to add etc.  The imported grades always override current grades.


===Import from XML===
===Import from XML===
Line 802: Line 937:
     <result>
     <result>
         <state>['new' or 'regrade']</state>
         <state>['new' or 'regrade']</state>
             <assignment>[idnumber]</assignmentid>
             <assignment>[idnumber]</assignment>
             <student>[studentid]</student>
             <student>[studentid]</student>
             <score>[score]</score>
             <score>[score]</score>
Line 808: Line 943:
         <result>
         <result>
             <state>['new' or 'regrade']</state>
             <state>['new' or 'regrade']</state>
             <assignment>[idnumber]</assignmentid>
             <assignment>[idnumber]</assignment>
             <student>[studentid]</student>
             <student>[studentid]</student>
             <score>[score]</score>
             <score>[score]</score>
Line 817: Line 952:
== Capabilities and Permissions ==
== Capabilities and Permissions ==


* moodle/course:viewcoursegrades
* moodle/grade:view  -  view own grades or grades of other user if used in CONTEXT_USER


* moodle/course:downloadcoursegrades
* moodle/grade:viewall - view grades of all users


* moodle/user:viewusergrades
* moodle/grade:viewhidden - see grades that are marked as hidden for the owner


* moodle/grade:viewhidden
* moodle/grade:hide - be able to hide/unhide cells, items or categories


* moodle/grade:editlocked
* moodle/grade:lock - be able to lock cells, items or categories
 
* moodle/grade:unlock - be able to unlock cells, items or categories
 
* moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)
 
* moodle/grade:import - general import grades, requires separate permission for each plugin
 
* moodle/grade:export - export grades, requires separate permission for each plugin
 
* gradereport/grader:view - can view the grader report
 
* gradeimport/csv:view - can view/use the csv import plugin
 
* gradeexport/csv:view - can view/use the csv export plugin


* moodle:site/accessallgroups
* moodle:site/accessallgroups


== Development Tasks and Tracking ==


== Interface Mockups ==
For details of 1.9 development see [http://tracker.moodle.org/browse/MDL-9137 MDL-9137]


Nicolas is working on a mock-up interface that you can play with:
For details of 2.0 development see [https://docs.moodle.org/en/Development:Gradebook_improvements Gradebook_imporovements] and [http://tracker.moodle.org/browse/MDL-19131 MDL-19131]


    [http://test.moodle.com/gradebook/ Mock Gradebook]
==Updating module code==
Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.


It's changing rapidly in response to your feedback.
Steps:
*add xxx_update_grades() function into mod/xxx/lib.php
*add xxx_grade_item_update() function into mod/xxx/lib.php
*patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()
*patch all places of code that change grade values to call xxx_update_grades()
*patch code that displays grades to students to use final grades from the gradebook


== Rough Development Timeline ==
There are many examples in official modules, assignment has the most advanced implementation.


# Develop Event API
== Ideas for the future ==
## Core tables
{{Moodle 2.1}}
## events.php to load/maintain handlers
See [[Gradebook_improvements]] and MDL-25423 for details of planned future enhancements
## Core API functions lib/eventslib.php and unit tests
 
# Develop Core Gradebook
*option to aggregate including/excluding hidden grades - needs db changes
## Core tables
*option to rollback all changes during import operation if anything fails
## Core API functions lib/gradelib.php and unit tests
*performance improvements
## Core handler for grade changes
*conditional activities
## Define plugin directory structure
*course completion criteria
## Cron job for support of legacy grade functions in modules
*better public API for modules
# Core Moodle improvements
*better API for gradebook plugins
## Support for all grades-based plugins for db, cron, access.php, events.php etc
*better state tracking in export plugins
# Develop Core activity modules
*ajax reports
## Triggers for all major activity modules
*specialised reports
## Handlers for all major activity modules
*submission and marking date tracking db changes
# Reports
*calculation formula improvements
## Standard report for teachers
*historical views
## Standard report for students
*individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group
# Exports
## Standard exports (like 1.8)
## XML export (OU format)
# Imports
## CSV format


== See also ==
== See also ==


* [http://moodle.org/mod/forum/discuss.php?d=69223&mode=3 Gradebook Development ideas] forum discussion
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion
* [[Events]]
* [[Gradebook Report Tutorial]]
 
 


[[Category:Grades]]
[[Category:Grades]]
[[Category:Interfaces]]

Latest revision as of 13:22, 14 July 2021

Note: This page is a work-in-progress. Feedback and suggested improvements are welcome. Please join the discussion on moodle.org or use the page comments.


Executive Summary

This document primarily describes the current workings of the gradebook. For more detailed information about current gradebook development see Gradebook_improvements

The gradebook mechanisms must be rebuilt to:

  1. Improve performance and scalability - All grades from throughout the system will be pushed to a central system of tables. This means reports based on grades can be generated much faster, and the gradebook has ultimate control over the content.
  2. Improve flexibility - All aspects of the new gradebook will use simple plugin structures, namely: exports, imports and displays/reports. It is expected that the community will be very active in producing special-purpose reports analysing the basic grade data in new ways, for example, or writing plugins to transfer grades to student information systems.
  3. Allow rubrics for outcomes (aka standards,competencies,goals) - As well as numerical grades, each grading item can consist of a number of scores made on a rubric against a standard outcome statement. These can be automatically converted to a numerical grade if desired or just shown as is.
  4. Allow arbitrary columns and derived columns - Arbitrary columns of data can be added (either manually or via import). Columns can also be automatically filled based on formulas.
  5. Implement limited public API - Activities may use this API to send grades/outcomes to gradebook and find out the final grades.

Glossary

Here are some terms used in the gradebook, both in the development and the user interface. Using these terms in discussions about the gradebook will help to reduce confusion.

Term Definition
Activity An instance of an activity module (e.g. a single quiz, assignment etc...)
Calculation A formula used to calculate grades, based (optionally) on other grade items. Not the same as Calculated question types.
Category A set of Grade Items. A Category also has its own aggregated Grade which is calculated from its Grade Items. There is no limit to the level of nesting of Categories (a Category may belong to another Category). However, each Grade Item may belong to only one Category.
Course completion The concept of meeting certain criteria for completing a course. In the context of the gradebook, this means a set of grades that must be reached, or a number of outcomes/competencies to complete/master.
Grade A Grade is a single assessment. It may be a number or an item on a scale (possibly tied to an Outcome). Raw grade value is the numerical or scale grade from activity. Final grade is the grade reported in gradebook.
Gradebook A central location in Moodle where students' Grades are stored and displayed. Teachers can keep track of their students' progress and organise which set of Grades their students will be able to see. Students see their own Grades.
Grade Item A "column" of Grades. It can be created from a specific Activity or other module, calculated from other Grade Items, or entered manually.
Grade Locks See linked section of this page
History The gradebook has its own type of log, which keeps a History of all changes made to grades.
Outcome Outcomes are specific descriptions of what a person is expected to be able to do or understand at the completion of an activity or course. An activity might have more than one outcome, and each may have a grade against it (usually on a scale). Other terms for Outcomes are Competencies and Goals. See some Examples.
Scale A scale is a set of responses from which the teacher can choose one. eg Very cool, Cool, Fairly cool, Not very cool, Not cool
Letter Grades Special representation of grade values similar to scales. Letters are configured in course contexts or above and are defined by lower boundary. eg A (above 90 %), B (above 80 %), C (above 70 %), D (above 50 %), F (above 0 %)

Database structures

grade_items

This table keeps information about gradeable items (ie columns). If an activity (eg an assignment or quiz) has multiple grade_items associated with it (eg several outcomes and numerical grade), then there will be a corresponding multiple number of rows in this table.

idnumber is a tag unique inside a course identifying the grade item, useful for identifying data in exports and for referring to the grade item in calculations. It is the same as the idnumber in course_modules.


Field Type Default Info
id int(10) autoincrementing
courseid int(10) The course this item is part of
categoryid int(10)
NULL
the category group this item belongs to
itemname varchar(255)
NULL
The name of this item (pushed in by the module or entered by user)
itemtype varchar(30) 'mod', 'blocks', 'manual', 'course', 'category' etc
itemmodule varchar(30)
NULL
'forum', 'quiz', 'csv', etc
iteminstance int(10)
NULL
id of the item module
itemnumber int(10)
NULL
Can be used to distinguish multiple grades for an activity
iteminfo text
NULL
Info and notes about this item XXX
idnumber varchar(255)
NULL
Arbitrary idnumber provided by the module responsible (optional and course unique)
calculation text
NULL
Spreadsheet-type formula used to process the raw grades into final grades
gradetype int(4)
1
0 = none, 1 = value, 2 = scale, 3 = text
grademax float(10,5)
100
What is the maximum allowable grade?
grademin float(10,5)
0
What is the minimum allowable grade?
scaleid int(10)
NULL
If this grade is based on a scale, which one is it?
outcomeid int(10)
NULL
If this is outcome item, which outcome is it?
gradepass float(10,5)
0
What grade is needed to pass? grademin <= gradepass <= grademax
multfactor float(10,5)
1.0
Multiply all raw grades from activities by this
plusfactor float(10,5)
0.0
Add this to all raw grades from activities by this
aggregationcoef float(10,5)
0.0
Weight applied to all grades in this grade item during aggregation with other grade items.
sortorder int(10)
0
Sorting order of the columns (pre-order walk of the grading tree)
display int(10)
0
Display as real grades, percentages (in reference to the minimum and maximum grades) or letters (A, B, C etc..), or course default (0)
hidden int(10)
0
1 is hidden, 1 is hide always, > 1 is a date to hide until (prevents viewing of all user grades)
locked int(10)
0
0 is not locked, > 0 is a date when was item locked (no final grade or grade_item updates possible)
locktime int(10)
0
0 no auto locking, > 0 is a date to lock grade item and final grades after automatically
needsupdate int(10)
0
If this flag is set, then the whole column will be recalculated. If set in course item, some other item needs recalculation. Calculated and category items are recalculated together with any other items.
timecreated int(10) The first time this grade_item was created
timemodified int(10) The last time this grade_item was modified

grade_categories

This table keeps information about categories, used for grouping items. An associated grade_item will be maintained for each category to store the aggregate data.

Field Type Default Info
id int(10) autoincrementing
courseid int(10) The course this grade category is part of
parent int(10)
NULL
Parent grade_category (hierarchical)
depth int(10)
0
How deep is this category from the highest level (1,2,3)
path varchar(255) Shows the path as /1/2/3/
fullname varchar(255) The name of this grade category
aggregation int(10)
0
A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc)
keephigh int(10)
0
Keep only the X highest items
droplow int(10)
0
Drop the X lowest items
aggregateonlygraded int(1)
0
Aggregate only existing grades
aggregateoutcomes int(1)
0
Aggregate otcomes together with normal items
aggregatesubcats int(1)
0
Aggregate only items placed directly in category or all items in subcategories excluding the subcategory totals
timecreated int(10) The first time this grade_category was created
timemodified int(10) The last time this grade_category was modified
hidden int(1)
0

grade_grades

This table keeps individual grades for each user and each item. The raw grade is exactly as imported or submitted by modules. The rawgrademax/min and rawscaleid are stored here to record the values at the time the grade was stored, because teachers might change this for an activity! All the results are normalised/resampled/calculated for the finalgrade, which is relative to the max/min/scaleid values stored in the grade_item. The finalgrade field is effectively a cache and values are rebuilt whenever raw values or the grade_item changes.

Note that the finalgrade for a scale-based item may be non-integer! It needs to be rounded on display.

Field Type Default Info
id int(10) autoincrementing
itemid int(10) The item this grade belongs to
userid int(10) The user who this grade is for
rawgrade float(11,10)
NULL
The raw grade that came into the system
rawgrademax float(11,10)
100
The maximum allowable grade when this was created
rawgrademin float(11,10)
0
The minimum allowable grade when this was created
rawscaleid int(10)
NULL
If this grade is based on a scale, which one was it?
usermodified int(10)
NULL
the userid of the person who last modified the raw grade value
finalgrade float(11,10)
NULL
The final grade (cached) after all calculations are made. Overriden grades are also stored here.
hidden int(10)
0
0 is not hidden, 1 is hide always, > 1 is a date to hide until
locked int(10)
0
0 is not locked, > 0 when was the grade locked
locktime int(10)
0
0 is never, > 0 is a date to lock the final grade after automatically
exported int(10)
0
0 is not exported, > 0 is the last exported date
excluded int(10)
0
grade excluded from aggregation, > 0 is the last excluded date
overridden int(10)
0
0 is not overridden, > 0 is the last overridden date
feedback text
NULL
Manual feedback from the teacher. Could be a code like 'mi'.
feedbackformat int(10)
0
Text format for feedback
information text
NULL
not sued yet (Further information like forum rating distribution 4/5/7/0/1 ?)
informationformat int(10)
0
Text format for information
timecreated int(10) temporary hack - the date of submission in activity if any, new field expected in 2.0
timemodified int(10) temporary hack - the date of grading in activity or date of manual grading in gradebook, new field expected in 2.0

grade_outcomes

This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2). For more info about these see Outcomes.

Field Type Default Info
id int(10) autoincrementing
courseid int(10)
NULL
Mostly these are defined site wide ie NULL
shortname varchar(255) The short name or code for this outcome statement
fullname text The full description of the outcome (usually 1 sentence)
scaleid int(10) The recommended scale for this outcome.
description text
NULL
The full description of the outcome (usually 1 sentence)
descriptionformat int(2) 0
timecreated int(10) the time this outcome was first created
timemodified int(10) the time this outcome was last updated
usermodified int(10)
NULL
the userid of the person who last modified this outcome

grade_outcomes_courses

An intersection table used to make standard outcomes available to courses.

Field Type Default Info
id int(10) autoincrementing
courseid int(10) The id of the course being assigned the outcome
outcomeid int(10) The id of the outcome being assigned to the course

grade_import_newitem

Field Type Default Info
id int(10) autoincrementing
itemname varchar(255) new grade item name
importcode int(10) import batch code for identification
importer int(10) user importing the data

grade_import_values

Field Type Default Info
id int(10) autoincrementing
itemid int(10) NULL if set, this points to existing grade_items id
newgradeitem int(10) NULL *TODO* Document
userid int(10) *TODO* Document
finalgrade float(10,5) NULL raw grade value
feedback text NULL *TODO* Document
importcode int(10) similar to backup_code, a unique batch code for identifying one batch of imports
importer int(10) NULL *TODO* Document

History tables

These table keep track of changes to most of the grade tables. Using these it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use these tables for that, rather than storing this information in the main Moodle log. The following tables are set up for that purpose:

  1. grade_categories_history
  2. grade_grades_history
  3. grade_items_history
  4. grade_outcomes_history

Each of them has the same DB structure as their matching table (e.g. grade_categories), with 4 extra fields:


Field Type Default Info
action int(10) 0 The action that lead to the change being recorded (insert, update, delete)
oldid int(10) The id of the record being changed or inserted (PK of the main table, not the history table)
source varchar(255) NULL The module from which the action originated
loggeduser int(10) NULL The userid of the person who performed the action.

grade_letters

Field Type Default Info
id int(10) autoincrementing
contextid int(10) What contextid does this letter apply to (from levels CONTEXT_SYSTEM, CONTEXT_COURSECAT or CONTEXT_COURSE)
lowerboundary float(10,5) The lower boundary of the letter. Its upper boundary is the lower boundary of the next highest letter, unless there is none above, in which case it's grademax for that grade_item.
letter varchar(255) The display value of the letter. Can be any character or string of characters (OK, A, 10% etc..)

Overview of module communication

Modules usually store raw grades internally and pass them into gradebook every time they change. Gradebook may also request activities to resend the grades.

The gradebook is designed to be as separate as possible from the code of activities - modules do not read grade tables or use internal gradebook API.

Originally it was planned to use new events API, but in the end it was decided to use minimal API consisting of several function in lib/gradelib.php and each mod/xxx/lib.php


Backward compatibility with Moodle 1.8 and earlier

Function grade_grab_legacy_grades($courseid) may be used to request transfer of grades from legacy or 3rd party activities which were not yet converted to new grade API. This function is not called automatically.

Modules are responsible to push existing grades into gradebook during upgrade.

API for communication with modules/blocks

Modules may use only functions from lib/gradelib.php which are marked as public. This API may be extended in later 1.9.x release. Activities should access/update only own grades.

grade_get_grades()

grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0)

Returns grading information for given activity - optionally with users grades. Manual, course or category items can not be queried.

grade_get_outcomes()

grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance,$userid=0)

Returns list of outcomes used in course together with current outcomes for this user.

grade_is_locked()

grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL)

This function will tell a module whether a grade (or grade_item if $userid is not given) is currently locked or not. If it's locked to the current user then the module can print a nice message or prevent editing in the module. If no $userid is given, the method will always return the grade_item's locked state. If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked, the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will return the locked state of the specific grade. (info)

grade_update()

grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL)

Submit new or update grade; update/create grade_item definition. Grade must have userid specified, rawgrade and feedback with format are optional. rawgrade NULL means 'Not graded', missing property or key means do not change existing. Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.

Returns:

  • GRADE_UPDATE_OK = 0
  • GRADE_UPDATE_FAILED = 1
  • GRADE_UPDATE_MULTIPLE = 2
  • GRADE_UPDATE_ITEM_LOCKED = 4
  • GRADE_UPDATE_ITEM_DELETED = GRADE_UPDATE_ITEM_DELETED

grade_update_outcomes()

grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data)

Updates outcomes of a given user. Manual outcomes cannot be updated.

Private gradebook API

Private API is used by gradebook plugins and core Moodle code, it may change in 2.0. Most of the interesting classes and functions are in lib/gradelib.php, grade/lib.php and grade/report/lib.php.

The following 3 functions are all in /lib/gradelib.php

grade_regrade_final_grades()

grade_regrade_final_grades($courseid=NULL, $userid=NULL, $updated_item=NULL)

Updates all grade_grades->finalgrade records for each grade_item matching the given attributes. The search is further restricted, so that only grade_items that have needs_update == true or that use calculation are retrieved and used for the update. The function returns the number of grade_items updated (NOT the same as the number of grades_grades updated!).

grade_verify_idnumber()

grade_verify_idnumber($idnumber, $grade_item = null, $cm = null, $gradeitem)

Verify new value of idnumber - checks for uniqueness of new idnubmers, existing are kept intact.

remove_course_grades()

remove_course_grades($courseid, $showfeedback)

Remove all grade related course data - history is kept

grade_update_mod_grades()

grade_update_mod_grades($modinstance, $userid=0)

Force full update of module grades in central gradebook. Invokes $modinstance->modname.'_grade_item_update' and $modinstance->modname.'_update_grades' on mods implementing those methods.

TODO: add description of the other methods and classes + simple usage examples + querylib.php description

Dealing with multiple grades

Modules usually produce only one grade item per activity. Optionally one or more outcomes may be attached to activities.

Some activities may need to aggregate multiple ratings or attempts before sending them into the gradebook. Activities can not send variable number of items.

If the gradebook receives multiple grade items from a module, then they are automatically grouped together in a unique grade category (with the same name as the module instance). See Outcomes for more details.

TODO: this may still be changed

Calculated grade items

Categories or manual items maybe calculated using spreadsheet-like formulas. Formulas may reference other items from the same course only using Id numbers in double square brackets.

eg:  = MEAN([[quiz121]], [[quizend]]) + [[assignmentAXC]] + 20.0

Regrading / updating of final grades

TODO: describe needsupdate flag and incremental updates

Adjustment of raw grades

Grade_item contains optional rules for adjusting the raw grade before it is cached into a final grade. These rules are processed BEFORE the calculation discussed above. Scale is never changed. Multfactor and plusfactor may be used to alter raw grades coming from activities, but it is recommended to use formulas instead.

Displaying the grades to ordinary participants

The module takes responsibility for displaying grades within the module (to a student, say). It is recommended to use the real final grades obtained using grade_get_grades() functionBecause guidebook might force hiding, override grade, etc.

For full display of grades in a whole course say, the student uses the same link as teachers use to access the gradebook. However, due to their different permissions they will only have access to specific reports. By default this is the User report report which only shows their own grades and has very few configuration options.

Locked grades

Both whole columns and individual grades can be locked in the gradebook, via the locked field. Teachers may want to do this to prevent further changes from the modules, or from other teachers. When a grade is locked, any changes that might affect that grade are ignored. When the graded is unlocked, activities are asked to resend the latest grades.

In the main GUIs the lock toggling will be achieved by clicking on a little padlock icon beside each entry or column.

There is also an option to lock grade or item after some specified date.

Overridden grades

Grades can be manually modified (overridden) in the gradebook. When this is done the entered value is always used instead of the aggregated, calculated or activity grade.

Once grades have been overriden in the gradebook they become read only in the original module. The module should provide a visual indication as to why the grade cannot be modified.

The need to improve how the module expresses that a grade has been overridden will be reduced by the new grading interface

Hidden grades and categories

Grades and categories can be hidden in the gradebook or the "categories and items" screen. When a category is hidden all the grade items within it are automatically hidden as well. When a category is un-hidden then all the grade items within it are un-hidden.

The teacher always sees totals calculated from all relevant items (hidden or un-hidden)

(Features below were added in 1.9.8 and 2.0)

When a grade is shown its parent category will also be shown if it was hidden. MDL-21367

The teacher decides what ordinary users can see in the case of totals that include hidden grades (MDL-21218, in 1.9.8 and 2.0). The user and overview report each have a setting to choose between:

  1. Hide any totals that are dependent on a hidden item (show a hyphen there) [DEFAULT]
  2. Display totals excluding the hidden items
  3. Display full totals including the hidden items (may allow students to back-calculate hidden grades)

Logging

All grading related changes maybe logged in history tables.

Security Issues

For security an option to force SSL for the gradebook might be good.

Overall grade

Each course has exactly one course grade item. It may be used for this purpose now. Other course completion criteria will be implemented in 2.0.

Report plugins

All the main interface of the gradebook are implemented as report plugins. Each plugin is fully responsible for page layout, there are some handy functions in grade/lib.php. They can even define their own capabilities and extra tables if the core tables are not enough, as they'll have a full /grade/report/xxxx/db directory.

Each report defines one capability to allow people to see that report, so that admins have control over who can see what reports. For example, the participant interface can be a totally separate report plugin.

This allows for the widest flexibility and safety in how grades are presented.

Default teacher interface

This interface will be what teachers see by default, and will subsume everything the current interface (in Moodle 1.8) does.

Some snippets of functionality: Moodle1.9

Overall it's a grid, with participant names down one side and grade items along the top.

Columns will be able to be collapsed together by grouping them into categories. Grades for categories can be calculated via various means.

“Eye-cons” on the columns and checkboxes by every grade (this bit possibly controlled with a switch) allow hiding by category, by column, by individual grade.

Textual notes can be added to each grade for more info. These show up to participants as well.

A groups menu allows the teacher to switch between showing EACH of the groups they have access to, or ALL the groups they have access to.

All grade items will link to modulepath/grade.php?id=44 which will work out what the current person should be allowed to see and either redirect them to the correct page or just show them immediately. This copes with situations like the quiz, say, where we want editing teachers to go to the detailed reports there while participants just see their own grade or whatever the quiz is set to show.

User preference to SWITCH between showing raw grades, percentage grades, or both, or grade letters (A/B/C etc).

Settings for grade letters not only define the transformation from percentage to grades, but also the transformation from letters to grades (in case the teacher edits some of the letter grades).

Categories are shown above the headings for each column. Clicking for more info on a category will just show the category with a summary column showing total/average for just that category (PLUS the summary column for the whole course).

All columns should be sortable up/down.

At the bottom of each column is a row with the mean course score. If in groups mode, then add ANOTHER row with just the group mean. Add the number of grades used in brackets. eg 56% (11). When the report is paged, these means are still for the whole course/group (not the page!)

Moodle 2.0


Teachers can type “straight into” the grid using AJAX or fallback to forms. No popup menus for values.

Later on we can support customisable shorthand codes to make data entry quick (eg type 'ab' for absent, or 'nge' for not good enough).

See the QA testing site for a live demo of this report.

Default participant interface

This interface will be what participants see by default:

Some snippets of functionality:

  • Invert the grid to show one item per row, with the total/average at the bottom.
  • Use second/third columns to show categories.
  • Include ranking score in another column.
  • Show feedback
  • Show percentage
  • No editing functionality.

See the QA testing site for a live demo of this report.

Outcomes report

This simple informational report displays all the outcomes used by the course, with the following information:

  • Outcome name
  • Overall average: If the outcome is used by more than one activity, this shows you the mean across all these activities in the current course
  • Site-wide: Yes or No: A site-wide outcome is automatically made available to all courses.
  • Activities: A list of links to the activities in the current course that use each outcome. One row per activity (table splits here)
  • Average: For each activity using the outcome, the average score is shown.
  • Number of grades: For each activity using the outcome, the number of grades is shown (non-graded participants are ignored)

Overview report

Another basic report, showing a participant's course averages in each of the courses in which s/he has received grades.

Export plugins

The API for these is extremely simple. Each export plugin should occupy a directory under /grade/export/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.

Import plugins

Each import plugin should occupy a directory under /grade/import/xyz and needs to provide only an index.php file as a the primary interface. This file just accepts a 'courseid' parameter.

The index.php will show an interface for further options and selections.

Import plugin must validate data before starting the import operation, if some parts of import fail the user must be notified.

Some sample import plugins are:

Import from CSV

Accepts an upload of (or URL to) a CSV file. Multiple options describe how to process the file, which columns to add etc. The imported grades always override current grades.

Import from XML

Accepts an upload of (or URL to) an XML file with this kind of format (from OU).

<results batch="[someuniqueimportnumber]">
    <result>
        <state>['new' or 'regrade']</state>
            <assignment>[idnumber]</assignment>
            <student>[studentid]</student>
            <score>[score]</score>
        </result>
        <result>
            <state>['new' or 'regrade']</state>
            <assignment>[idnumber]</assignment>
            <student>[studentid]</student>
            <score>[score]</score>
        </result>
        [...]
</results>

Capabilities and Permissions

  • moodle/grade:view - view own grades or grades of other user if used in CONTEXT_USER
  • moodle/grade:viewall - view grades of all users
  • moodle/grade:viewhidden - see grades that are marked as hidden for the owner
  • moodle/grade:hide - be able to hide/unhide cells, items or categories
  • moodle/grade:lock - be able to lock cells, items or categories
  • moodle/grade:unlock - be able to unlock cells, items or categories
  • moodle/grade:manage - manage grade items and categories in gradebook (create, edit, lock, hide, delete, etc.)
  • moodle/grade:import - general import grades, requires separate permission for each plugin
  • moodle/grade:export - export grades, requires separate permission for each plugin
  • gradereport/grader:view - can view the grader report
  • gradeimport/csv:view - can view/use the csv import plugin
  • gradeexport/csv:view - can view/use the csv export plugin
  • moodle:site/accessallgroups

Development Tasks and Tracking

For details of 1.9 development see [https://tracker.moodle.org/browse/MDL-9137 MDL-9137]

For details of 2.0 development see Gradebook_imporovements and [https://tracker.moodle.org/browse/MDL-19131 MDL-19131]

Updating module code

Module authors must implement new gradebook API and add upgrade code for migration of old grades into new gradebook. Fortunately the needed changes are not big.

Steps:

  • add xxx_update_grades() function into mod/xxx/lib.php
  • add xxx_grade_item_update() function into mod/xxx/lib.php
  • patch xxx_update_instance(), xxx_add_instance() and xxx_delete_instance() to call xxx_grade_item_update()
  • patch all places of code that change grade values to call xxx_update_grades()
  • patch code that displays grades to students to use final grades from the gradebook

There are many examples in official modules, assignment has the most advanced implementation.

Ideas for the future

Moodle 2.1

See Gradebook_improvements and MDL-25423 for details of planned future enhancements

  • option to aggregate including/excluding hidden grades - needs db changes
  • option to rollback all changes during import operation if anything fails
  • performance improvements
  • conditional activities
  • course completion criteria
  • better public API for modules
  • better API for gradebook plugins
  • better state tracking in export plugins
  • ajax reports
  • specialised reports
  • submission and marking date tracking db changes
  • calculation formula improvements
  • historical views
  • individual graph of grades (time vs %). Bar graph, lineal graph. Add (or not) the maximum posible; line of 0 (=minimum), 25, 50 (=median), 75 and 100 (=max) percentils of the group

See also