Skip to content

Commit 85d35aa

Browse files
authored
Merge pull request #4611 from aturanjanin/owtransform
[ENH] ApplyDomain: data info displayed in the status bar
2 parents da19ae1 + 6bd7591 commit 85d35aa

File tree

2 files changed

+60
-11
lines changed

2 files changed

+60
-11
lines changed

Orange/widgets/data/owtransform.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
from typing import Optional
22

3-
from Orange.data import Table, Domain
3+
from AnyQt.QtCore import Qt
4+
5+
from Orange.data import Table
46
from Orange.widgets import gui
57
from Orange.widgets.report.report import describe_data
68
from Orange.widgets.utils.sql import check_sql_input
79
from Orange.widgets.utils.widgetpreview import WidgetPreview
10+
from Orange.widgets.utils.state_summary import format_multiple_summaries, \
11+
format_summary_details
812
from Orange.widgets.widget import OWWidget, Input, Output, Msg
913

1014

@@ -31,7 +35,7 @@ class Error(OWWidget.Error):
3135
def __init__(self):
3236
super().__init__()
3337
self.data = None # type: Optional[Table]
34-
self.template_domain = None # type: Optional[Domain]
38+
self.template_data = None # type: Optional[Table]
3539
self.transformed_info = describe_data(None) # type: OrderedDict
3640

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

48+
self.info.set_input_summary(self.info.NoInput)
49+
self.info.set_output_summary(self.info.NoOutput)
50+
4451
def set_input_label_text(self):
4552
text = "No data on input."
4653
if self.data:
@@ -51,11 +58,11 @@ def set_input_label_text(self):
5158

5259
def set_template_label_text(self):
5360
text = "No template data on input."
54-
if self.data and self.template_domain is not None:
61+
if self.data and self.template_data:
5562
text = "Template domain applied."
56-
elif self.template_domain is not None:
63+
elif self.template_data:
5764
text = "Template data includes {:,} features.".format(
58-
len(self.template_domain.attributes))
65+
len(self.template_data.domain.attributes))
5966
self.template_label.setText(text)
6067

6168
def set_output_label_text(self, data):
@@ -74,21 +81,36 @@ def set_data(self, data):
7481
@Inputs.template_data
7582
@check_sql_input
7683
def set_template_data(self, data):
77-
self.template_domain = data and data.domain
84+
self.template_data = data
7885

7986
def handleNewSignals(self):
87+
summary, details, kwargs = self.info.NoInput, "", {}
88+
if self.data or self.template_data:
89+
n_data = len(self.data) if self.data else 0
90+
n_template = len(self.template_data) if self.template_data else 0
91+
summary = f"{self.info.format_number(n_data)}, " \
92+
f"{self.info.format_number(n_template)}"
93+
kwargs = {"format": Qt.RichText}
94+
details = format_multiple_summaries([
95+
("Data", self.data),
96+
("Template data", self.template_data)
97+
])
98+
self.info.set_input_summary(summary, details, **kwargs)
8099
self.apply()
81100

82101
def apply(self):
83102
self.clear_messages()
84103
transformed_data = None
85-
if self.data and self.template_domain is not None:
104+
if self.data and self.template_data:
86105
try:
87-
transformed_data = self.data.transform(self.template_domain)
106+
transformed_data = self.data.transform(self.template_data.domain)
88107
except Exception as ex: # pylint: disable=broad-except
89108
self.Error.error(ex)
90109

91110
data = transformed_data
111+
summary = len(data) if data else self.info.NoOutput
112+
details = format_summary_details(data) if data else ""
113+
self.info.set_output_summary(summary, details)
92114
self.transformed_info = describe_data(data)
93115
self.Outputs.transformed_data.send(data)
94116
self.set_template_label_text()
@@ -97,8 +119,8 @@ def apply(self):
97119
def send_report(self):
98120
if self.data:
99121
self.report_data("Data", self.data)
100-
if self.template_domain is not None:
101-
self.report_domain("Template data", self.template_domain)
122+
if self.template_data:
123+
self.report_domain("Template data", self.template_data.domain)
102124
if self.transformed_info:
103125
self.report_items("Transformed data", self.transformed_info)
104126

