Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable report testing #1472

Merged
merged 2 commits into from
Aug 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 45 additions & 68 deletions Orange/canvas/report/tests/test_report.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import unittest
from importlib import import_module
import os
import warnings

from PyQt4.QtGui import QFont, QBrush
from PyQt4.QtCore import Qt
from Orange.data.table import Table
Expand All @@ -9,43 +12,15 @@
from Orange.distance import Euclidean
from Orange.canvas.report.owreport import OWReport
from Orange.widgets import gui
from Orange.widgets.widget import OWWidget
from Orange.widgets.tests.base import WidgetTest
from Orange.widgets.classify.owclassificationtree import OWClassificationTree
from Orange.widgets.classify.owclassificationtreegraph import OWClassificationTreeGraph
from Orange.widgets.classify.owknn import OWKNNLearner
from Orange.widgets.classify.owlogisticregression import OWLogisticRegression
from Orange.widgets.classify.owmajority import OWMajority
from Orange.widgets.classify.ownaivebayes import OWNaiveBayes
from Orange.widgets.classify.owrandomforest import OWRandomForest
from Orange.widgets.classify.owsvmclassification import OWSVMClassification
from Orange.widgets.data.owconcatenate import OWConcatenate
from Orange.widgets.data.owcontinuize import OWContinuize
from Orange.widgets.data.owdatainfo import OWDataInfo
from Orange.widgets.data.owdatasampler import OWDataSampler
from Orange.widgets.data.owdiscretize import OWDiscretize
from Orange.widgets.data.owfeatureconstructor import OWFeatureConstructor
from Orange.widgets.data.owfile import OWFile
from Orange.widgets.data.owimpute import OWImpute
from Orange.widgets.data.owmergedata import OWMergeData
from Orange.widgets.data.owoutliers import OWOutliers
from Orange.widgets.data.owpaintdata import OWPaintData
from Orange.widgets.data.owpurgedomain import OWPurgeDomain
from Orange.widgets.data.owrank import OWRank
from Orange.widgets.data.owselectcolumns import OWSelectAttributes
from Orange.widgets.data.owselectrows import OWSelectRows
from Orange.widgets.data.owsql import OWSql
from Orange.widgets.data.owtable import OWDataTable
from Orange.widgets.data.owcolor import OWColor
from Orange.widgets.data.owpreprocess import OWPreprocess
from Orange.widgets.evaluate.owcalibrationplot import OWCalibrationPlot
from Orange.widgets.evaluate.owliftcurve import OWLiftCurve
from Orange.widgets.evaluate.owrocanalysis import OWROCAnalysis
from Orange.widgets.evaluate.owtestlearners import OWTestLearners
from Orange.widgets.regression.owregressiontree import OWRegressionTree
from Orange.widgets.regression.owregressiontreegraph import OWRegressionTreeGraph
from Orange.widgets.regression.owknnregression import OWKNNRegression
from Orange.widgets.regression.owmean import OWMean
from Orange.widgets.regression.owsvmregression import OWSVMRegression
from Orange.widgets.unsupervised.owcorrespondence import OWCorrespondenceAnalysis
from Orange.widgets.unsupervised.owdistancemap import OWDistanceMap
from Orange.widgets.unsupervised.owdistances import OWDistances
Expand All @@ -54,15 +29,35 @@
from Orange.widgets.unsupervised.owmds import OWMDS
from Orange.widgets.unsupervised.owpca import OWPCA
from Orange.widgets.utils.itemmodels import PyTableModel
from Orange.widgets.visualize.owboxplot import OWBoxPlot
from Orange.widgets.visualize.owdistributions import OWDistributions
from Orange.widgets.visualize.owheatmap import OWHeatMap
from Orange.widgets.visualize.owlinearprojection import OWLinearProjection
from Orange.widgets.visualize.owmosaic import OWMosaicDisplay
from Orange.widgets.visualize.owscattermap import OWScatterMap
from Orange.widgets.visualize.owscatterplot import OWScatterPlot
from Orange.widgets.visualize.owsieve import OWSieveDiagram
from Orange.widgets.visualize.owvenndiagram import OWVennDiagram


