mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
Merge branch 'MDL-65175_master' of git://github.com/dmonllao/moodle
This commit is contained in:
commit
30a09fc94c
@ -75,7 +75,7 @@ if ($hassiteconfig) {
|
||||
$defaultreader, $options));
|
||||
|
||||
// Enable/disable time splitting methods.
|
||||
$alltimesplittings = \core_analytics\manager::get_all_time_splittings();
|
||||
$alltimesplittings = \core_analytics\manager::get_time_splitting_methods_for_evaluation(true);
|
||||
|
||||
$timesplittingoptions = array();
|
||||
$timesplittingdefaults = array('\core\analytics\time_splitting\quarters_accum',
|
||||
|
2
admin/tool/analytics/amd/build/model.min.js
vendored
2
admin/tool/analytics/amd/build/model.min.js
vendored
@ -1 +1 @@
|
||||
define(["jquery","core/str","core/log","core/notification","core/modal_factory","core/modal_events","core/templates"],function(a,b,c,d,e,f,g){var h={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},"delete":{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}},i=function(b){return a(b.closest("tr")[0]).find("span.target-name").text()};return{confirmAction:function(g,j){a('[data-action-id="'+g+'"]').on("click",function(g){g.preventDefault();var k=a(g.currentTarget);if("undefined"==typeof h[j])return void c.error('Action "'+j+'" is not allowed.');var l=[h[j].title,h[j].body];l[1].param=i(k);var m=b.get_strings(l),n=e.create({type:e.types.SAVE_CANCEL});a.when(m,n).then(function(a,b){return b.setTitle(a[0]),b.setBody(a[1]),b.setSaveButtonText(a[0]),b.getRoot().on(f.save,function(){window.location.href=k.attr("href")}),b.show(),b}).fail(d.exception)})},selectEvaluationMode:function(c,h){a('[data-action-id="'+c+'"]').on("click",function(c){c.preventDefault();var i=a(c.currentTarget);if(!h)return void(window.location.href=i.attr("href"));var j=b.get_strings([{key:"evaluatemodel",component:"tool_analytics"},{key:"evaluationmode",component:"tool_analytics"}]),k=e.create({type:e.types.SAVE_CANCEL}),l=g.render("tool_analytics/evaluation_mode_selection",{});a.when(j,k).then(function(b,c){return c.getRoot().on(f.hidden,c.destroy.bind(c)),c.setTitle(b[1]),c.setSaveButtonText(b[0]),c.setBody(l),c.getRoot().on(f.save,function(){var b=a("input[name='evaluationmode']:checked").val();"trainedmodel"==b&&i.attr("href",i.attr("href")+"&mode=trainedmodel"),window.location.href=i.attr("href")}),c.show(),c}).fail(d.exception)})},selectExportOptions:function(c,h){a('[data-action-id="'+c+'"]').on("click",function(c){c.preventDefault();var i=a(c.currentTarget);if(!h)return i.attr("href",i.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=i.attr("href"));var j=b.get_strings([{key:"export",component:"tool_analytics"}]),k=e.create({type:e.types.SAVE_CANCEL}),l=g.render("tool_analytics/export_options",{});a.when(j,k).then(function(b,c){return c.getRoot().on(f.hidden,c.destroy.bind(c)),c.setTitle(b[0]),c.setSaveButtonText(b[0]),c.setBody(l),c.getRoot().on(f.save,function(){var b=a("input[name='exportoption']:checked").val();"exportdata"==b?i.attr("href",i.attr("href")+"&action=exportdata"):(i.attr("href",i.attr("href")+"&action=exportmodel"),a("#id-includeweights").is(":checked")?i.attr("href",i.attr("href")+"&includeweights=1"):i.attr("href",i.attr("href")+"&includeweights=0")),window.location.href=i.attr("href")}),c.show(),c}).fail(d.exception)})}}});
|
||||
define(["jquery","core/str","core/log","core/notification","core/modal_factory","core/modal_events","core/templates"],function(a,b,c,d,e,f,g){var h={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},"delete":{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}},i=function(b){return a(b.closest("tr")[0]).find("span.target-name").text()};return{confirmAction:function(g,j){a('[data-action-id="'+g+'"]').on("click",function(g){g.preventDefault();var k=a(g.currentTarget);if("undefined"==typeof h[j])return void c.error('Action "'+j+'" is not allowed.');var l=[h[j].title,h[j].body];l[1].param=i(k);var m=b.get_strings(l),n=e.create({type:e.types.SAVE_CANCEL});a.when(m,n).then(function(a,b){return b.setTitle(a[0]),b.setBody(a[1]),b.setSaveButtonText(a[0]),b.getRoot().on(f.save,function(){window.location.href=k.attr("href")}),b.show(),b}).fail(d.exception)})},selectEvaluationOptions:function(c,h,i){a('[data-action-id="'+c+'"]').on("click",function(c){c.preventDefault();var j=a(c.currentTarget),k=b.get_strings([{key:"evaluatemodel",component:"tool_analytics"},{key:"evaluate",component:"tool_analytics"}]),l=e.create({type:e.types.SAVE_CANCEL}),m=g.render("tool_analytics/evaluation_options",{trainedexternally:h,timesplittingmethods:i});a.when(k,l).then(function(b,c){return c.getRoot().on(f.hidden,c.destroy.bind(c)),c.setTitle(b[0]),c.setSaveButtonText(b[1]),c.setBody(m),c.getRoot().on(f.save,function(){var b=a("input[name='evaluationmode']:checked").val();"trainedmodel"==b&&j.attr("href",j.attr("href")+"&mode=trainedmodel");var c=a("#id-evaluation-timesplitting").val();j.attr("href",j.attr("href")+"×plitting="+c),window.location.href=j.attr("href")}),c.show(),c}).fail(d.exception)})},selectExportOptions:function(c,h){a('[data-action-id="'+c+'"]').on("click",function(c){c.preventDefault();var i=a(c.currentTarget);if(!h)return i.attr("href",i.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=i.attr("href"));var j=b.get_strings([{key:"export",component:"tool_analytics"}]),k=e.create({type:e.types.SAVE_CANCEL}),l=g.render("tool_analytics/export_options",{});a.when(j,k).then(function(b,c){return c.getRoot().on(f.hidden,c.destroy.bind(c)),c.setTitle(b[0]),c.setSaveButtonText(b[0]),c.setBody(l),c.getRoot().on(f.save,function(){var b=a("input[name='exportoption']:checked").val();"exportdata"==b?i.attr("href",i.attr("href")+"&action=exportdata"):(i.attr("href",i.attr("href")+"&action=exportmodel"),a("#id-includeweights").is(":checked")?i.attr("href",i.attr("href")+"&includeweights=1"):i.attr("href",i.attr("href")+"&includeweights=0")),window.location.href=i.attr("href")}),c.show(),c}).fail(d.exception)})}}});
|
@ -101,50 +101,53 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays a select-evaluation-mode choice.
|
||||
* Displays evaluation mode and time-splitting method choices.
|
||||
*
|
||||
* @param {String} actionId
|
||||
* @param {Boolean} trainedOnlyExternally
|
||||
*/
|
||||
selectEvaluationMode: function(actionId, trainedOnlyExternally) {
|
||||
selectEvaluationOptions: function(actionId, trainedOnlyExternally, timeSplittingMethods) {
|
||||
$('[data-action-id="' + actionId + '"]').on('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
var a = $(ev.currentTarget);
|
||||
|
||||
if (!trainedOnlyExternally) {
|
||||
// We can not evaluate trained models if the model was trained using data from this site.
|
||||
// Default to evaluate the model configuration if that is the case.
|
||||
window.location.href = a.attr('href');
|
||||
return;
|
||||
}
|
||||
|
||||
var stringsPromise = Str.get_strings([
|
||||
{
|
||||
key: 'evaluatemodel',
|
||||
component: 'tool_analytics'
|
||||
}, {
|
||||
key: 'evaluationmode',
|
||||
key: 'evaluate',
|
||||
component: 'tool_analytics'
|
||||
}
|
||||
]);
|
||||
var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL});
|
||||
var bodyPromise = Templates.render('tool_analytics/evaluation_mode_selection', {});
|
||||
var bodyPromise = Templates.render('tool_analytics/evaluation_options', {
|
||||
trainedexternally: trainedOnlyExternally,
|
||||
timesplittingmethods: timeSplittingMethods
|
||||
});
|
||||
|
||||
$.when(stringsPromise, modalPromise).then(function(strings, modal) {
|
||||
|
||||
|
||||
modal.getRoot().on(ModalEvents.hidden, modal.destroy.bind(modal));
|
||||
|
||||
modal.setTitle(strings[1]);
|
||||
modal.setSaveButtonText(strings[0]);
|
||||
modal.setTitle(strings[0]);
|
||||
modal.setSaveButtonText(strings[1]);
|
||||
modal.setBody(bodyPromise);
|
||||
|
||||
modal.getRoot().on(ModalEvents.save, function() {
|
||||
|
||||
// Evaluation mode.
|
||||
var evaluationMode = $("input[name='evaluationmode']:checked").val();
|
||||
if (evaluationMode == 'trainedmodel') {
|
||||
a.attr('href', a.attr('href') + '&mode=trainedmodel');
|
||||
}
|
||||
|
||||
// Selected time-splitting id.
|
||||
var timeSplittingMethod = $("#id-evaluation-timesplitting").val();
|
||||
a.attr('href', a.attr('href') + '×plitting=' + timeSplittingMethod);
|
||||
|
||||
window.location.href = a.attr('href');
|
||||
return;
|
||||
});
|
||||
|
@ -45,7 +45,7 @@ class helper {
|
||||
// Form field is PARAM_ALPHANUMEXT and we are sending fully qualified class names
|
||||
// as option names, but replacing the backslash for a string that is really unlikely
|
||||
// to ever be part of a class name.
|
||||
return str_replace('\\', '2015102400ouuu', $class);
|
||||
return str_replace('\\', '__', $class);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,7 +56,7 @@ class helper {
|
||||
*/
|
||||
public static function option_to_class($option) {
|
||||
// Really unlikely but yeah, I'm a bad booyyy.
|
||||
return str_replace('2015102400ouuu', '\\', $option);
|
||||
return str_replace('__', '\\', $option);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +71,17 @@ class models_list implements \renderable, \templatable {
|
||||
$onlycli = 1;
|
||||
}
|
||||
|
||||
// Evaluation options.
|
||||
$timesplittingmethods = [
|
||||
['id' => 'all', 'text' => get_string('alltimesplittingmethods', 'tool_analytics')],
|
||||
];
|
||||
foreach (\core_analytics\manager::get_time_splitting_methods_for_evaluation(true) as $timesplitting) {
|
||||
$timesplittingmethods[] = [
|
||||
'id' => \tool_analytics\output\helper::class_to_option($timesplitting->get_id()),
|
||||
'text' => $timesplitting->get_name()->out(),
|
||||
];
|
||||
}
|
||||
|
||||
$data->models = array();
|
||||
foreach ($this->models as $model) {
|
||||
$modeldata = $model->export();
|
||||
@ -192,7 +203,15 @@ class models_list implements \renderable, \templatable {
|
||||
$trainedonlyexternally = !$model->trained_locally() && $model->is_trained();
|
||||
|
||||
$actionid = 'evaluate-' . $model->get_id();
|
||||
$PAGE->requires->js_call_amd('tool_analytics/model', 'selectEvaluationMode', [$actionid, $trainedonlyexternally]);
|
||||
|
||||
// Include the current time-splitting method as the default selection method the model already have one.
|
||||
if ($model->get_model_obj()->timesplitting) {
|
||||
$currenttimesplitting = ['id' => 'current', 'text' => get_string('currenttimesplitting', 'tool_analytics')];
|
||||
array_unshift($timesplittingmethods, $currenttimesplitting);
|
||||
}
|
||||
|
||||
$evaluateparams = [$actionid, $trainedonlyexternally, $timesplittingmethods];
|
||||
$PAGE->requires->js_call_amd('tool_analytics/model', 'selectEvaluationOptions', $evaluateparams);
|
||||
$urlparams['action'] = 'evaluate';
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_analytics')),
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
$string['accuracy'] = 'Accuracy';
|
||||
$string['allpredictions'] = 'All predictions';
|
||||
$string['alltimesplittingmethods'] = 'All time-splitting methods';
|
||||
$string['analysingsitedata'] = 'Analysing the site';
|
||||
$string['analyticmodels'] = 'Analytics models';
|
||||
$string['bettercli'] = 'Evaluating models and generating predictions may involve heavy processing. It is recommended to run these actions from the command line.';
|
||||
@ -36,6 +37,7 @@ $string['clienablemodel'] = 'You can enable the model by selecting a time-splitt
|
||||
$string['clievaluationandpredictions'] = 'A scheduled task iterates through enabled models and gets predictions. Models evaluation via the web interface is disabled. You can allow these processes to be executed manually via the web interface by disabling the <a href="{$a}">\'onlycli\'</a> analytics setting.';
|
||||
$string['clievaluationandpredictionsnoadmin'] = 'A scheduled task iterates through enabled models and gets predictions. Models evaluation via the web interface is disabled. It may be enabled by a site administrator.';
|
||||
$string['createmodel'] = 'Create model';
|
||||
$string['currenttimesplitting'] = 'Current time-splitting method';
|
||||
$string['delete'] = 'Delete';
|
||||
$string['deletemodelconfirmation'] = 'Are you sure you want to delete "{$a}"? These changes can not be reverted.';
|
||||
$string['disabled'] = 'Disabled';
|
||||
@ -111,6 +113,7 @@ $string['predictionprocessfinished'] = 'Prediction process finished';
|
||||
$string['previouspage'] = 'Previous page';
|
||||
$string['samestartdate'] = 'Current start date is good';
|
||||
$string['sameenddate'] = 'Current end date is good';
|
||||
$string['selecttimesplittingforevaluation'] = 'Select the time-splitting method you want to use to evaluate the model configuration.';
|
||||
$string['target'] = 'Target';
|
||||
$string['target_help'] = 'The target is what the model will predict.';
|
||||
$string['target_link'] = 'Targets';
|
||||
|
@ -172,7 +172,19 @@ switch ($action) {
|
||||
$mode = optional_param('mode', false, PARAM_ALPHANUM);
|
||||
if ($mode == 'trainedmodel') {
|
||||
$options['mode'] = 'trainedmodel';
|
||||
} else {
|
||||
|
||||
// All is the default in core_analytics\model::evaluate() as well.
|
||||
$timesplitting = optional_param('timesplitting', 'all', PARAM_ALPHANUMEXT);
|
||||
if ($timesplitting === 'current') {
|
||||
$options['timesplitting'] = \core_analytics\manager::get_time_splitting($model->get_model_obj()->timesplitting);
|
||||
} else if ($timesplitting !== 'all') {
|
||||
$options['timesplitting'] = \core_analytics\manager::get_time_splitting(
|
||||
\tool_analytics\output\helper::option_to_class($timesplitting)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$results = $model->evaluate($options);
|
||||
|
||||
// We reset the theme and the output as some indicators may be using external functions
|
||||
|
@ -1,42 +0,0 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template tool_analytics/evaluation_mode_selector
|
||||
|
||||
Evaluation mode selector.
|
||||
|
||||
The purpose of this template is to render the evaluation mode radio button.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
}
|
||||
}}
|
||||
<div class="box mb-4">{{#str}} evaluationmodeinfo, tool_analytics {{/str}}</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="evaluationmode" id="id-mode-trainedmodel" value="trainedmodel" checked>
|
||||
<label class="form-check-label" for="id-mode-trainedmodel">{{#str}} evaluationmodetrainedmodel, tool_analytics {{/str}}</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="evaluationmode" id="id-mode-configuration" value="configuration">
|
||||
<label class="form-check-label" for="id-mode-configuration">{{#str}} evaluationmodeconfiguration, tool_analytics {{/str}}</label>
|
||||
</div>
|
82
admin/tool/analytics/templates/evaluation_options.mustache
Normal file
82
admin/tool/analytics/templates/evaluation_options.mustache
Normal file
@ -0,0 +1,82 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template tool_analytics/evaluation_options
|
||||
|
||||
Evaluation selector.
|
||||
|
||||
The purpose of this template is to render the evaluation mode options.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"trainedexternally": "1",
|
||||
"timesplittingmethods": [
|
||||
{
|
||||
"id": "ou",
|
||||
"name": "Quarters"
|
||||
}, {
|
||||
"id": "yeah",
|
||||
"name": "Tenths"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
|
||||
{{#trainedexternally}}
|
||||
<div class="box mb-4">{{#str}} evaluationmodeinfo, tool_analytics {{/str}}</div>
|
||||
|
||||
<div class="custom-control custom-radio">
|
||||
<input class="custom-control-input" type="radio" name="evaluationmode" id="id-mode-trainedmodel" value="trainedmodel" checked>
|
||||
<label class="custom-control-label" for="id-mode-trainedmodel">{{#str}} evaluationmodetrainedmodel, tool_analytics {{/str}}</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-radio">
|
||||
<input class="custom-control-input" type="radio" name="evaluationmode" id="id-mode-configuration" value="configuration">
|
||||
<label class="custom-control-label" for="id-mode-configuration">{{#str}} evaluationmodeconfiguration, tool_analytics {{/str}}</label>
|
||||
</div>
|
||||
{{/trainedexternally}}
|
||||
|
||||
{{! Hidden by default if #trainedexternally as the default option is trainedmodel in this case.}}
|
||||
<div id="id-evaluation-timesplitting-container" class="m-t-1 {{#trainedexternally}}hidden{{/trainedexternally}}">
|
||||
{{#str}} selecttimesplittingforevaluation, tool_analytics {{/str}}
|
||||
<div>
|
||||
<select id="id-evaluation-timesplitting" name="timesplitting" class="custom-select m-t-1">
|
||||
{{#timesplittingmethods}}
|
||||
<option value="{{id}}">{{text}}</option>
|
||||
{{/timesplittingmethods}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{#js}}
|
||||
require(['jquery'], function($) {
|
||||
$("input[name='evaluationmode']:radio").change(function() {
|
||||
if ($(this).val() == 'configuration') {
|
||||
$('#id-evaluation-timesplitting-container').show();
|
||||
} else {
|
||||
$('#id-evaluation-timesplitting-container').hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
{{/js}}
|
@ -275,6 +275,15 @@ abstract class base {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this method valid to evaluate prediction models?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid_for_evaluation(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the time splitting method ranges.
|
||||
*
|
||||
|
@ -59,4 +59,13 @@ abstract class upcoming_periodic extends periodic {
|
||||
public function cache_indicator_calculations(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriden as these time-splitting methods are based on future dates.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function valid_for_evaluation(): bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -287,23 +287,32 @@ class manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default time splitting methods for model evaluation.
|
||||
* Returns the time-splitting methods for model evaluation.
|
||||
*
|
||||
* @param bool $all Return all the time-splitting methods that can potentially be used for evaluation or the default ones.
|
||||
* @return \core_analytics\local\time_splitting\base[]
|
||||
*/
|
||||
public static function get_time_splitting_methods_for_evaluation() {
|
||||
public static function get_time_splitting_methods_for_evaluation(bool $all = false) {
|
||||
|
||||
if ($enabledtimesplittings = get_config('analytics', 'defaulttimesplittingsevaluation')) {
|
||||
$enabledtimesplittings = array_flip(explode(',', $enabledtimesplittings));
|
||||
if ($all === false) {
|
||||
if ($enabledtimesplittings = get_config('analytics', 'defaulttimesplittingsevaluation')) {
|
||||
$enabledtimesplittings = array_flip(explode(',', $enabledtimesplittings));
|
||||
}
|
||||
}
|
||||
|
||||
$timesplittings = self::get_all_time_splittings();
|
||||
foreach ($timesplittings as $key => $timesplitting) {
|
||||
|
||||
// We remove the ones that are not enabled. This also respects the default value (all methods enabled).
|
||||
if (!empty($enabledtimesplittings) && !isset($enabledtimesplittings[$key])) {
|
||||
if (!$timesplitting->valid_for_evaluation()) {
|
||||
unset($timesplittings[$key]);
|
||||
}
|
||||
|
||||
if ($all === false) {
|
||||
// We remove the ones that are not enabled. This also respects the default value (all methods enabled).
|
||||
if (!empty($enabledtimesplittings) && !isset($enabledtimesplittings[$key])) {
|
||||
unset($timesplittings[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $timesplittings;
|
||||
}
|
||||
|
@ -376,4 +376,31 @@ class analytics_manager_testcase extends advanced_testcase {
|
||||
|
||||
$this->assertSame([], $repeated);
|
||||
}
|
||||
|
||||
/**
|
||||
* test_get_time_splitting_methods description
|
||||
* @return null
|
||||
*/
|
||||
public function test_get_time_splitting_methods() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$all = \core_analytics\manager::get_all_time_splittings();
|
||||
$this->assertArrayHasKey('\core\analytics\time_splitting\upcoming_week', $all);
|
||||
$this->assertArrayHasKey('\core\analytics\time_splitting\quarters', $all);
|
||||
|
||||
$allforevaluation = \core_analytics\manager::get_time_splitting_methods_for_evaluation(true);
|
||||
$this->assertArrayNotHasKey('\core\analytics\time_splitting\upcoming_week', $allforevaluation);
|
||||
$this->assertArrayHasKey('\core\analytics\time_splitting\quarters', $allforevaluation);
|
||||
|
||||
$defaultforevaluation = \core_analytics\manager::get_time_splitting_methods_for_evaluation(false);
|
||||
$this->assertArrayNotHasKey('\core\analytics\time_splitting\upcoming_week', $defaultforevaluation);
|
||||
$this->assertArrayHasKey('\core\analytics\time_splitting\quarters', $defaultforevaluation);
|
||||
|
||||
$sometimesplittings = '\core\analytics\time_splitting\single_range,' .
|
||||
'\core\analytics\time_splitting\tenths';
|
||||
set_config('defaulttimesplittingsevaluation', $sometimesplittings, 'analytics');
|
||||
|
||||
$defaultforevaluation = \core_analytics\manager::get_time_splitting_methods_for_evaluation(false);
|
||||
$this->assertArrayNotHasKey('\core\analytics\time_splitting\quarters', $defaultforevaluation);
|
||||
}
|
||||
}
|
||||
|
@ -448,8 +448,7 @@ class core_analytics_prediction_testcase extends advanced_testcase {
|
||||
$this->setAdminuser();
|
||||
set_config('enabled_stores', 'logstore_standard', 'tool_log');
|
||||
|
||||
$sometimesplittings = '\core\analytics\time_splitting\weekly,' .
|
||||
'\core\analytics\time_splitting\single_range,' .
|
||||
$sometimesplittings = '\core\analytics\time_splitting\single_range,' .
|
||||
'\core\analytics\time_splitting\quarters';
|
||||
set_config('defaulttimesplittingsevaluation', $sometimesplittings, 'analytics');
|
||||
|
||||
@ -620,8 +619,6 @@ class core_analytics_prediction_testcase extends advanced_testcase {
|
||||
'modelquality' => 'random',
|
||||
'ncourses' => 50,
|
||||
'expectedresults' => array(
|
||||
// The course duration is too much to be processed by in weekly basis.
|
||||
'\core\analytics\time_splitting\weekly' => \core_analytics\model::NO_DATASET,
|
||||
'\core\analytics\time_splitting\single_range' => \core_analytics\model::LOW_SCORE,
|
||||
'\core\analytics\time_splitting\quarters' => \core_analytics\model::LOW_SCORE,
|
||||
)
|
||||
@ -630,8 +627,6 @@ class core_analytics_prediction_testcase extends advanced_testcase {
|
||||
'modelquality' => 'perfect',
|
||||
'ncourses' => 50,
|
||||
'expectedresults' => array(
|
||||
// The course duration is too much to be processed by in weekly basis.
|
||||
'\core\analytics\time_splitting\weekly' => \core_analytics\model::NO_DATASET,
|
||||
'\core\analytics\time_splitting\single_range' => \core_analytics\model::OK,
|
||||
'\core\analytics\time_splitting\quarters' => \core_analytics\model::OK,
|
||||
)
|
||||
|
@ -24,6 +24,9 @@ information provided here is intended especially for developers.
|
||||
number of ranges.
|
||||
* Can now overwrite cache_indicator_calculations(). You should return false if the time frames generated
|
||||
by your time-splitting method are unique and / or can hardly be reused by further models.
|
||||
* Can now overwrite valid_for_evaluation(). You can return false if the time-splitting method can not be
|
||||
used to evaluate prediction models or if it does not make sense to evaluate prediction models with it,
|
||||
as for example upcoming_periodic children classes.
|
||||
* \core_analytics\local\analyser\base::get_most_recent_prediction_range has been moved to
|
||||
\core_analytics\local\time_splitting\base::get_most_recent_prediction_range and it is not overwritable
|
||||
by time splitting methods.
|
||||
|
Loading…
x
Reference in New Issue
Block a user