Skip to content

Commit 35231b7

Browse files
Get unique names when renaming vars
1 parent b5be01d commit 35231b7

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

Orange/widgets/data/owfile.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from Orange.widgets.utils.filedialogs import RecentPathsWComboMixin, \
2222
open_filename_dialog
2323
from Orange.widgets.utils.widgetpreview import WidgetPreview
24-
from Orange.widgets.widget import Output
24+
from Orange.widgets.widget import Output, Msg
2525

2626
# Backward compatibility: class RecentPath used to be defined in this module,
2727
# and it is used in saved (pickled) settings. It must be imported into the
@@ -121,11 +121,13 @@ class Outputs:
121121
domain_editor = SettingProvider(DomainEditor)
122122

123123
class Warning(widget.OWWidget.Warning):
124-
file_too_big = widget.Msg("The file is too large to load automatically."
125-
" Press Reload to load.")
126-
load_warning = widget.Msg("Read warning:\n{}")
124+
file_too_big = Msg("The file is too large to load automatically."
125+
" Press Reload to load.")
126+
load_warning = Msg("Read warning:\n{}")
127127
performance_warning = widget.Msg(
128128
"Categorical variables with >100 values may decrease performance.")
129+
renamed_vars = Msg("Some variables have been renamed "
130+
"to avoid duplicates.\n{}")
129131

130132
class Error(widget.OWWidget.Error):
131133
file_not_found = widget.Msg("File not found.")
@@ -478,6 +480,7 @@ def _inspect_discrete_variables(self, domain):
478480

479481
def apply_domain_edit(self):
480482
self.Warning.performance_warning.clear()
483+
self.Warning.renamed_vars.clear()
481484
if self.data is None:
482485
table = None
483486
else:
@@ -493,6 +496,8 @@ def apply_domain_edit(self):
493496
table.ids = np.array(self.data.ids)
494497
table.attributes = getattr(self.data, 'attributes', {})
495498
self._inspect_discrete_variables(domain)
499+
if self.domain_editor.renamed_variables:
500+
self.Warning.renamed_vars(', '.join(self.domain_editor.renamed_variables))
496501

497502
self.Outputs.data.send(table)
498503
self.apply_button.setEnabled(False)

Orange/widgets/data/tests/test_owfile.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ def test_domain_changes_are_stored(self):
141141
data = self.get_output(self.widget.Outputs.data)
142142
self.assertIsInstance(data.domain["iris"], StringVariable)
143143

144+
def test_rename_duplicates(self):
145+
self.open_dataset("iris")
146+
147+
idx = self.widget.domain_editor.model().createIndex(3, 0)
148+
self.assertFalse(self.widget.Warning.renamed_vars.is_shown())
149+
self.widget.domain_editor.model().setData(idx, "iris", Qt.EditRole)
150+
self.widget.apply_button.click()
151+
data = self.get_output(self.widget.Outputs.data)
152+
self.assertIn("iris (1)", data.domain)
153+
self.assertIn("iris (2)", data.domain)
154+
self.assertTrue(self.widget.Warning.renamed_vars.is_shown())
155+
156+
self.widget.domain_editor.model().setData(idx, "different iris", Qt.EditRole)
157+
self.widget.apply_button.click()
158+
self.assertFalse(self.widget.Warning.renamed_vars.is_shown())
159+
144160
def test_variable_name_change(self):
145161
"""
146162
Test whether the name of the variable is changed correctly by

Orange/widgets/utils/domaineditor.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from Orange.data import DiscreteVariable, ContinuousVariable, StringVariable, \
1212
TimeVariable, Domain
13+
from Orange.data.util import get_unique_names_duplicates
1314
from Orange.statistics.util import unique
1415
from Orange.widgets import gui
1516
from Orange.widgets.gui import HorizontalGridDelegate
@@ -219,6 +220,8 @@ def __init__(self, widget):
219220
self.place_delegate = PlaceDelegate(self, VarTableModel.places)
220221
self.setItemDelegateForColumn(Column.place, self.place_delegate)
221222

223+
self.renamed_variables = []
224+
222225
@staticmethod
223226
def _is_missing(x):
224227
return str(x) in ("nan", "")
@@ -264,7 +267,7 @@ def get_domain(self, domain, data):
264267
"""
265268
# Allow type-checking with type() instead of isinstance() for exact comparison
266269
# pylint: disable=unidiomatic-typecheck
267-
270+
self.renamed_variables = []
268271
variables = self.model().variables
269272
places = [[], [], []] # attributes, class_vars, metas
270273
cols = [[], [], []] # Xcols, Ycols, Mcols
@@ -285,6 +288,13 @@ def numbers_are_round(var, col_data):
285288
((mt, Place.meta) for mt in domain.metas)))):
286289
return domain, [data.X, data.Y, data.metas]
287290

291+
unique_names = get_unique_names_duplicates([var[0] for var in variables])
292+
for var, u in zip(variables, unique_names):
293+
if var[0] != u:
294+
self.renamed_variables.append(var[0])
295+
var[0] = u
296+
self.model().set_variables(variables)
297+
288298
for (name, tpe, place, _, may_be_numeric), (orig_var, orig_plc) in \
289299
zip(variables,
290300
chain([(at, Place.feature) for at in domain.attributes],

0 commit comments

Comments
 (0)