def get_owwidgets(top_module_name):
top_module = import_module(top_module_name)
widgets = []
for root, dirs, files in os.walk(top_module.__path__[0]):
root = root[len(top_module.__path__[0]):].lstrip(os.path.sep)
for file in files:
if file.lower().startswith('ow') and file.lower().endswith('.py'):
module_name = top_module_name + '.' + os.path.join(root, file).replace(os.path.sep, '.')[:-len('.py')]
try:
module = import_module(module_name, top_module_name[:top_module_name.index('.')])
except ImportError:
warnings.warn('Failed to import module: ' + module_name)
continue
for name, value in module.__dict__.items():
if (name.upper().startswith('OW') and
isinstance(value, type) and
issubclass(value, OWWidget) and
getattr(value, 'name', None) and
getattr(value, 'send_report', None)):
widgets.append(value)
return list(set(widgets))


DATA_WIDGETS = get_owwidgets('Orange.widgets.data')
VISUALIZATION_WIDGETS = get_owwidgets('Orange.widgets.visualize')
CLASSIFICATION_WIDGETS = get_owwidgets('Orange.widgets.classify')
REGRESSION_WIDGETS = get_owwidgets('Orange.widgets.regression')


class TestReport(WidgetTest):
Expand Down Expand Up @@ -119,57 +114,46 @@ def test_report_table(self):
'</tr></table>')


@unittest.skip('Segfaults. Dunno. @astaric says it might be something on the QWidget.')
class TestReportWidgets(WidgetTest):
clas_widgets = [OWClassificationTree, OWKNNLearner, OWLogisticRegression,
OWMajority, OWNaiveBayes, OWRandomForest,
OWSVMClassification]
data_widgets = [OWConcatenate, OWContinuize, OWDataInfo, OWDataSampler,
OWDiscretize, OWFeatureConstructor, OWOutliers, OWImpute,
OWMergeData, OWFile, OWPaintData, OWPurgeDomain, OWRank,
OWSelectAttributes, OWSelectRows, OWSql, OWDataTable,
OWColor, OWPreprocess]
clas_widgets = CLASSIFICATION_WIDGETS
data_widgets = DATA_WIDGETS
eval_widgets = [OWCalibrationPlot, OWLiftCurve, OWROCAnalysis]
regr_widgets = [OWRegressionTree, OWKNNRegression, OWMean, OWSVMRegression]
regr_widgets = REGRESSION_WIDGETS
unsu_widgets = [OWCorrespondenceAnalysis, OWDistances, OWKMeans,
OWMDS, OWPCA]
dist_widgets = [OWDistanceMap, OWHierarchicalClustering]
visu_widgets = [OWBoxPlot, OWDistributions, OWHeatMap, OWLinearProjection,
OWMosaicDisplay, OWScatterPlot,
OWSieveDiagram, OWScatterMap, OWVennDiagram]
visu_widgets = VISUALIZATION_WIDGETS
spec_widgets = [OWClassificationTreeGraph, OWTestLearners,
OWRegressionTreeGraph]

def _create_report(self, widgets, rep, data):
for widget in widgets:
w = widget()
if w.inputs and data is not None:
w = self.create_widget(widget)
if w.inputs and isinstance(data, w.inputs[0].type):
handler = getattr(w, w.inputs[0].handler)
handler(data)
w.create_report_html()
w.create_report_html()
rep.make_report(w)
# rep.show()

def test_report_widgets_classify(self):
rep = OWReport.get_instance()
data = Table("zoo")
data = Table("titanic")
widgets = self.clas_widgets

w = OWClassificationTreeGraph()
w = self.create_widget(OWClassificationTreeGraph)
clf = TreeLearner(max_depth=3)(data)
clf.instances = data
w.ctree(clf)
w.create_report_html()
rep.make_report(w)

self.assertEqual(len(widgets) + 1, 8)
self._create_report(widgets, rep, data)

