From efcba80a58953b476ee6ba95b2fb833b3c7503a6 Mon Sep 17 00:00:00 2001 From: astaric Date: Fri, 2 Mar 2018 11:44:21 +0100 Subject: [PATCH] test & score: resort scores when data changes Fixes #2926 --- Orange/widgets/evaluate/owtestlearners.py | 7 +++ .../evaluate/tests/test_owtestlearners.py | 59 ++++++++++++++++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Orange/widgets/evaluate/owtestlearners.py b/Orange/widgets/evaluate/owtestlearners.py index c83b70d3b47..2277429f634 100644 --- a/Orange/widgets/evaluate/owtestlearners.py +++ b/Orange/widgets/evaluate/owtestlearners.py @@ -586,6 +586,13 @@ def _update_stats_model(self): model.appendRow(row) + # Resort rows based on current sorting + header = self.view.horizontalHeader() + model.sort( + header.sortIndicatorSection(), + header.sortIndicatorOrder() + ) + self.error("\n".join(errors), shown=bool(errors)) self.Warning.scores_not_computed(shown=has_missing_scores) diff --git a/Orange/widgets/evaluate/tests/test_owtestlearners.py b/Orange/widgets/evaluate/tests/test_owtestlearners.py index f5eec880e05..beb1ca6282a 100644 --- a/Orange/widgets/evaluate/tests/test_owtestlearners.py +++ b/Orange/widgets/evaluate/tests/test_owtestlearners.py @@ -5,9 +5,11 @@ import numpy as np from AnyQt.QtWidgets import QMenu -from AnyQt.QtCore import QPoint +from AnyQt.QtCore import QPoint, Qt +from AnyQt.QtTest import QTest from Orange.classification import MajorityLearner, LogisticRegressionLearner +from Orange.classification.majority import ConstantModel from Orange.data import Table, Domain, DiscreteVariable, ContinuousVariable from Orange.evaluation import Results, TestOnTestData from Orange.evaluation.scoring import ClassificationScore, RegressionScore, \ @@ -19,6 +21,7 @@ from Orange.widgets.settings import ( ClassValuesContextHandler, PerfectDomainContextHandler) from Orange.widgets.tests.base import WidgetTest +from Orange.widgets.tests.utils import simulate class TestOWTestLearners(WidgetTest): @@ -258,16 +261,13 @@ def test_target_changing(self): average_auc = float(w.view.model().item(0, 1).text()) - w.class_selection = "Iris-setosa" - w._on_target_class_changed() + simulate.combobox_activate_item(w.controls.class_selection, "Iris-setosa") setosa_auc = float(w.view.model().item(0, 1).text()) - w.class_selection = "Iris-versicolor" - w._on_target_class_changed() + simulate.combobox_activate_item(w.controls.class_selection, "Iris-versicolor") versicolor_auc = float(w.view.model().item(0, 1).text()) - w.class_selection = "Iris-virginica" - w._on_target_class_changed() + simulate.combobox_activate_item(w.controls.class_selection, "Iris-virginica") virginica_auc = float(w.view.model().item(0, 1).text()) self.assertGreater(average_auc, versicolor_auc) @@ -276,6 +276,51 @@ def test_target_changing(self): self.assertGreater(setosa_auc, versicolor_auc) self.assertGreater(setosa_auc, virginica_auc) + def test_resort_on_data_change(self): + iris = Table("iris") + # one example is included from the other class + # to keep F1 from complaining + setosa = iris[:51] + versicolor = iris[49:100] + + class SetosaLearner: + def __call__(self, data): + model = ConstantModel([1., 0, 0]) + model.domain = iris.domain + return model + + class VersicolorLearner: + def __call__(self, data): + model = ConstantModel([0, 1., 0]) + model.domain = iris.domain + return model + + # this is done manually to avoid multiple computations + self.widget.resampling = 5 + self.widget.set_train_data(iris) + self.widget.set_learner(SetosaLearner(), 1) + self.widget.set_learner(VersicolorLearner(), 2) + + self.send_signal(self.widget.Inputs.test_data, setosa, wait=5000) + + self.widget.show() + header = self.widget.view.horizontalHeader() + QTest.mouseClick(header.viewport(), Qt.LeftButton) + + # Ensure that the click on header caused an ascending sort + # Ascending sort means that wrong model should be listed first + self.assertEqual(header.sortIndicatorOrder(), Qt.AscendingOrder) + self.assertEqual( + self.widget.view.model().item(0, 0).text(), + "VersicolorLearner") + + self.send_signal(self.widget.Inputs.test_data, versicolor, wait=5000) + self.assertEqual( + self.widget.view.model().item(0, 0).text(), + "SetosaLearner") + + self.widget.hide() + class TestHelpers(unittest.TestCase): def test_results_one_vs_rest(self):