Skip to content

Commit a780239

Browse files
authored
Merge pull request #5527 from VesnaT/fix_pivot
[FIX] Pivot: Handle empty data, metas only
2 parents 543f271 + 646b4a2 commit a780239

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

Orange/widgets/data/owpivot.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ class Warning(OWWidget.Warning):
744744
renamed_vars = Msg("Some variables have been renamed in some tables"
745745
"to avoid duplicates.\n{}")
746746
too_many_values = Msg("Selected variable has too many values.")
747+
no_variables = Msg("At least 1 primitive variable is required.")
747748

748749
settingsHandler = DomainContextHandler()
749750
row_feature = ContextSetting(None)
@@ -854,20 +855,29 @@ def no_col_feature(self):
854855
def skipped_aggs(self):
855856
def add(fun):
856857
data, var = self.data, self.val_feature
858+
primitive_funcs = Pivot.ContVarFunctions + Pivot.DiscVarFunctions
857859
return data and not var and fun not in Pivot.AutonomousFunctions \
858860
or var and var.is_discrete and fun in Pivot.ContVarFunctions \
859-
or var and var.is_continuous and fun in Pivot.DiscVarFunctions
861+
or var and var.is_continuous and fun in Pivot.DiscVarFunctions \
862+
or var and not var.is_primitive() and fun in primitive_funcs
860863
skipped = [str(fun) for fun in self.sel_agg_functions if add(fun)]
861864
return ", ".join(sorted(skipped))
862865

866+
@property
867+
def data_has_primitives(self):
868+
if not self.data:
869+
return False
870+
domain = self.data.domain
871+
return any(v.is_primitive() for v in domain.variables + domain.metas)
872+
863873
def __feature_changed(self):
864874
self.selection = set()
865875
self.pivot = None
866876
self.commit()
867877

868878
def __val_feature_changed(self):
869879
self.selection = set()
870-
if self.no_col_feature:
880+
if self.no_col_feature or not self.pivot:
871881
return
872882
self.pivot.update_pivot_table(self.val_feature)
873883
self.commit()
@@ -896,7 +906,8 @@ def set_data(self, data):
896906
self.pivot = None
897907
self.check_data()
898908
self.init_attr_values()
899-
self.openContext(self.data)
909+
if self.data_has_primitives:
910+
self.openContext(self.data)
900911
self.unconditional_commit()
901912

902913
def check_data(self):
@@ -912,8 +923,8 @@ def init_attr_values(self):
912923
self.row_feature = model[0]
913924
model = self.controls.val_feature.model()
914925
if model and len(model) > 2:
915-
self.val_feature = domain.variables[0] \
916-
if domain.variables[0] in model else model[2]
926+
allvars = domain.variables + domain.metas
927+
self.val_feature = allvars[0] if allvars[0] in model else model[2]
917928

918929
def commit(self):
919930
def send_outputs(pivot_table, filtered_data, grouped_data):
@@ -933,9 +944,16 @@ def send_outputs(pivot_table, filtered_data, grouped_data):
933944
self.Warning.cannot_aggregate.clear()
934945
self.Warning.no_col_feature.clear()
935946

947+
self.table_view.clear()
948+
936949
if self.pivot is None:
950+
if self.data:
951+
if not self.data_has_primitives:
952+
self.Warning.no_variables()
953+
send_outputs(None, None, None)
954+
return
955+
937956
if self.no_col_feature:
938-
self.table_view.clear()
939957
self.Warning.no_col_feature()
940958
send_outputs(None, None, None)
941959
return
@@ -965,7 +983,6 @@ def send_outputs(pivot_table, filtered_data, grouped_data):
965983
self.Warning.renamed_vars(self.pivot.renamed)
966984

967985
def _update_graph(self):
968-
self.table_view.clear()
969986
if self.pivot.pivot_table:
970987
col_feature = self.col_feature or self.row_feature
971988
self.table_view.update_table(col_feature.name,

Orange/widgets/data/tests/test_owpivot.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,32 @@ def test_table_values(self):
278278
self.assertEqual(model.data(model.index(4, 4)), "114.0")
279279
self.assertEqual(model.data(model.index(5, 4)), "reversable defect")
280280

281+
def test_only_metas_table(self):
282+
self.send_signal(self.widget.Inputs.data, self.zoo[:, 17:])
283+
self.assertTrue(self.widget.Warning.no_variables.is_shown())
284+
285+
data = self.zoo.transform(Domain([], metas=self.zoo.domain.attributes))
286+
self.send_signal(self.widget.Inputs.data, data)
287+
self.assertFalse(self.widget.Warning.no_variables.is_shown())
288+
289+
def test_empty_table(self):
290+
data = self.heart_disease[:, :0]
291+
self.send_signal(self.widget.Inputs.data, data)
292+
self.assertTrue(self.widget.Warning.no_variables.is_shown())
293+
self.send_signal(self.widget.Inputs.data, None)
294+
self.assertFalse(self.widget.Warning.no_variables.is_shown())
295+
296+
data = self.heart_disease
297+
self.send_signal(self.widget.Inputs.data, data)
298+
299+
zoo_domain = self.zoo.domain
300+
data = self.zoo.transform(Domain([], metas=zoo_domain.metas))
301+
self.send_signal(self.widget.Inputs.data, data)
302+
303+
domain = Domain([], zoo_domain.class_vars, metas=zoo_domain.metas)
304+
data = self.zoo.transform(domain)
305+
self.send_signal(self.widget.Inputs.data, data)
306+
281307

282308
class TestAggregationFunctionsEnum(unittest.TestCase):
283309
def test_pickle(self):

0 commit comments

Comments
 (0)