def test_report_widgets_data(self):
rep = OWReport.get_instance()
data = Table("zoo")
widgets = self.data_widgets
self.assertEqual(len(widgets), 19)
self._create_report(widgets, rep, data)

def test_report_widgets_evaluate(self):
Expand All @@ -181,7 +165,7 @@ def test_report_widgets_evaluate(self):
store_data=True)
results.learner_names = ["LR l2"]

w = OWTestLearners()
w = self.create_widget(OWTestLearners)
set_learner = getattr(w, w.inputs[0].handler)
set_train = getattr(w, w.inputs[1].handler)
set_test = getattr(w, w.inputs[2].handler)
Expand All @@ -191,51 +175,44 @@ def test_report_widgets_evaluate(self):
w.create_report_html()
rep.make_report(w)

self.assertEqual(len(widgets) + 1, 4)
self._create_report(widgets, rep, results)

def test_report_widgets_regression(self):
rep = OWReport.get_instance()
data = Table("housing")
widgets = self.regr_widgets

w = OWRegressionTreeGraph()
w = self.create_widget(OWRegressionTreeGraph)
mod = TreeRegressionLearner(max_depth=3)(data)
mod.instances = data
w.ctree(mod)
w.create_report_html()
rep.make_report(w)

self.assertEqual(len(widgets) + 1, 5)
self._create_report(widgets, rep, data)

def test_report_widgets_unsupervised(self):
rep = OWReport.get_instance()
data = Table("zoo")
widgets = self.unsu_widgets
self.assertEqual(len(widgets), 5)
self._create_report(widgets, rep, data)

def test_report_widgets_unsupervised_dist(self):
rep = OWReport.get_instance()
data = Table("zoo")
dist = Euclidean(data)
widgets = self.dist_widgets
self.assertEqual(len(widgets), 2)
self._create_report(widgets, rep, dist)

def test_report_widgets_visualize(self):
rep = OWReport.get_instance()
data = Table("zoo")
widgets = self.visu_widgets
self.assertEqual(len(widgets), 9)
self._create_report(widgets, rep, data)

@unittest.skip('... in favor of other methods. Segfaults.')
def test_report_widgets_all(self):
rep = OWReport.get_instance()
widgets = self.clas_widgets + self.data_widgets + self.eval_widgets + \
self.regr_widgets + self.unsu_widgets + self.dist_widgets + \
self.visu_widgets + self.spec_widgets
self.assertEqual(len(widgets), 52)
self._create_report(widgets, rep, None)
9 changes: 6 additions & 3 deletions Orange/widgets/data/oweditdomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,12 @@ def sizeHint(self):
return sh.expandedTo(QSize(660, 550))

def send_report(self):
self.report_raw("", EditDomainReport(
old_domain=chain(self.data.domain.variables, self.data.domain.metas),
new_domain=self.domain_model).to_html())
if self.data is not None:
self.report_raw("", EditDomainReport(
old_domain=chain(self.data.domain.variables, self.data.domain.metas),
new_domain=self.domain_model).to_html())
else:
self.report_data(None)


class EditDomainReport:
Expand Down
7 changes: 4 additions & 3 deletions Orange/widgets/unsupervised/owkmeans.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,11 @@ def set_data(self, data):
self.run()

def send_report(self):
k_clusters = self.k
if self.optimize_k and self.optimization_runs and self.selected_row() is not None:
k_clusters = self.optimization_runs[self.selected_row()][1].k
self.report_items((
("Number of clusters",
self.optimization_runs[self.selected_row()][1].k
if self.optimize_k else self.k),
("Number of clusters", k_clusters),
("Optimization",
self.optimize_k != 0 and
"{}, {} re-runs limited to {} steps".format(
Expand Down
3 changes: 3 additions & 0 deletions Orange/widgets/visualize/owsilhouetteplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ def commit(self):
self.send("Other Data", other)

def send_report(self):
if not len(self.cluster_var_model):
return

self.report_plot()
caption = "Silhouette plot ({} distance), clustered by '{}'".format(
self.Distances[self.distance_idx][0],
Expand Down