diff --git a/Orange/widgets/data/owimpute.py b/Orange/widgets/data/owimpute.py index 691ddb5b9c3..08270311e4f 100644 --- a/Orange/widgets/data/owimpute.py +++ b/Orange/widgets/data/owimpute.py @@ -13,9 +13,8 @@ QVBoxLayout, QStackedWidget, QComboBox, QWidget, QButtonGroup, QStyledItemDelegate, QListView, QDoubleSpinBox, QLabel ) -from AnyQt.QtCore import Qt, QThread, QModelIndex, QDateTime, QLocale +from AnyQt.QtCore import Qt, QThread, QModelIndex, QDateTime from AnyQt.QtCore import pyqtSlot as Slot -from AnyQt.QtGui import QDoubleValidator from orangewidget.utils.listview import ListViewSearch @@ -127,6 +126,10 @@ def var_key(var): return qname, var.name +DBL_MIN = np.finfo(float).min +DBL_MAX = np.finfo(float).max + + class OWImpute(OWWidget): name = "Impute" description = "Impute missing values in the data table." @@ -156,7 +159,7 @@ class Warning(OWWidget.Warning): _variable_imputation_state = settings.ContextSetting({}) # type: VariableState autocommit = settings.Setting(True) - default_numeric = settings.Setting("") + default_numeric_value = settings.Setting(0.0) default_time = settings.Setting(0) want_main_area = False @@ -206,17 +209,19 @@ def set_default_time(datetime): button.setChecked(Method.Default == self.default_method_index) hlayout.addWidget(button) - locale = QLocale() - locale.setNumberOptions(locale.NumberOption.RejectGroupSeparator) - validator = QDoubleValidator() - validator.setLocale(locale) - self.numeric_value_widget = le = gui.lineEdit( - None, self, "default_numeric", - validator=validator, alignment=Qt.AlignRight, - callback=self._invalidate, - enabled=self.default_method_index == Method.Default + self.numeric_value_widget = QDoubleSpinBox( + minimum=DBL_MIN, maximum=DBL_MAX, singleStep=.1, decimals=5, + value=self.default_numeric_value, + alignment=Qt.AlignRight, + enabled=self.default_method_index == Method.Default, ) - hlayout.addWidget(le) + self.numeric_value_widget.editingFinished.connect( + self.__on_default_numeric_value_edited + ) + self.connect_control( + "default_numeric_value", self.numeric_value_widget.setValue + ) + hlayout.addWidget(self.numeric_value_widget) hlayout.addWidget(QLabel(", time:")) @@ -278,7 +283,7 @@ def set_default_time(datetime): ) self.value_double = QDoubleSpinBox( editingFinished=self._on_value_selected, - minimum=-1000., maximum=1000., singleStep=.1, decimals=3, + minimum=DBL_MIN, maximum=DBL_MAX, singleStep=.1, decimals=5, ) self.value_stack = value_stack = QStackedWidget() value_stack.addWidget(self.value_combo) @@ -323,15 +328,9 @@ def create_imputer(self, method, *args): m.method = default return m elif method == Method.Default and not args: # global default values - if self.default_numeric == "": - default_num = np.nan - else: - default_num, ok = QLocale().toDouble(self.default_numeric) - if not ok: - default_num = np.nan return impute.FixedValueByType( - default_continuous=default_num, - default_time=self.default_time or np.nan + default_continuous=self.default_numeric_value, + default_time=self.default_time ) else: return METHODS[method](*args) @@ -357,6 +356,13 @@ def set_default_method(self, index): """ self.default_method_index = index + def __on_default_numeric_value_edited(self): + val = self.numeric_value_widget.value() + if val != self.default_numeric_value: + self.default_numeric_value = val + if self.default_method_index == Method.Default: + self._invalidate() + @Inputs.data @check_sql_input def set_data(self, data): diff --git a/Orange/widgets/data/tests/test_owimpute.py b/Orange/widgets/data/tests/test_owimpute.py index 7538a8bfa10..397061c65e7 100644 --- a/Orange/widgets/data/tests/test_owimpute.py +++ b/Orange/widgets/data/tests/test_owimpute.py @@ -132,7 +132,7 @@ def test_overall_default(self): data = Table(domain, x, np.empty((2, 0))) widget = self.widget - widget.default_numeric = QLocale().toString(3.14) + widget.default_numeric_value = 3.14 widget.default_time = 42 widget.default_method_index = Method.Default