Skip to content

Commit 6a959e3

Browse files
committed
OWNeighbors: data info displayed in the status bar
1 parent bd2f7ec commit 6a959e3

File tree

2 files changed

+54
-41
lines changed

2 files changed

+54
-41
lines changed

Orange/widgets/data/owneighbors.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from Orange.widgets.utils.signals import Input, Output
1212
from Orange.widgets.widget import OWWidget, Msg
1313
from Orange.widgets.utils.widgetpreview import WidgetPreview
14+
from Orange.widgets.utils.state_summary import format_summary_details,\
15+
format_multiple_summaries
1416

1517
METRICS = [
1618
("Euclidean", distance.Euclidean),
@@ -88,14 +90,17 @@ def __init__(self):
8890
def _set_input_summary(self):
8991
n_data = len(self.data) if self.data else 0
9092
n_refs = len(self.reference) if self.reference else 0
91-
92-
if n_data or n_refs:
93-
details = \
94-
f"{n_data if n_data else 'No'} data instance(s) on input\n" \
95-
f"{n_refs if n_refs else 'No'} reference instance(s) on input "
96-
self.info.set_input_summary(f"{n_data} | {n_refs} ", details)
97-
else:
98-
self.info.set_input_summary(self.info.NoInput)
93+
summary, details, kwargs = self.info.NoInput, "", {}
94+
95+
if self.data or self.reference:
96+
summary = f"{self.info.format_number(n_data)}, " \
97+
f"{self.info.format_number(n_refs)}"
98+
details = format_multiple_summaries([
99+
("Data", self.data),
100+
("Reference", self.reference)
101+
])
102+
kwargs = {"format": Qt.RichText}
103+
self.info.set_input_summary(summary, details, **kwargs)
99104

100105
@Inputs.data
101106
def set_data(self, data):
@@ -107,8 +112,8 @@ def set_ref(self, refs):
107112

108113
def handleNewSignals(self):
109114
self.compute_distances()
110-
self.unconditional_apply()
111115
self._set_input_summary()
116+
self.unconditional_apply()
112117

113118
def recompute(self):
114119
self.compute_distances()
@@ -146,7 +151,8 @@ def apply(self):
146151
self.info.set_output_summary(self.info.NoOutput)
147152
else:
148153
neighbors = self._data_with_similarity(indices)
149-
self.info.set_output_summary(str(len(neighbors)))
154+
summary, details = len(neighbors), format_summary_details(neighbors)
155+
self.info.set_output_summary(summary, details)
150156
self.Outputs.data.send(neighbors)
151157

152158
def _compute_indices(self):

Orange/widgets/data/tests/test_owneighbors.py

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from Orange.data import Table, Domain, ContinuousVariable
88
from Orange.widgets.data.owneighbors import OWNeighbors, METRICS
99
from Orange.widgets.tests.base import WidgetTest, ParameterMapping
10+
from Orange.widgets.utils.state_summary import format_summary_details, \
11+
format_multiple_summaries
1012

1113

1214
class TestOWNeighbors(WidgetTest):
@@ -122,36 +124,43 @@ def test_missing_values(self):
122124
widget.apply_button.button.click()
123125
self.assertIsNotNone(self.get_output("Neighbors"))
124126

125-
def test_input_summary(self):
127+
def test_summary(self):
126128
"""Check if status bar is updated when data is received"""
127-
widget = self.widget
128-
input_sum = widget.info.set_input_summary = Mock()
129-
data = Table("iris")
130-
131-
input_sum.reset_mock()
132-
self.send_signal(widget.Inputs.reference, data[:5])
133-
input_sum.assert_called_with("0 | 5 ", "No data instance(s) on input\n"\
134-
"5 reference instance(s) on input ")
135-
136-
input_sum.reset_mock()
137-
self.send_signal(widget.Inputs.data, data[:10])
138-
input_sum.assert_called_with("10 | 5 ", "10 data instance(s) on input\n"\
139-
"5 reference instance(s) on input ")
140-
141-
input_sum.reset_mock()
142-
self.send_signals([(widget.Inputs.data, None), (widget.Inputs.reference, None)])
143-
input_sum.assert_called_once()
144-
self.assertEqual(input_sum.call_args[0][0].brief, "")
145-
146-
input_sum.reset_mock()
147-
self.send_signal(widget.Inputs.data, data[:15])
148-
input_sum.assert_called_with("15 | 0 ", "15 data instance(s) on input\n" \
149-
"No reference instance(s) on input ")
150-
151-
input_sum.reset_mock()
152-
self.send_signals([(widget.Inputs.data, data[:12]), (widget.Inputs.reference, data[-1:])])
153-
input_sum.assert_called_with("12 | 1 ", "12 data instance(s) on input\n"\
154-
"1 reference instance(s) on input ")
129+
info = self.widget.info
130+
data, reference = Table("iris"), Table("iris")[:5]
131+
no_input, no_output = "No data on input", "No data on output"
132+
133+
self.send_signal(self.widget.Inputs.data, data)
134+
data_list = [("Data", data), ("Reference", None)]
135+
summary, details = "150, 0", format_multiple_summaries(data_list)
136+
self.assertEqual(info._StateInfo__input_summary.brief, summary)
137+
self.assertEqual(info._StateInfo__input_summary.details, details)
138+
self.assertEqual(info._StateInfo__output_summary.brief, "")
139+
self.assertEqual(info._StateInfo__output_summary.details, no_output)
140+
141+
self.send_signal(self.widget.Inputs.reference, reference)
142+
data_list = [("Data", data), ("Reference", reference)]
143+
summary, details = "150, 5", format_multiple_summaries(data_list)
144+
self.assertEqual(info._StateInfo__input_summary.brief, summary)
145+
self.assertEqual(info._StateInfo__input_summary.details, details)
146+
output = self.get_output(self.widget.Outputs.data)
147+
summary, details = f"{len(output)}", format_summary_details(output)
148+
self.assertEqual(info._StateInfo__output_summary.brief, summary)
149+
self.assertEqual(info._StateInfo__output_summary.details, details)
150+
151+
self.send_signal(self.widget.Inputs.data, None)
152+
data_list = [("Data", None), ("Reference", reference)]
153+
summary, details = "0, 5", format_multiple_summaries(data_list)
154+
self.assertEqual(info._StateInfo__input_summary.brief, summary)
155+
self.assertEqual(info._StateInfo__input_summary.details, details)
156+
self.assertEqual(info._StateInfo__output_summary.brief, "")
157+
self.assertEqual(info._StateInfo__output_summary.details, no_output)
158+
159+
self.send_signal(self.widget.Inputs.reference, None)
160+
self.assertEqual(info._StateInfo__input_summary.brief, "")
161+
self.assertEqual(info._StateInfo__input_summary.details, no_input)
162+
self.assertEqual(info._StateInfo__output_summary.brief, "")
163+
self.assertEqual(info._StateInfo__output_summary.details, no_output)
155164

156165
def test_compute_distances_apply_called(self):
157166
"""Check compute distances and apply are called when receiving signal"""
@@ -329,7 +338,6 @@ def test_data_with_similarity(self):
329338

330339
def test_apply(self):
331340
widget = self.widget
332-
output_sum = widget.info.set_output_summary = Mock()
333341
widget.auto_apply = True
334342
data = Table("iris")
335343
indices = np.array([5, 10, 15, 100])
@@ -342,7 +350,6 @@ def test_apply(self):
342350
np.testing.assert_almost_equal(neigh.X, data.X[indices])
343351
np.testing.assert_almost_equal(
344352
neigh.metas.flatten(), widget.distances[indices])
345-
output_sum.assert_called_with(str(len(neigh)))
346353

347354
def test_all_equal_ref(self):
348355
widget = self.widget

0 commit comments

Comments
 (0)