Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Slow Rank #2494

Merged
merged 8 commits into from
Sep 20, 2017
Merged

[FIX] Slow Rank #2494

merged 8 commits into from
Sep 20, 2017

Conversation

kernc
Copy link
Contributor

@kernc kernc commented Jul 25, 2017

Issue

Fixes #2478

Description of changes

Updated owrank to use PyTableModel and its faster sorting, but then I kinda broke something. Then I kinda fixed it by refactoring the whole widget into something I could understand. And it still somewhat works.

Old selection settings won't restore correctly as they were saved as indices of sorted values. Suggestions welcome.

Includes
  • Code changes
  • Tests
  • Documentation

@codecov-io
Copy link

codecov-io commented Jul 25, 2017

Codecov Report

Merging #2494 into master will increase coverage by 0.02%.
The diff coverage is 87.84%.

@@            Coverage Diff            @@
##           master   #2494      +/-   ##
=========================================
+ Coverage   75.08%   75.1%   +0.02%     
=========================================
  Files         329     329              
  Lines       57773   57636     -137     
=========================================
- Hits        43377   43289      -88     
+ Misses      14396   14347      -49


def setHorizontalHeaderLabels(self, labels):
self._headers[Qt.Horizontal] = labels
def setHorizontalHeaderLabels(self, labels: [str or Variable]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a valid type annotation


def setVerticalHeaderLabels(self, labels):
self._headers[Qt.Vertical] = labels
def setVerticalHeaderLabels(self, labels: [str or Variable]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a valid type annotation

"""
A sorting proxy table model that sorts its rows in fast numpy,
avoiding potentially thousands of calls into
``QSortFilterProxyModel.lessThan()`` or any potenrially costly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potenrially -> potentially

header.setSectionResizeMode(header.Fixed)
header.setFixedWidth(50)
header.setDefaultSectionSize(22)
header.setTextElideMode(Qt.ElideMiddle) # QT-BUG
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. :)

selection.append(QItemSelectionRange(
model.index(row, 0), model.index(row, columnCount - 1)))

selModel.select(selection, QItemSelectionModel.ClearAndSelect)

self.setFocus(Qt.OtherFocusReason) # Prevent graying out scores?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not do this. It steals keyboard focus from the "Best ranked:" spin box while editing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return self.__sortIndInv[rows]
return rows

def invalidate(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invalidate -> resetSorting?

'invalidate' indicates that something is no longer valid. Is it even needed? It is equivalent to sort(-1).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep it as I get to override it in Rank's model.

"""The current sort order"""
return self.__sortOrder

def mapToSource(self, rows: int or numpy.ndarray or Ellipsis):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only evaluates to def mapToSource(self, rows: int):

Union[int, Sequence[int], type(...)] would be better.

However I would drop the Ellipsis unless you assure the returned array is is a copy or a read only view. Otherwise it makes little sense to keep __sortInd private.

I am also not too thrilled about the name. mapToSourceRows would be better (
I purposefully did not chose this name in TableModel in order to differentiate from QAbstractProxyModel.map{To,From}Source)

@@ -819,7 +959,7 @@ def addAction(self, action, *args):
return self.insertAction(-1, action, *args)


class TableModel(QAbstractTableModel):
class TableModel(AbstractSortTableModel, QAbstractTableModel):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AbstractSortTableModel is already an QAbstractTableModel.

self.Error.clear()
self.Information.clear()
self.Information.missings_imputed(
shown=self.data is not None and self.data.has_missing())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.data -> data
self.data is still the old dataset here.

# Settings as of version 3.3.5
settings = {
'__version__': 1,
Copy link
Member

@astaric astaric Sep 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Settings in 3.3.5 did not have versions yet. Therefore, __version__ was not present in the dict.

return str(left_data) < str(right_data)
# If older settings, restore sort header to default
# Saved selected_rows will likely be incorrect
if version is None or version < 2:
Copy link
Member

@astaric astaric Sep 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why check for None?
When settings dict does not have the __version__ key, 0 is passed as version

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backwards compatibility. 642e446 😎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rank widget takes ages to compute for moderate-sized data sets
5 participants