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

[ENH] ApplyDomain: data info displayed in the status bar #4611

Merged
merged 2 commits into from
Apr 17, 2020
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
42 changes: 32 additions & 10 deletions Orange/widgets/data/owtransform.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from typing import Optional

from Orange.data import Table, Domain
from AnyQt.QtCore import Qt

from Orange.data import Table
from Orange.widgets import gui
from Orange.widgets.report.report import describe_data
from Orange.widgets.utils.sql import check_sql_input
from Orange.widgets.utils.widgetpreview import WidgetPreview
from Orange.widgets.utils.state_summary import format_multiple_summaries, \
format_summary_details
from Orange.widgets.widget import OWWidget, Input, Output, Msg


Expand All @@ -31,7 +35,7 @@ class Error(OWWidget.Error):
def __init__(self):
super().__init__()
self.data = None # type: Optional[Table]
self.template_domain = None # type: Optional[Domain]
self.template_data = None # type: Optional[Table]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since self.template_data has been introduces self.template_domain is no longer needed.

self.transformed_info = describe_data(None) # type: OrderedDict

info_box = gui.widgetBox(self.controlArea, "Info")
Expand All @@ -41,6 +45,9 @@ def __init__(self):
self.set_input_label_text()
self.set_template_label_text()

self.info.set_input_summary(self.info.NoInput)
self.info.set_output_summary(self.info.NoOutput)

def set_input_label_text(self):
text = "No data on input."
if self.data:
Expand All @@ -51,11 +58,11 @@ def set_input_label_text(self):

def set_template_label_text(self):
text = "No template data on input."
if self.data and self.template_domain is not None:
if self.data and self.template_data:
text = "Template domain applied."
elif self.template_domain is not None:
elif self.template_data:
text = "Template data includes {:,} features.".format(
len(self.template_domain.attributes))
len(self.template_data.domain.attributes))
self.template_label.setText(text)

def set_output_label_text(self, data):
Expand All @@ -74,21 +81,36 @@ def set_data(self, data):
@Inputs.template_data
@check_sql_input
def set_template_data(self, data):
self.template_domain = data and data.domain
self.template_data = data

def handleNewSignals(self):
summary, details, kwargs = self.info.NoInput, "", {}
if self.data or self.template_data:
n_data = len(self.data) if self.data else 0
n_template = len(self.template_data) if self.template_data else 0
summary = f"{self.info.format_number(n_data)}, " \
f"{self.info.format_number(n_template)}"
kwargs = {"format": Qt.RichText}
details = format_multiple_summaries([
("Data", self.data),
("Template data", self.template_data)
])
self.info.set_input_summary(summary, details, **kwargs)
self.apply()

def apply(self):
self.clear_messages()
transformed_data = None
if self.data and self.template_domain is not None:
if self.data and self.template_data:
try:
transformed_data = self.data.transform(self.template_domain)
transformed_data = self.data.transform(self.template_data.domain)
except Exception as ex: # pylint: disable=broad-except
self.Error.error(ex)

data = transformed_data
summary = len(data) if data else self.info.NoOutput
details = format_summary_details(data) if data else ""
self.info.set_output_summary(summary, details)
self.transformed_info = describe_data(data)
self.Outputs.transformed_data.send(data)
self.set_template_label_text()
Expand All @@ -97,8 +119,8 @@ def apply(self):
def send_report(self):
if self.data:
self.report_data("Data", self.data)
if self.template_domain is not None:
self.report_domain("Template data", self.template_domain)
if self.template_data:
self.report_domain("Template data", self.template_data.domain)
if self.transformed_info:
self.report_items("Transformed data", self.transformed_info)

Expand Down
29 changes: 28 additions & 1 deletion Orange/widgets/data/tests/test_owtransform.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Test methods with long descriptive names can omit docstrings
# pylint: disable=missing-docstring
# pylint: disable=missing-docstring, protected-access
from unittest.mock import Mock

from numpy import testing as npt
Expand All @@ -9,6 +9,8 @@
from Orange.widgets.data.owtransform import OWTransform
from Orange.widgets.tests.base import WidgetTest
from Orange.widgets.unsupervised.owpca import OWPCA
from Orange.widgets.utils.state_summary import format_summary_details, \
format_multiple_summaries


class TestOWTransform(WidgetTest):
Expand All @@ -19,6 +21,8 @@ def setUp(self):

def test_output(self):
# send data and template data
info = self.widget.info
no_input, no_output = "No data on input", "No data on output"
self.send_signal(self.widget.Inputs.data, self.data[::15])
self.send_signal(self.widget.Inputs.template_data, self.disc_data)
output = self.get_output(self.widget.Outputs.transformed_data)
Expand All @@ -29,6 +33,13 @@ def test_output(self):
self.widget.template_label.text())
self.assertEqual("Output data includes 4 features.",
self.widget.output_label.text())
data_list = [("Data", self.data[::15]), ("Template data", self.disc_data)]
summary, details = "10, 150", format_multiple_summaries(data_list)
self.assertEqual(info._StateInfo__input_summary.brief, summary)
self.assertEqual(info._StateInfo__input_summary.details, details)
summary, details = "10", format_summary_details(output)
self.assertEqual(info._StateInfo__output_summary.brief, summary)
self.assertEqual(info._StateInfo__output_summary.details, details)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extra line can be removed.

# remove template data
self.send_signal(self.widget.Inputs.template_data, None)
Expand All @@ -39,6 +50,12 @@ def test_output(self):
self.assertEqual("No template data on input.",
self.widget.template_label.text())
self.assertEqual("", self.widget.output_label.text())
data_list = [("Data", self.data[::15]), ("Template data", None)]
summary, details = "10, 0", format_multiple_summaries(data_list)
self.assertEqual(info._StateInfo__input_summary.brief, summary)
self.assertEqual(info._StateInfo__input_summary.details, details)
self.assertEqual(info._StateInfo__output_summary.brief, "")
self.assertEqual(info._StateInfo__output_summary.details, no_output)

# send template data
self.send_signal(self.widget.Inputs.template_data, self.disc_data)
Expand All @@ -59,13 +76,23 @@ def test_output(self):
self.assertEqual("Template data includes 4 features.",
self.widget.template_label.text())
self.assertEqual("", self.widget.output_label.text())
data_list = [("Data", None), ("Template data", self.disc_data)]
summary, details = "0, 150", format_multiple_summaries(data_list)
self.assertEqual(info._StateInfo__input_summary.brief, summary)
self.assertEqual(info._StateInfo__input_summary.details, details)
self.assertEqual(info._StateInfo__output_summary.brief, "")
self.assertEqual(info._StateInfo__output_summary.details, no_output)

# remove template data
self.send_signal(self.widget.Inputs.template_data, None)
self.assertEqual("No data on input.", self.widget.input_label.text())
self.assertEqual("No template data on input.",
self.widget.template_label.text())
self.assertEqual("", self.widget.output_label.text())
self.assertEqual(info._StateInfo__input_summary.brief, "")
self.assertEqual(info._StateInfo__input_summary.details, no_input)
self.assertEqual(info._StateInfo__output_summary.brief, "")
self.assertEqual(info._StateInfo__output_summary.details, no_output)

def assertTableEqual(self, table1, table2):
self.assertIs(table1.domain, table2.domain)
Expand Down