Orange/widgets/data/tests/test_owtransform.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Test methods with long descriptive names can omit docstrings
2-
# pylint: disable=missing-docstring
2+
# pylint: disable=missing-docstring, protected-access
33
from unittest.mock import Mock
44

55
from numpy import testing as npt
@@ -9,6 +9,8 @@
99
from Orange.widgets.data.owtransform import OWTransform
1010
from Orange.widgets.tests.base import WidgetTest
1111
from Orange.widgets.unsupervised.owpca import OWPCA
12+
from Orange.widgets.utils.state_summary import format_summary_details, \
13+
format_multiple_summaries
1214

1315

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

2022
def test_output(self):
2123
# send data and template data
24+
info = self.widget.info
25+
no_input, no_output = "No data on input", "No data on output"
2226
self.send_signal(self.widget.Inputs.data, self.data[::15])
2327
self.send_signal(self.widget.Inputs.template_data, self.disc_data)
2428
output = self.get_output(self.widget.Outputs.transformed_data)
@@ -29,6 +33,13 @@ def test_output(self):
2933
self.widget.template_label.text())
3034
self.assertEqual("Output data includes 4 features.",
3135
self.widget.output_label.text())
36+
data_list = [("Data", self.data[::15]), ("Template data", self.disc_data)]
37+
summary, details = "10, 150", format_multiple_summaries(data_list)
38+
self.assertEqual(info._StateInfo__input_summary.brief, summary)
39+
self.assertEqual(info._StateInfo__input_summary.details, details)
40+
summary, details = "10", format_summary_details(output)
41+
self.assertEqual(info._StateInfo__output_summary.brief, summary)
42+
self.assertEqual(info._StateInfo__output_summary.details, details)
3243

3344
# remove template data
3445
self.send_signal(self.widget.Inputs.template_data, None)
@@ -39,6 +50,12 @@ def test_output(self):
3950
self.assertEqual("No template data on input.",
4051
self.widget.template_label.text())
4152
self.assertEqual("", self.widget.output_label.text())
53+
data_list = [("Data", self.data[::15]), ("Template data", None)]
54+
summary, details = "10, 0", format_multiple_summaries(data_list)
55+
self.assertEqual(info._StateInfo__input_summary.brief, summary)
56+
self.assertEqual(info._StateInfo__input_summary.details, details)
57+
self.assertEqual(info._StateInfo__output_summary.brief, "")
58+
self.assertEqual(info._StateInfo__output_summary.details, no_output)
4259

4360
# send template data
4461
self.send_signal(self.widget.Inputs.template_data, self.disc_data)
@@ -59,13 +76,23 @@ def test_output(self):
5976
self.assertEqual("Template data includes 4 features.",
6077
self.widget.template_label.text())
6178
self.assertEqual("", self.widget.output_label.text())
79+
data_list = [("Data", None), ("Template data", self.disc_data)]
80+
summary, details = "0, 150", format_multiple_summaries(data_list)
81+
self.assertEqual(info._StateInfo__input_summary.brief, summary)
82+
self.assertEqual(info._StateInfo__input_summary.details, details)
83+
self.assertEqual(info._StateInfo__output_summary.brief, "")
84+
self.assertEqual(info._StateInfo__output_summary.details, no_output)
6285

6386
# remove template data
6487
self.send_signal(self.widget.Inputs.template_data, None)
6588
self.assertEqual("No data on input.", self.widget.input_label.text())
6689
self.assertEqual("No template data on input.",
6790
self.widget.template_label.text())
6891
self.assertEqual("", self.widget.output_label.text())
92+
self.assertEqual(info._StateInfo__input_summary.brief, "")
93+
self.assertEqual(info._StateInfo__input_summary.details, no_input)
94+
self.assertEqual(info._StateInfo__output_summary.brief, "")
95+
self.assertEqual(info._StateInfo__output_summary.details, no_output)
6996

7097
def assertTableEqual(self, table1, table2):
7198
self.assertIs(table1.domain, table2.domain)

0 commit comments

Comments
 (0)