Merge branch 'MDL-41761-master' of git://github.com/jamiepratt/moodle
This commit is contained in:
@@ -84,8 +84,7 @@ abstract class quiz_attempts_report extends quiz_default_report {
|
||||
$this->qmsubselect = quiz_report_qm_filter_select($quiz);
|
||||
|
||||
$this->form = new $formclass($this->get_base_url(),
|
||||
array('qmsubselect' => $this->qmsubselect, 'quiz' => $quiz,
|
||||
'currentgroup' => $currentgroup, 'context' => $this->context));
|
||||
array('quiz' => $quiz, 'currentgroup' => $currentgroup, 'context' => $this->context));
|
||||
|
||||
return array($currentgroup, $students, $groupstudents, $allowed);
|
||||
}
|
||||
@@ -103,7 +102,7 @@ abstract class quiz_attempts_report extends quiz_default_report {
|
||||
* Get information about which students to show in the report.
|
||||
* @param object $cm the coures module.
|
||||
* @param object $course the course settings.
|
||||
* @return an array with four elements:
|
||||
* @return array with four elements:
|
||||
* 0 => integer the current group id (0 for none).
|
||||
* 1 => array ids of all the students in this course.
|
||||
* 2 => array ids of all the students in the current group.
|
||||
|
||||
@@ -137,52 +137,64 @@ function quiz_report_can_filter_only_graded($quiz) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the quiz grading method return sub select sql to find the id of the
|
||||
* one attempt that will be graded for each user. Or return
|
||||
* empty string if all attempts contribute to final grade.
|
||||
* This is a wrapper for {@link quiz_report_grade_method_sql} that takes the whole quiz object instead of just the grading method
|
||||
* as a param. See definition for {@link quiz_report_grade_method_sql} below.
|
||||
*
|
||||
* @param object $quiz
|
||||
* @param string $quizattemptsalias sql alias for 'quiz_attempts' table
|
||||
* @return string sql to test if this is an attempt that will contribute towards the grade of the user
|
||||
*/
|
||||
function quiz_report_qm_filter_select($quiz, $quizattemptsalias = 'quiza') {
|
||||
if ($quiz->attempts == 1) {
|
||||
// This quiz only allows one attempt.
|
||||
return '';
|
||||
}
|
||||
return quiz_report_grade_method_sql($quiz->grademethod, $quizattemptsalias);
|
||||
}
|
||||
|
||||
switch ($quiz->grademethod) {
|
||||
/**
|
||||
* Given a quiz grading method return sql to test if this is an
|
||||
* attempt that will be contribute towards the grade of the user. Or return an
|
||||
* empty string if the grading method is QUIZ_GRADEAVERAGE and thus all attempts
|
||||
* contribute to final grade.
|
||||
*
|
||||
* @param string $grademethod quiz grading method.
|
||||
* @param string $quizattemptsalias sql alias for 'quiz_attempts' table
|
||||
* @return string sql to test if this is an attempt that will contribute towards the graded of the user
|
||||
*/
|
||||
function quiz_report_grade_method_sql($grademethod, $quizattemptsalias = 'quiza') {
|
||||
switch ($grademethod) {
|
||||
case QUIZ_GRADEHIGHEST :
|
||||
return "$quizattemptsalias.id = (
|
||||
SELECT MIN(qa2.id)
|
||||
FROM {quiz_attempts} qa2
|
||||
WHERE qa2.quiz = $quizattemptsalias.quiz AND
|
||||
qa2.userid = $quizattemptsalias.userid AND
|
||||
COALESCE(qa2.sumgrades, 0) = (
|
||||
SELECT MAX(COALESCE(qa3.sumgrades, 0))
|
||||
FROM {quiz_attempts} qa3
|
||||
WHERE qa3.quiz = $quizattemptsalias.quiz AND
|
||||
qa3.userid = $quizattemptsalias.userid
|
||||
)
|
||||
)";
|
||||
SELECT MIN(qa2.id)
|
||||
FROM {quiz_attempts} qa2
|
||||
WHERE qa2.quiz = $quizattemptsalias.quiz AND
|
||||
qa2.userid = $quizattemptsalias.userid AND
|
||||
COALESCE(qa2.sumgrades, 0) = (
|
||||
SELECT MAX(COALESCE(qa3.sumgrades, 0))
|
||||
FROM {quiz_attempts} qa3
|
||||
WHERE qa3.quiz = $quizattemptsalias.quiz AND
|
||||
qa3.userid = $quizattemptsalias.userid
|
||||
)
|
||||
)";
|
||||
|
||||
case QUIZ_GRADEAVERAGE :
|
||||
return '';
|
||||
|
||||
case QUIZ_ATTEMPTFIRST :
|
||||
return "$quizattemptsalias.id = (
|
||||
SELECT MIN(qa2.id)
|
||||
FROM {quiz_attempts} qa2
|
||||
WHERE qa2.quiz = $quizattemptsalias.quiz AND
|
||||
qa2.userid = $quizattemptsalias.userid)";
|
||||
return "$quizattemptsalias.attempt = 1";
|
||||
|
||||
case QUIZ_ATTEMPTLAST :
|
||||
return "$quizattemptsalias.id = (
|
||||
SELECT MAX(qa2.id)
|
||||
FROM {quiz_attempts} qa2
|
||||
WHERE qa2.quiz = $quizattemptsalias.quiz AND
|
||||
qa2.userid = $quizattemptsalias.userid)";
|
||||
SELECT MAX(qa2.id)
|
||||
FROM {quiz_attempts} qa2
|
||||
WHERE qa2.quiz = $quizattemptsalias.quiz AND
|
||||
qa2.userid = $quizattemptsalias.userid)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nuber of students whose score was in a particular band for this quiz.
|
||||
* Get the number of students whose score was in a particular band for this quiz.
|
||||
* @param number $bandwidth the width of each band.
|
||||
* @param int $bands the number of bands
|
||||
* @param int $quizid the quiz id.
|
||||
@@ -225,10 +237,10 @@ ORDER BY
|
||||
$data = $DB->get_records_sql_menu($sql, $params);
|
||||
|
||||
// We need to create array elements with values 0 at indexes where there is no element.
|
||||
$data = $data + array_fill(0, $bands + 1, 0);
|
||||
$data = $data + array_fill(0, $bands + 1, 0);
|
||||
ksort($data);
|
||||
|
||||
// Place the maximum (prefect grade) into the last band i.e. make last
|
||||
// Place the maximum (perfect grade) into the last band i.e. make last
|
||||
// band for example 9 <= g <=10 (where 10 is the perfect grade) rather than
|
||||
// just 9 <= g <10.
|
||||
$data[$bands - 1] += $data[$bands];
|
||||
|
||||
@@ -28,16 +28,24 @@
|
||||
*/
|
||||
class quiz_statistics_calculated {
|
||||
|
||||
public function __construct($allattempts = null) {
|
||||
if ($allattempts !== null) {
|
||||
$this->allattempts = $allattempts;
|
||||
/**
|
||||
* @param string $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student,
|
||||
* the default null value is used when constructing an instance whose values will be
|
||||
* populated from a db record.
|
||||
*/
|
||||
public function __construct($whichattempts = null) {
|
||||
if ($whichattempts !== null) {
|
||||
$this->whichattempts = $whichattempts;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool whether we are calculating calculate stats from all attempts.
|
||||
* @var int which attempts we are calculating calculate stats from.
|
||||
*/
|
||||
public $allattempts;
|
||||
public $whichattempts;
|
||||
|
||||
/* Following stats all described here : http://docs.moodle.org/dev/Quiz_statistics_calculations#Test_statistics */
|
||||
|
||||
@@ -45,10 +53,18 @@ class quiz_statistics_calculated {
|
||||
|
||||
public $allattemptscount = 0;
|
||||
|
||||
public $lastattemptscount = 0;
|
||||
|
||||
public $highestattemptscount = 0;
|
||||
|
||||
public $firstattemptsavg;
|
||||
|
||||
public $allattemptsavg;
|
||||
|
||||
public $lastattemptsavg;
|
||||
|
||||
public $highestattemptsavg;
|
||||
|
||||
public $median;
|
||||
|
||||
public $standarddeviation;
|
||||
@@ -68,20 +84,34 @@ class quiz_statistics_calculated {
|
||||
*/
|
||||
public $timemodified;
|
||||
|
||||
/**
|
||||
* Count of attempts selected by $this->whichattempts
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function s() {
|
||||
if ($this->allattempts) {
|
||||
return $this->allattemptscount;
|
||||
} else {
|
||||
return $this->firstattemptscount;
|
||||
}
|
||||
return $this->get_field('count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Average grade for the attempts selected by $this->whichattempts
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function avg() {
|
||||
if ($this->allattempts) {
|
||||
return $this->allattemptsavg;
|
||||
} else {
|
||||
return $this->firstattemptsavg;
|
||||
}
|
||||
return $this->get_field('avg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right field name to fetch a stat for these attempts that is calculated for more than one $whichattempts (count or
|
||||
* avg).
|
||||
*
|
||||
* @param string $field name of field
|
||||
* @return int|float
|
||||
*/
|
||||
protected function get_field($field) {
|
||||
$fieldname = quiz_statistics_calculator::using_attempts_string_id($this->whichattempts).$field;
|
||||
return $this->{$fieldname};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +127,8 @@ class quiz_statistics_calculated {
|
||||
'allattemptscount' => 'number',
|
||||
'firstattemptsavg' => 'summarks_as_percentage',
|
||||
'allattemptsavg' => 'summarks_as_percentage',
|
||||
'lastattemptsavg' => 'summarks_as_percentage',
|
||||
'highestattemptsavg' => 'summarks_as_percentage',
|
||||
'median' => 'summarks_as_percentage',
|
||||
'standarddeviation' => 'summarks_as_percentage',
|
||||
'skewness' => 'number_format',
|
||||
@@ -149,27 +181,18 @@ class quiz_statistics_calculated {
|
||||
$formattedvalue = $value;
|
||||
}
|
||||
|
||||
$quizinfo[get_string($property, 'quiz_statistics', $this->using_attempts_string())] = $formattedvalue;
|
||||
$quizinfo[get_string($property, 'quiz_statistics',
|
||||
quiz_statistics_calculator::using_attempts_lang_string($this->whichattempts))] = $formattedvalue;
|
||||
}
|
||||
|
||||
return $quizinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the appropriate lang string to describe this option.
|
||||
*/
|
||||
protected function using_attempts_string() {
|
||||
if ($this->allattempts) {
|
||||
return get_string('allattempts', 'quiz_statistics');
|
||||
} else {
|
||||
return get_string('firstattempts', 'quiz_statistics');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array of names of properties of this class that are cached in db record.
|
||||
*/
|
||||
protected $fieldsindb = array('allattempts', 'firstattemptscount', 'allattemptscount', 'firstattemptsavg', 'allattemptsavg',
|
||||
protected $fieldsindb = array('whichattempts', 'firstattemptscount', 'allattemptscount', 'firstattemptsavg', 'allattemptsavg',
|
||||
'lastattemptscount', 'highestattemptscount', 'lastattemptsavg', 'highestattemptsavg',
|
||||
'median', 'standarddeviation', 'skewness',
|
||||
'kurtosis', 'cic', 'errorratio', 'standarderror');
|
||||
|
||||
|
||||
@@ -32,16 +32,26 @@ class quiz_statistics_calculator {
|
||||
* Compute the quiz statistics.
|
||||
*
|
||||
* @param int $quizid the quiz id.
|
||||
* @param int $currentgroup the current group. 0 for none.
|
||||
* @param bool $useallattempts use all attempts, or just first attempts.
|
||||
* @param int $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @param array $groupstudents students in this group.
|
||||
* @param int $p number of positions (slots).
|
||||
* @param float $sumofmarkvariance sum of mark variance, calculated as part of question statistics
|
||||
* @return quiz_statistics_calculated $quizstats The statistics for overall attempt scores.
|
||||
*/
|
||||
public function calculate($quizid, $currentgroup, $useallattempts, $groupstudents, $p, $sumofmarkvariance) {
|
||||
public function calculate($quizid, $whichattempts, $groupstudents, $p, $sumofmarkvariance) {
|
||||
|
||||
$quizstats = $this->attempt_counts_and_averages($quizid, $currentgroup, $useallattempts, $groupstudents);
|
||||
|
||||
|
||||
$quizstats = new quiz_statistics_calculated($whichattempts);
|
||||
|
||||
$countsandaverages = $this->attempt_counts_and_averages($quizid, $groupstudents);
|
||||
|
||||
foreach ($countsandaverages as $propertyname => $value) {
|
||||
$quizstats->{$propertyname} = $value;
|
||||
}
|
||||
|
||||
$s = $quizstats->s();
|
||||
|
||||
@@ -51,7 +61,7 @@ class quiz_statistics_calculator {
|
||||
|
||||
// Recalculate sql again this time possibly including test for first attempt.
|
||||
list($fromqa, $whereqa, $qaparams) =
|
||||
quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents, $useallattempts);
|
||||
quiz_statistics_attempts_sql($quizid, $groupstudents, $whichattempts);
|
||||
|
||||
$quizstats->median = $this->median($s, $fromqa, $whereqa, $qaparams);
|
||||
|
||||
@@ -80,7 +90,7 @@ class quiz_statistics_calculator {
|
||||
}
|
||||
|
||||
if ($p > 1) {
|
||||
$quizstats->cic = (100 * $p / ($p -1)) * (1 - ($sumofmarkvariance / $k2));
|
||||
$quizstats->cic = (100 * $p / ($p - 1)) * (1 - ($sumofmarkvariance / $k2));
|
||||
$quizstats->errorratio = 100 * sqrt(1 - ($quizstats->cic / 100));
|
||||
$quizstats->standarderror = $quizstats->errorratio *
|
||||
$quizstats->standarddeviation / 100;
|
||||
@@ -90,7 +100,7 @@ class quiz_statistics_calculator {
|
||||
}
|
||||
}
|
||||
|
||||
$quizstats->cache(quiz_statistics_qubaids_condition($quizid, $currentgroup, $groupstudents, $useallattempts));
|
||||
$quizstats->cache(quiz_statistics_qubaids_condition($quizid, $groupstudents, $whichattempts));
|
||||
|
||||
return $quizstats;
|
||||
}
|
||||
@@ -129,61 +139,88 @@ class quiz_statistics_calculator {
|
||||
array($qubaids->get_hash_code(), $timemodified));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a particular quiz grading method return a lang string describing which attempts contribute to grade.
|
||||
*
|
||||
* Note internally we use the grading method constants to represent which attempts we are calculating statistics for, each
|
||||
* grading method corresponds to different attempts for each user.
|
||||
*
|
||||
* @param int $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @return string the appropriate lang string to describe this option.
|
||||
*/
|
||||
public static function using_attempts_lang_string($whichattempts) {
|
||||
return get_string(static::using_attempts_string_id($whichattempts), 'quiz_statistics');
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a particular quiz grading method return a string id for use as a field name prefix in mdl_quiz_statistics or to
|
||||
* fetch the appropriate language string describing which attempts contribute to grade.
|
||||
*
|
||||
* Note internally we use the grading method constants to represent which attempts we are calculating statistics for, each
|
||||
* grading method corresponds to different attempts for each user.
|
||||
*
|
||||
* @param int $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @return string the string id for this option.
|
||||
*/
|
||||
public static function using_attempts_string_id($whichattempts) {
|
||||
switch ($whichattempts) {
|
||||
case QUIZ_ATTEMPTFIRST :
|
||||
return 'firstattempts';
|
||||
case QUIZ_GRADEHIGHEST :
|
||||
return 'highestattempts';
|
||||
case QUIZ_ATTEMPTLAST :
|
||||
return 'lastattempts';
|
||||
case QUIZ_GRADEAVERAGE :
|
||||
return 'allattempts';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculating count and mean of marks for first and ALL attempts by students.
|
||||
*
|
||||
* See : http://docs.moodle.org/dev/Quiz_item_analysis_calculations_in_practise
|
||||
* #Calculating_MEAN_of_grades_for_all_attempts_by_students
|
||||
* @param int $quizid
|
||||
* @param int $currentgroup
|
||||
* @param bool $useallattempts
|
||||
* @param array $groupstudents
|
||||
* @return quiz_statistics_calculated containing calculated counts, totals and averages.
|
||||
* @return stdClass with properties with count and avg with prefixes firstattempts, highestattempts, etc.
|
||||
*/
|
||||
protected function attempt_counts_and_averages($quizid, $currentgroup, $useallattempts, $groupstudents) {
|
||||
protected function attempt_counts_and_averages($quizid, $groupstudents) {
|
||||
global $DB;
|
||||
|
||||
$quizstats = new quiz_statistics_calculated($useallattempts);
|
||||
list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql($quizid, $groupstudents);
|
||||
|
||||
list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents, true);
|
||||
$selects = array();
|
||||
foreach (array_keys(quiz_get_grading_options()) as $which) {
|
||||
$fieldprefix = static::using_attempts_string_id($which);
|
||||
$condition = quiz_report_grade_method_sql($which);
|
||||
if ($condition == '') {
|
||||
$case = '1';
|
||||
} else {
|
||||
$case = "CASE WHEN ($condition) THEN 1 ELSE 0 END";
|
||||
}
|
||||
$selects[] = "
|
||||
SUM($case) AS {$fieldprefix}count,
|
||||
SUM(sumgrades * $case) AS {$fieldprefix}total";
|
||||
}
|
||||
$select = join(',', $selects);
|
||||
|
||||
$attempttotals = $DB->get_records_sql("
|
||||
SELECT
|
||||
CASE WHEN attempt = 1 THEN 1 ELSE 0 END AS isfirst,
|
||||
COUNT(1) AS countrecs,
|
||||
SUM(sumgrades) AS total
|
||||
$attempttotals = $DB->get_record_sql("
|
||||
SELECT {$select}
|
||||
FROM $fromqa
|
||||
WHERE $whereqa
|
||||
GROUP BY CASE WHEN attempt = 1 THEN 1 ELSE 0 END", $qaparams);
|
||||
WHERE $whereqa", $qaparams);
|
||||
|
||||
// Above query that returns sums and counts for first attempt and other non first attempts.
|
||||
// We want to work out stats for first attempt or ALL attempts.
|
||||
|
||||
if (isset($attempttotals[1])) {
|
||||
$quizstats->firstattemptscount = $attempttotals[1]->countrecs;
|
||||
$firstattemptstotal = $attempttotals[1]->total;
|
||||
} else {
|
||||
$quizstats->firstattemptscount = 0;
|
||||
$firstattemptstotal = 0;
|
||||
foreach (array_keys(quiz_get_grading_options()) as $which) {
|
||||
$fieldprefix = static::using_attempts_string_id($which);
|
||||
$attempttotals->{$fieldprefix.'avg'} = $attempttotals->{$fieldprefix.'total'} / $attempttotals->{$fieldprefix.'count'};
|
||||
unset($attempttotals->{$fieldprefix.'total'});
|
||||
}
|
||||
|
||||
if (isset($attempttotals[0])) {
|
||||
$quizstats->allattemptscount = $quizstats->firstattemptscount + $attempttotals[0]->countrecs;
|
||||
$allattemptstotal = $firstattemptstotal + $attempttotals[0]->total;
|
||||
} else {
|
||||
$quizstats->allattemptscount = $quizstats->firstattemptscount;
|
||||
$allattemptstotal = $firstattemptstotal;
|
||||
}
|
||||
|
||||
if ($quizstats->allattemptscount !== 0) {
|
||||
$quizstats->allattemptsavg = $allattemptstotal / $quizstats->allattemptscount;
|
||||
}
|
||||
|
||||
if ($quizstats->firstattemptscount !== 0) {
|
||||
$quizstats->firstattemptsavg = $firstattemptstotal / $quizstats->firstattemptscount;
|
||||
}
|
||||
|
||||
return $quizstats;
|
||||
return $attempttotals;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,11 +8,15 @@
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="hashcode" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false" COMMENT="sha1 hash of serialized qubaids_condition class. Unique for every combination of class name and property."/>
|
||||
<FIELD NAME="allattempts" TYPE="int" LENGTH="4" NOTNULL="true" SEQUENCE="false" COMMENT="bool used to indicate whether these stats are for all attempts or just for the first."/>
|
||||
<FIELD NAME="whichattempts" TYPE="int" LENGTH="4" NOTNULL="true" SEQUENCE="false" COMMENT="bool used to indicate whether these stats are for all attempts or just for the first."/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="firstattemptscount" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="highestattemptscount" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="lastattemptscount" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="allattemptscount" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="firstattemptsavg" TYPE="number" LENGTH="15" NOTNULL="false" SEQUENCE="false" DECIMALS="5"/>
|
||||
<FIELD NAME="highestattemptsavg" TYPE="number" LENGTH="15" NOTNULL="false" SEQUENCE="false" DECIMALS="5"/>
|
||||
<FIELD NAME="lastattemptsavg" TYPE="number" LENGTH="15" NOTNULL="false" SEQUENCE="false" DECIMALS="5"/>
|
||||
<FIELD NAME="allattemptsavg" TYPE="number" LENGTH="15" NOTNULL="false" SEQUENCE="false" DECIMALS="5"/>
|
||||
<FIELD NAME="median" TYPE="number" LENGTH="15" NOTNULL="false" SEQUENCE="false" DECIMALS="5"/>
|
||||
<FIELD NAME="standarddeviation" TYPE="number" LENGTH="15" NOTNULL="false" SEQUENCE="false" DECIMALS="5"/>
|
||||
|
||||
@@ -85,6 +85,51 @@ function xmldb_quiz_statistics_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2013092000, 'quiz', 'statistics');
|
||||
}
|
||||
|
||||
if ($oldversion < 2013093000) {
|
||||
// Define table quiz_statistics to be dropped.
|
||||
$table = new xmldb_table('quiz_statistics');
|
||||
|
||||
// Conditionally launch drop table for quiz_statistics.
|
||||
if ($dbman->table_exists($table)) {
|
||||
$dbman->drop_table($table);
|
||||
}
|
||||
|
||||
// Define table quiz_statistics to be created.
|
||||
$table = new xmldb_table('quiz_statistics');
|
||||
|
||||
// Adding fields to table quiz_statistics.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
||||
$table->add_field('hashcode', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('whichattempts', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('firstattemptscount', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('highestattemptscount', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('lastattemptscount', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('allattemptscount', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('firstattemptsavg', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('highestattemptsavg', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('lastattemptsavg', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('allattemptsavg', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('median', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('standarddeviation', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('skewness', XMLDB_TYPE_NUMBER, '15, 10', null, null, null, null);
|
||||
$table->add_field('kurtosis', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
|
||||
$table->add_field('cic', XMLDB_TYPE_NUMBER, '15, 10', null, null, null, null);
|
||||
$table->add_field('errorratio', XMLDB_TYPE_NUMBER, '15, 10', null, null, null, null);
|
||||
$table->add_field('standarderror', XMLDB_TYPE_NUMBER, '15, 10', null, null, null, null);
|
||||
|
||||
// Adding keys to table quiz_statistics.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
||||
|
||||
// Conditionally launch create table for quiz_statistics.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Statistics savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2013093000, 'quiz', 'statistics');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,12 @@ $string['firstattempts'] = 'first attempts';
|
||||
$string['firstattemptsavg'] = 'Average grade of first attempts';
|
||||
$string['firstattemptscount'] = 'Number of complete graded first attempts';
|
||||
$string['frequency'] = 'Frequency';
|
||||
$string['highestattempts'] = 'highest graded attempt';
|
||||
$string['highestattemptsavg'] = 'Average grade of highest graded attempts';
|
||||
$string['intended_weight'] = 'Intended weight';
|
||||
$string['kurtosis'] = 'Score distribution kurtosis (for {$a})';
|
||||
$string['lastattempts'] = 'last attempt';
|
||||
$string['lastattemptsavg'] = 'Average grade of last attempts';
|
||||
$string['lastcalculated'] = 'Last calculated {$a->lastcalculated} ago there have been {$a->count} attempts since then.';
|
||||
$string['median'] = 'Median grade (for {$a})';
|
||||
$string['modelresponse'] = 'Model response';
|
||||
@@ -85,6 +89,7 @@ $string['quizoverallstatistics'] = 'Quiz overall statistics';
|
||||
$string['quizstructureanalysis'] = 'Quiz structure analysis';
|
||||
$string['random_guess_score'] = 'Random guess score';
|
||||
$string['recalculatenow'] = 'Recalculate now';
|
||||
$string['reportsettings'] = 'Statistics calculation settings';
|
||||
$string['response'] = 'Response';
|
||||
$string['skewness'] = 'Score distribution skewness (for {$a})';
|
||||
$string['standarddeviation'] = 'Standard deviation (for {$a})';
|
||||
|
||||
@@ -61,6 +61,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
// A qid paramter indicates we should display the detailed analysis of a sub question.
|
||||
$qid = optional_param('qid', 0, PARAM_INT);
|
||||
$slot = optional_param('slot', 0, PARAM_INT);
|
||||
$whichattempts = optional_param('whichattempts', $quiz->grademethod, PARAM_INT);
|
||||
|
||||
$pageoptions = array();
|
||||
$pageoptions['id'] = $cm->id;
|
||||
@@ -69,17 +70,15 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
$reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions);
|
||||
|
||||
$mform = new quiz_statistics_settings_form($reporturl);
|
||||
if ($fromform = $mform->get_data()) {
|
||||
$useallattempts = $fromform->useallattempts;
|
||||
if ($fromform->useallattempts) {
|
||||
set_user_preference('quiz_report_statistics_useallattempts',
|
||||
$fromform->useallattempts);
|
||||
} else {
|
||||
unset_user_preference('quiz_report_statistics_useallattempts');
|
||||
}
|
||||
|
||||
} else {
|
||||
$useallattempts = get_user_preferences('quiz_report_statistics_useallattempts', 0);
|
||||
$mform->set_data(array('whichattempts' => $whichattempts));
|
||||
|
||||
if ($fromform = $mform->get_data()) {
|
||||
$whichattempts = $fromform->whichattempts;
|
||||
}
|
||||
|
||||
if ($whichattempts != $quiz->grademethod) {
|
||||
$reporturl->param('whichattempts', $whichattempts);
|
||||
}
|
||||
|
||||
// Find out current groups mode.
|
||||
@@ -103,7 +102,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
}
|
||||
}
|
||||
|
||||
$qubaids = quiz_statistics_qubaids_condition($quiz->id, $currentgroup, $groupstudents, $useallattempts);
|
||||
$qubaids = quiz_statistics_qubaids_condition($quiz->id, $groupstudents, $whichattempts);
|
||||
|
||||
// If recalculate was requested, handle that.
|
||||
if ($recalculate && confirm_sesskey()) {
|
||||
@@ -128,10 +127,10 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
if (!$nostudentsingroup) {
|
||||
// Get the data to be displayed.
|
||||
list($quizstats, $questionstats, $subquestionstats) =
|
||||
$this->get_quiz_and_questions_stats($quiz, $currentgroup, $useallattempts, $groupstudents, $questions);
|
||||
$this->get_quiz_and_questions_stats($quiz, $whichattempts, $groupstudents, $questions);
|
||||
} else {
|
||||
// Or create empty stats containers.
|
||||
$quizstats = new quiz_statistics_calculated($useallattempts);
|
||||
$quizstats = new quiz_statistics_calculated($whichattempts);
|
||||
$questionstats = array();
|
||||
$subquestionstats = array();
|
||||
}
|
||||
@@ -159,7 +158,6 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
}
|
||||
|
||||
// Print display options form.
|
||||
$mform->set_data(array('useallattempts' => $useallattempts));
|
||||
$mform->display();
|
||||
}
|
||||
|
||||
@@ -172,7 +170,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
$this->output_quiz_structure_analysis_table($quizstats->s(), $questionstats, $subquestionstats);
|
||||
|
||||
if ($this->table->is_downloading() == 'xhtml' && $quizstats->s() != 0) {
|
||||
$this->output_statistics_graph($quiz->id, $currentgroup, $useallattempts);
|
||||
$this->output_statistics_graph($quiz->id, $currentgroup, $whichattempts);
|
||||
}
|
||||
|
||||
foreach ($questions as $slot => $question) {
|
||||
@@ -232,15 +230,14 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
} else {
|
||||
// On-screen display of overview report.
|
||||
echo $OUTPUT->heading(get_string('quizinformation', 'quiz_statistics'));
|
||||
echo $this->output_caching_info($quizstats, $quiz->id, $currentgroup,
|
||||
$groupstudents, $useallattempts, $reporturl);
|
||||
echo $this->output_caching_info($quizstats, $quiz->id, $groupstudents, $whichattempts, $reporturl);
|
||||
echo $this->everything_download_options();
|
||||
$quizinfo = $quizstats->get_formatted_quiz_info_data($course, $cm, $quiz);
|
||||
echo $this->output_quiz_info_table($quizinfo);
|
||||
if ($quizstats->s()) {
|
||||
echo $OUTPUT->heading(get_string('quizstructureanalysis', 'quiz_statistics'));
|
||||
$this->output_quiz_structure_analysis_table($quizstats->s(), $questionstats, $subquestionstats);
|
||||
$this->output_statistics_graph($quiz->id, $currentgroup, $useallattempts);
|
||||
$this->output_statistics_graph($quiz->id, $currentgroup, $whichattempts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,14 +468,14 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
* Output the HTML needed to show the statistics graph.
|
||||
* @param $quizid
|
||||
* @param $currentgroup
|
||||
* @param $useallattempts
|
||||
* @param $whichattempts
|
||||
*/
|
||||
protected function output_statistics_graph($quizid, $currentgroup, $useallattempts) {
|
||||
protected function output_statistics_graph($quizid, $currentgroup, $whichattempts) {
|
||||
global $PAGE;
|
||||
|
||||
$output = $PAGE->get_renderer('mod_quiz');
|
||||
$imageurl = new moodle_url('/mod/quiz/report/statistics/statistics_graph.php',
|
||||
compact('quizid', 'currentgroup', 'useallattempts'));
|
||||
compact('quizid', 'currentgroup', 'whichattempts'));
|
||||
$graphname = get_string('statisticsreportgraph', 'quiz_statistics');
|
||||
echo $output->graph($imageurl, $graphname);
|
||||
}
|
||||
@@ -488,18 +485,20 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
* or by recomputing them.
|
||||
*
|
||||
* @param object $quiz the quiz settings.
|
||||
* @param int $currentgroup the current group. 0 for none.
|
||||
* @param bool $useallattempts use all attempts, or just first attempts.
|
||||
* @param string $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @param array $groupstudents students in this group.
|
||||
* @param array $questions question definitions.
|
||||
* @param array $questions full question data.
|
||||
* @return array with 4 elements:
|
||||
* - $quizstats The statistics for overall attempt scores.
|
||||
* - $questionstats array of \core_question\statistics\questions\calculated objects keyed by slot.
|
||||
* - $subquestionstats array of \core_question\statistics\questions\calculated_for_subquestion objects keyed by question id.
|
||||
*/
|
||||
protected function get_quiz_and_questions_stats($quiz, $currentgroup, $useallattempts, $groupstudents, $questions) {
|
||||
protected function get_quiz_and_questions_stats($quiz, $whichattempts, $groupstudents, $questions) {
|
||||
|
||||
$qubaids = quiz_statistics_qubaids_condition($quiz->id, $currentgroup, $groupstudents, $useallattempts);
|
||||
$qubaids = quiz_statistics_qubaids_condition($quiz->id, $groupstudents, $whichattempts);
|
||||
|
||||
$qcalc = new \core_question\statistics\questions\calculator($questions);
|
||||
|
||||
@@ -509,8 +508,8 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
// Recalculate now.
|
||||
list($questionstats, $subquestionstats) = $qcalc->calculate($qubaids);
|
||||
|
||||
$quizstats = $quizcalc->calculate($quiz->id, $currentgroup, $useallattempts,
|
||||
$groupstudents, count($questions), $qcalc->get_sum_of_mark_variance());
|
||||
$quizstats = $quizcalc->calculate($quiz->id, $whichattempts, $groupstudents, count($questions),
|
||||
$qcalc->get_sum_of_mark_variance());
|
||||
|
||||
if ($quizstats->s()) {
|
||||
$this->analyse_responses_for_all_questions_and_subquestions($qubaids, $questions, $subquestionstats);
|
||||
@@ -574,16 +573,16 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
* with a recalcuate now button.
|
||||
* @param object $quizstats the overall quiz statistics.
|
||||
* @param int $quizid the quiz id.
|
||||
* @param int $currentgroup the id of the currently selected group, or 0.
|
||||
* @param array $groupstudents ids of students in the group.
|
||||
* @param bool $useallattempts whether to use all attempts, instead of just
|
||||
* first attempts.
|
||||
* @param array $groupstudents ids of students in the group or empty array if groups not used.
|
||||
* @param string $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @param moodle_url $reporturl url for this report
|
||||
* @return string a HTML snipped saying when the stats were last computed,
|
||||
* or blank if that is not appropriate.
|
||||
*/
|
||||
protected function output_caching_info($quizstats, $quizid, $currentgroup,
|
||||
$groupstudents, $useallattempts, $reporturl) {
|
||||
protected function output_caching_info($quizstats, $quizid, $groupstudents, $whichattempts, $reporturl) {
|
||||
global $DB, $OUTPUT;
|
||||
|
||||
if (empty($quizstats->timemodified)) {
|
||||
@@ -591,8 +590,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
}
|
||||
|
||||
// Find the number of attempts since the cached statistics were computed.
|
||||
list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql(
|
||||
$quizid, $currentgroup, $groupstudents, $useallattempts, true);
|
||||
list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql($quizid, $groupstudents, $whichattempts, true);
|
||||
$count = $DB->count_records_sql("
|
||||
SELECT COUNT(1)
|
||||
FROM $fromqa
|
||||
|
||||
@@ -36,17 +36,15 @@ class quiz_statistics_settings_form extends moodleform {
|
||||
protected function definition() {
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('header', 'preferencespage',
|
||||
get_string('preferencespage', 'quiz_overview'));
|
||||
$mform->addElement('header', 'preferencespage', get_string('reportsettings', 'quiz_statistics'));
|
||||
|
||||
$options = array();
|
||||
$options[0] = get_string('attemptsfirst', 'quiz_statistics');
|
||||
$options[1] = get_string('attemptsall', 'quiz_statistics');
|
||||
$mform->addElement('select', 'useallattempts',
|
||||
get_string('calculatefrom', 'quiz_statistics'), $options);
|
||||
$mform->setDefault('useallattempts', 0);
|
||||
foreach (array_keys(quiz_get_grading_options()) as $which) {
|
||||
$options[$which] = \quiz_statistics_calculator::using_attempts_lang_string($which);
|
||||
}
|
||||
|
||||
$mform->addElement('submit', 'submitbutton',
|
||||
get_string('preferencessave', 'quiz_overview'));
|
||||
$mform->addElement('select', 'whichattempts', get_string('calculatefrom', 'quiz_statistics'), $options);
|
||||
|
||||
$mform->addElement('submit', 'submitbutton', get_string('preferencessave', 'quiz_overview'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ require_once($CFG->dirroot . '/mod/quiz/report/statistics/statisticslib.php');
|
||||
// Get the parameters.
|
||||
$quizid = required_param('quizid', PARAM_INT);
|
||||
$currentgroup = required_param('currentgroup', PARAM_INT);
|
||||
$useallattempts = required_param('useallattempts', PARAM_INT);
|
||||
$whichattempts = required_param('whichattempts', PARAM_INT);
|
||||
|
||||
$quiz = $DB->get_record('quiz', array('id' => $quizid), '*', MUST_EXIST);
|
||||
$cm = get_coursemodule_from_instance('quiz', $quiz->id);
|
||||
@@ -55,10 +55,14 @@ if (groups_get_activity_groupmode($cm)) {
|
||||
if ($currentgroup && !in_array($currentgroup, array_keys($groups))) {
|
||||
print_error('groupnotamember', 'group');
|
||||
}
|
||||
$groupstudents = get_users_by_capability($modcontext, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'),
|
||||
'', '', '', '', $currentgroup, '', false);
|
||||
|
||||
$qubaids = quiz_statistics_qubaids_condition($quizid, $currentgroup, $groupstudents, $useallattempts);
|
||||
if (empty($currentgroup)) {
|
||||
$groupstudents = array();
|
||||
} else {
|
||||
$groupstudents = get_users_by_capability($modcontext, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'),
|
||||
'', '', '', '', $currentgroup, '', false);
|
||||
}
|
||||
$qubaids = quiz_statistics_qubaids_condition($quizid, $groupstudents, $whichattempts);
|
||||
|
||||
// Load the rest of the required data.
|
||||
$questions = quiz_report_get_significant_questions($quiz);
|
||||
|
||||
@@ -23,8 +23,19 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
function quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents,
|
||||
$allattempts = true, $includeungraded = false) {
|
||||
/**
|
||||
* SQL to fetch relevant 'quiz_attempts' records.
|
||||
*
|
||||
* @param int $quizid quiz id to get attempts for
|
||||
* @param array $groupstudents empty array if not using groups or array of students in current group.
|
||||
* @param string $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @param bool $includeungraded whether to fetch ungraded attempts too
|
||||
* @return array FROM and WHERE sql fragments and sql params
|
||||
*/
|
||||
function quiz_statistics_attempts_sql($quizid, $groupstudents, $whichattempts = QUIZ_GRADEAVERAGE, $includeungraded = false) {
|
||||
global $DB;
|
||||
|
||||
$fromqa = '{quiz_attempts} quiza ';
|
||||
@@ -32,15 +43,17 @@ function quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents,
|
||||
$whereqa = 'quiza.quiz = :quizid AND quiza.preview = 0 AND quiza.state = :quizstatefinished';
|
||||
$qaparams = array('quizid' => (int)$quizid, 'quizstatefinished' => quiz_attempt::FINISHED);
|
||||
|
||||
if (!empty($currentgroup) && $groupstudents) {
|
||||
if ($groupstudents) {
|
||||
ksort($groupstudents);
|
||||
list($grpsql, $grpparams) = $DB->get_in_or_equal(array_keys($groupstudents),
|
||||
SQL_PARAMS_NAMED, 'u');
|
||||
$whereqa .= " AND quiza.userid $grpsql";
|
||||
$qaparams += $grpparams;
|
||||
}
|
||||
|
||||
if (!$allattempts) {
|
||||
$whereqa .= ' AND quiza.attempt = 1';
|
||||
$whichattemptsql = quiz_report_grade_method_sql($whichattempts);
|
||||
if ($whichattemptsql) {
|
||||
$whereqa .= ' AND '.$whichattemptsql;
|
||||
}
|
||||
|
||||
if (!$includeungraded) {
|
||||
@@ -54,16 +67,16 @@ function quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents,
|
||||
* Return a {@link qubaid_condition} from the values returned by {@link quiz_statistics_attempts_sql}.
|
||||
*
|
||||
* @param int $quizid
|
||||
* @param int $currentgroup
|
||||
* @param array $groupstudents
|
||||
* @param bool $allattempts
|
||||
* @param string $whichattempts which attempts to use, represented internally as one of the constants as used in
|
||||
* $quiz->grademethod ie.
|
||||
* QUIZ_GRADEAVERAGE, QUIZ_GRADEHIGHEST, QUIZ_ATTEMPTLAST or QUIZ_ATTEMPTFIRST
|
||||
* we calculate stats based on which attempts would affect the grade for each student.
|
||||
* @param bool $includeungraded
|
||||
* @return \qubaid_join
|
||||
*/
|
||||
function quiz_statistics_qubaids_condition($quizid, $currentgroup, $groupstudents,
|
||||
$allattempts = true, $includeungraded = false) {
|
||||
list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql($quizid, $currentgroup,
|
||||
$groupstudents, $allattempts, $includeungraded);
|
||||
function quiz_statistics_qubaids_condition($quizid, $groupstudents, $whichattempts = QUIZ_GRADEAVERAGE, $includeungraded = false) {
|
||||
list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql($quizid, $groupstudents, $whichattempts, $includeungraded);
|
||||
return new qubaid_join($fromqa, 'quiza.uniqueid', $whereqa, $qaparams);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,11 @@ require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
|
||||
*/
|
||||
class testable_quiz_statistics_report extends quiz_statistics_report {
|
||||
|
||||
public function get_stats($quiz, $useallattempts = true,
|
||||
$currentgroup = 0, $groupstudents = array(), $nostudentsingroup = false) {
|
||||
$qubaids = quiz_statistics_qubaids_condition($quiz->id, $currentgroup, $groupstudents, $useallattempts);
|
||||
public function get_stats($quiz, $whichattempts = QUIZ_GRADEAVERAGE, $groupstudents = array()) {
|
||||
$qubaids = quiz_statistics_qubaids_condition($quiz->id, $groupstudents, $whichattempts);
|
||||
$this->clear_cached_data($qubaids);
|
||||
$questions = $this->load_and_initialise_questions_for_calculations($quiz);
|
||||
return $this->get_quiz_and_questions_stats($quiz, $currentgroup, $useallattempts, $groupstudents, $questions);
|
||||
return $this->get_quiz_and_questions_stats($quiz, $whichattempts, $groupstudents, $questions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2013092000;
|
||||
$plugin->requires = 2013092000;
|
||||
$plugin->version = 2013093000;
|
||||
$plugin->requires = 2013092700;
|
||||
$plugin->cron = 18000;
|
||||
$plugin->component = 'quiz_statistics';
|
||||
|
||||
Reference in New Issue
Block a user