class TestPyTableModel(TestCase): def setUp(self): self.model = PyTableModel([[1, 4], [2, 3]]) def test_init(self): self.model = PyTableModel() self.assertEqual(self.model.rowCount(), 0) def test_rowCount(self): self.assertEqual(self.model.rowCount(), 2) self.assertEqual(len(self.model), 2) def test_columnCount(self): self.assertEqual(self.model.columnCount(), 2) def test_data(self): mi = self.model.index(0, 0) self.assertEqual(self.model.data(mi), '1') self.assertEqual(self.model.data(mi, Qt.EditRole), 1) def test_editable(self): editable_model = PyTableModel([[0]], editable=True) self.assertFalse( int(self.model.flags(self.model.index(0, 0)) & Qt.ItemIsEditable)) self.assertTrue( int( editable_model.flags(editable_model.index(0, 0)) & Qt.ItemIsEditable)) def test_sort(self): self.model.sort(1) self.assertEqual(self.model[0][0], 2) def test_setHeaderLabels(self): self.model.setHorizontalHeaderLabels(['Col 1', 'Col 2']) self.assertEqual(self.model.headerData(1, Qt.Horizontal), 'Col 2') self.assertEqual(self.model.headerData(1, Qt.Vertical), '1') def test_removeRows(self): self.model.removeRows(0, 1) self.assertEqual(len(self.model), 1) self.assertEqual(self.model[0][1], 3) def test_removeColumns(self): self.model.removeColumns(0, 1) self.assertEqual(self.model.columnCount(), 1) self.assertEqual(self.model[1][0], 3) def test_insertRows(self): self.model.insertRows(0, 1) self.assertEqual(self.model[1][0], 1) def test_insertColumns(self): self.model.insertColumns(0, 1) self.assertEqual(self.model[0], ['', 1, 4]) def test_wrap(self): self.model.wrap([[0]]) self.assertEqual(self.model.rowCount(), 1) self.assertEqual(self.model.columnCount(), 1) def test_clear(self): self.model.clear() self.assertEqual(self.model.rowCount(), 0) def test_append(self): self.model.append([5, 6]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_extend(self): self.model.extend([[5, 6]]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_insert(self): self.model.insert(0, [5, 6]) self.assertEqual(self.model[0][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_remove(self): self.model.remove([2, 3]) self.assertEqual(self.model.rowCount(), 1) def test_other_roles(self): self.model.append([2, 3]) self.model.setData(self.model.index(2, 0), Qt.AlignCenter, Qt.TextAlignmentRole) del self.model[1] self.assertTrue( Qt.AlignCenter & self.model.data(self.model.index(1, 0), Qt.TextAlignmentRole))
class TestPyTableModel(unittest.TestCase): def setUp(self): self.model = PyTableModel([[1, 4], [2, 3]]) def test_init(self): self.model = PyTableModel() self.assertEqual(self.model.rowCount(), 0) def test_rowCount(self): self.assertEqual(self.model.rowCount(), 2) self.assertEqual(len(self.model), 2) def test_columnCount(self): self.assertEqual(self.model.columnCount(), 2) def test_data(self): mi = self.model.index(0, 0) self.assertEqual(self.model.data(mi), '1') self.assertEqual(self.model.data(mi, Qt.EditRole), 1) def test_editable(self): editable_model = PyTableModel([[0]], editable=True) self.assertFalse( int(self.model.flags(self.model.index(0, 0)) & Qt.ItemIsEditable)) self.assertTrue( int( editable_model.flags(editable_model.index(0, 0)) & Qt.ItemIsEditable)) def test_sort(self): self.model.sort(1) self.assertEqual(self.model.index(0, 0).data(Qt.EditRole), 2) def test_setHeaderLabels(self): self.model.setHorizontalHeaderLabels(['Col 1', 'Col 2']) self.assertEqual(self.model.headerData(1, Qt.Horizontal), 'Col 2') self.assertEqual(self.model.headerData(1, Qt.Vertical), 2) def test_removeRows(self): self.model.removeRows(0, 1) self.assertEqual(len(self.model), 1) self.assertEqual(self.model[0][1], 3) def test_removeColumns(self): self.model.removeColumns(0, 1) self.assertEqual(self.model.columnCount(), 1) self.assertEqual(self.model[1][0], 3) def test_insertRows(self): self.model.insertRows(0, 1) self.assertEqual(self.model[1][0], 1) def test_insertColumns(self): self.model.insertColumns(0, 1) self.assertEqual(self.model[0], ['', 1, 4]) def test_wrap(self): self.model.wrap([[0]]) self.assertEqual(self.model.rowCount(), 1) self.assertEqual(self.model.columnCount(), 1) def test_clear(self): self.model.clear() self.assertEqual(self.model.rowCount(), 0) def test_append(self): self.model.append([5, 6]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_extend(self): self.model.extend([[5, 6]]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_insert(self): self.model.insert(0, [5, 6]) self.assertEqual(self.model[0][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_remove(self): self.model.remove([2, 3]) self.assertEqual(self.model.rowCount(), 1) def test_other_roles(self): self.model.append([2, 3]) self.model.setData(self.model.index(2, 0), Qt.AlignCenter, Qt.TextAlignmentRole) del self.model[1] self.assertTrue( Qt.AlignCenter & self.model.data(self.model.index(1, 0), Qt.TextAlignmentRole)) def test_set_iten_slice(self): self.model[:1] = [[10, 11], [12, 13], [14, 15]] self.assertEqual(list(self.model), [[10, 11], [12, 13], [14, 15], [2, 3]]) self.model[1:3] = [] self.assertEqual(list(self.model), [[10, 11], [2, 3]]) self.model[:] = [[20, 21]] self.assertEqual(list(self.model), [[20, 21]]) self.model[1:] = [[10, 11], [2, 3]] self.assertEqual(list(self.model), [[20, 21], [10, 11], [2, 3]]) def test_emits_column_changes_on_row_insert(self): inserted = [] removed = [] model = PyTableModel() model.columnsInserted.connect(inserted.append) model.columnsRemoved.connect(removed.append) inserted = QSignalSpy(model.columnsInserted) removed = QSignalSpy(model.columnsRemoved) model.append([2]) self.assertEqual(list(inserted)[-1][1:], [0, 0]) model.append([2, 3]) self.assertEqual(list(inserted)[-1][1:], [1, 1]) del model[:] self.assertEqual(list(removed)[0][1:], [0, 1]) model.extend([[0, 1], [0, 2]]) self.assertEqual(list(inserted)[-1][1:], [0, 1]) model.clear() self.assertEqual(list(removed)[0][1:], [0, 1]) model[:] = [[1], [2]] self.assertEqual(list(inserted)[-1][1:], [0, 0])
class TestPyTableModel(unittest.TestCase): def setUp(self): self.model = PyTableModel([[1, 4], [2, 3]]) def test_init(self): self.model = PyTableModel() self.assertEqual(self.model.rowCount(), 0) def test_rowCount(self): self.assertEqual(self.model.rowCount(), 2) self.assertEqual(len(self.model), 2) def test_columnCount(self): self.assertEqual(self.model.columnCount(), 2) def test_data(self): mi = self.model.index(0, 0) self.assertEqual(self.model.data(mi), '1') self.assertEqual(self.model.data(mi, Qt.EditRole), 1) def test_editable(self): editable_model = PyTableModel([[0]], editable=True) self.assertFalse(int(self.model.flags(self.model.index(0, 0)) & Qt.ItemIsEditable)) self.assertTrue(int(editable_model.flags(editable_model.index(0, 0)) & Qt.ItemIsEditable)) def test_sort(self): self.model.sort(1) self.assertEqual(self.model.index(0, 0).data(Qt.EditRole), 2) def test_setHeaderLabels(self): self.model.setHorizontalHeaderLabels(['Col 1', 'Col 2']) self.assertEqual(self.model.headerData(1, Qt.Horizontal), 'Col 2') self.assertEqual(self.model.headerData(1, Qt.Vertical), 2) def test_removeRows(self): self.model.removeRows(0, 1) self.assertEqual(len(self.model), 1) self.assertEqual(self.model[0][1], 3) def test_removeColumns(self): self.model.removeColumns(0, 1) self.assertEqual(self.model.columnCount(), 1) self.assertEqual(self.model[1][0], 3) def test_insertRows(self): self.model.insertRows(0, 1) self.assertEqual(self.model[1][0], 1) def test_insertColumns(self): self.model.insertColumns(0, 1) self.assertEqual(self.model[0], ['', 1, 4]) def test_wrap(self): self.model.wrap([[0]]) self.assertEqual(self.model.rowCount(), 1) self.assertEqual(self.model.columnCount(), 1) def test_clear(self): self.model.clear() self.assertEqual(self.model.rowCount(), 0) def test_append(self): self.model.append([5, 6]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_extend(self): self.model.extend([[5, 6]]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_insert(self): self.model.insert(0, [5, 6]) self.assertEqual(self.model[0][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_remove(self): self.model.remove([2, 3]) self.assertEqual(self.model.rowCount(), 1) def test_other_roles(self): self.model.append([2, 3]) self.model.setData(self.model.index(2, 0), Qt.AlignCenter, Qt.TextAlignmentRole) del self.model[1] self.assertTrue(Qt.AlignCenter & self.model.data(self.model.index(1, 0), Qt.TextAlignmentRole))
class TestPyTableModel(TestCase): def setUp(self): self.model = PyTableModel([[1, 4], [2, 3]]) def test_init(self): self.model = PyTableModel() self.assertEqual(self.model.rowCount(), 0) def test_rowCount(self): self.assertEqual(self.model.rowCount(), 2) self.assertEqual(len(self.model), 2) def test_columnCount(self): self.assertEqual(self.model.columnCount(), 2) def test_data(self): self.assertEqual(str(self.model.data(self.model.index(0, 0))), '1') def test_sort(self): self.model.sort(1) self.assertEqual(self.model[0][0], 2) def test_setHeaderLabels(self): self.model.setHorizontalHeaderLabels(['Col 1', 'Col 2']) self.assertEqual(self.model.headerData(1, Qt.Horizontal), 'Col 2') self.assertEqual(self.model.headerData(1, Qt.Vertical), '1') def test_removeRows(self): self.model.removeRows(0, 1) self.assertEqual(len(self.model), 1) self.assertEqual(self.model[0][1], 3) def test_removeColumns(self): self.model.removeColumns(0, 1) self.assertEqual(self.model.columnCount(), 1) self.assertEqual(self.model[1][0], 3) def test_insertRows(self): self.model.insertRows(0, 1) self.assertEqual(self.model[1][0], 1) def test_insertColumns(self): self.model.insertColumns(0, 1) self.assertEqual(self.model[0], ['', 1, 4]) def test_wrap(self): self.model.wrap([[0]]) self.assertEqual(self.model.rowCount(), 1) self.assertEqual(self.model.columnCount(), 1) def test_clear(self): self.model.clear() self.assertEqual(self.model.rowCount(), 0) def test_append(self): self.model.append([5, 6]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_extend(self): self.model.extend([[5, 6]]) self.assertEqual(self.model[2][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_insert(self): self.model.insert(0, [5, 6]) self.assertEqual(self.model[0][1], 6) self.assertEqual(self.model.rowCount(), 3) def test_remove(self): self.model.remove([2, 3]) self.assertEqual(self.model.rowCount(), 1)
class OWRankSurvivalFeatures(OWWidget, ConcurrentWidgetMixin): name = 'Rank Survival Features' # TODO: Add widget metadata description = '' icon = 'icons/owranksurvivalfeatures.svg' priority = 30 keywords = [] buttons_area_orientation = Qt.Vertical select_none, manual_selection, select_n_best = range(3) settingsHandler = DomainContextHandler() selected_attrs = ContextSetting([], schema_only=True) selection_method = Setting(select_n_best, schema_only=True) n_selected = Setting(20, schema_only=True) auto_commit: bool = Setting(False, schema_only=True) class Inputs: data = Input('Data', Table) class Outputs: reduced_data = Output('Reduced Data', Table, default=True) def __init__(self): OWWidget.__init__(self) ConcurrentWidgetMixin.__init__(self) self.data: Optional[Table] = None self.attr_name_to_variable: Optional[Table] = None self.covariates_from_worker_result = None self.time_var: Optional[str] = None self.event_var: Optional[str] = None gui.rubber(self.controlArea) sel_method_box = gui.vBox(self.buttonsArea, 'Select Attributes') grid = QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.setSpacing(6) self.select_buttons = QButtonGroup() self.select_buttons.buttonClicked[int].connect( self.set_selection_method) def button(text, buttonid, toolTip=None): b = QRadioButton(text) self.select_buttons.addButton(b, buttonid) if toolTip is not None: b.setToolTip(toolTip) return b b1 = button(self.tr('None'), OWRankSurvivalFeatures.select_none) b2 = button(self.tr('Manual'), OWRankSurvivalFeatures.manual_selection) b3 = button(self.tr('Best ranked:'), OWRankSurvivalFeatures.select_n_best) s = gui.spin( sel_method_box, self, 'n_selected', 1, 999, callback=lambda: self.set_selection_method(OWRankSurvivalFeatures. select_n_best), addToLayout=False, ) grid.addWidget(b1, 0, 0) grid.addWidget(b2, 1, 0) grid.addWidget(b3, 2, 0) grid.addWidget(s, 2, 1) sel_method_box.layout().addLayout(grid) self.commit_button = gui.auto_commit(self.buttonsArea, self, 'auto_commit', '&Commit', box=False) # Main area self.model = PyTableModel(parent=self) self.table_view = TableView(parent=self) self.table_view.setModel(self.model) self.model.setHorizontalHeaderLabels([ 'Log-Likelihood', 'Log-Likelihood Ratio', f'{"p".center(13)}', 'FDR' ]) self.table_view.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.table_view.selectionModel().selectionChanged.connect( self.on_select) def _set_select_manual(): self.set_selection_method(OWRankSurvivalFeatures.manual_selection) self.table_view.manualSelection.connect(_set_select_manual) self.table_view.verticalHeader().sectionClicked.connect( _set_select_manual) self.mainArea.layout().addWidget(self.table_view) @property def covariates(self) -> Optional[List[str]]: if not self.data: return return [attr.name for attr in self.data.domain.attributes] @Inputs.data @check_survival_data def set_data(self, data: Table): self.closeContext() self.selected_attrs = [] self.covariates_from_worker_result = [] self.model.clear() self.model.resetSorting() if not data: return self.data = data self.attr_name_to_variable = { attr.name: attr for attr in self.data.domain.attributes } self.openContext(data) time_var, event_var = get_survival_endpoints(self.data.domain) self.time_var, self.event_var = time_var.name, event_var.name self.start(worker, self.data, self.covariates, self.time_var, self.event_var) def commit(self): if not self.selected_attrs: self.Outputs.reduced_data.send(None) else: reduced_domain = Domain(self.selected_attrs, self.data.domain.class_vars, self.data.domain.metas) data = self.data.transform(reduced_domain) self.Outputs.reduced_data.send(data) def on_done(self, worker_result): covariate_names, results = worker_result # wrap everything except covariate names self.model.wrap(results.tolist()) # this is temp solution because covariate orders gets mixed when using multiprocessing self.covariates_from_worker_result = covariate_names.tolist() # match covariate names to domain variables and set vertical header self.model.setVerticalHeaderLabels( [self.attr_name_to_variable[name] for name in covariate_names]) self.table_view.resizeColumnsToContents() self.auto_select() def on_exception(self, ex): raise ex def on_partial_result(self, result: Any) -> None: pass def set_selection_method(self, method): self.selection_method = method self.select_buttons.button(method).setChecked(True) self.auto_select() def auto_select(self): selection_model = self.table_view.selectionModel() row_count = self.model.rowCount() column_count = self.model.columnCount() if self.selection_method == OWRankSurvivalFeatures.select_none: selection = QItemSelection() elif self.selection_method == OWRankSurvivalFeatures.select_n_best: n_selected = min(self.n_selected, row_count) selection = QItemSelection( self.model.index(0, 0), self.model.index(n_selected - 1, column_count - 1)) else: selection = QItemSelection() if self.selected_attrs is not None: attr_indices = [ self.covariates_from_worker_result.index(var.name) for var in self.selected_attrs ] for row in self.model.mapFromSourceRows(attr_indices): selection.append( QItemSelectionRange( self.model.index(row, 0), self.model.index(row, column_count - 1))) selection_model.select(selection, QItemSelectionModel.ClearAndSelect) def on_select(self): selected_rows = self.table_view.selectionModel().selectedRows(0) row_indices = [i.row() for i in selected_rows] attr_indices = self.model.mapToSourceRows(row_indices) self.selected_attrs = [ self.model._headers[Qt.Vertical][row] for row in attr_indices ] self.commit()