getting selected index number of column times of a QTableView - pyqt

I am trying to index of selected row but when I try to do
1.
indexes = tableview.selectionModel().selection().indexes()
indexes will be a list of selected rows total number of column times,
even if I try
2
indexes = tableView.selectedIndexes()
this too give me the correct indexes selected but total number of column times...
I am just expecting selected row/s in list only once.

If you are selecting the entire row, you can do this by changing the SelectionBehavior of your widget. This will automatically select the entire row, instead of a single cell.
self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
After that is set, in your 'itemSelectionChanged' signal, you need to print the row for each item:
def __init__(self):
...
self.itemSelectionChanged.connect(self.selection_changed)
def selection_changed(self):
rows=[idx.row() for idx in self.selectionModel().selectedRows()]
print(rows) # or return rows
This will return the following for a table that looks like this (with this selection)
Shows a selection of:
[1, 2]
If you do not want to select every column using the SelectionBehavior, you need to change your signal a bit. selectedRows will only return a row if the entire row is selected. If you are selecting individual cells, but still only want the row, change your signal to this:
def selection_changed(self):
rows=[idx.row() for idx in self.selectionModel().selectedIndexes()]
rows = set(rows)
print(rows) # or return rows
This changes selectedRows to selectedIndexes. The important thing that you've noticed is that it will return an entry for every cell selected, even if they are on the same row. The solution to that is the line
rows = set(rows)
This will return only unique entries. Thus, the same selection as above returns
set([1,2])

Related

Can I display a pandas data frame over a range of index values (multiple rows)?

A way to display a table including the first row of a data frame (index = 0) and all columns is the following:
some_variable = df.loc[0, :]
Is there a way to so this same thing over multiple index values (displaying a range of rows)?
If I understand correctly, you want to print some top rows.
If you want top n rows
print(df.head(n))
If you want to print a set of rows.
print(df.loc[[id1,id2,id3],:])

Count number of ROWS inside each COLUMN? package XLRD

I started working with XLRD package for python 3.7.
I have a excel file that contains a fixed number of columns (20) but inside each column, the number of rows is changing (e.g.: first column has 21 rows, second column has 14 rows).
I wrote this:
for col in range(worksheet.ncols):
rows_number= worksheet.nrows
print(rows_number)
I'd like to know the number of rows for each column. With this code, I get 20 times (number of columns) the number of rows inside the first column. Actually I understand why. I'm iterating the nrows without changing the column.
How to get number of rows for all the columns?
If I try as follow, I get AttributeError since col doesn't have nrows attribute.
for col in range(worksheet.ncols):
rows_number= col.nrows
print(rows_number)
Thank you for your help!!
You can use list comprehension to get the non empty cells in a column, using col method in xlrd and comparing the Cell Type and then calculating its length
for colx in range(worksheet.ncols):
non_emptycells=[i for i,x in enumerate(sheet.col(colx)) if x.ctype is not 0]
print(len(non_emptycells))
You could use a nested while loop to work out the number of rows in each column
for c in range(worksheet.ncols):
counter = 0 # count of the rows
value = worksheet.cell(row=counter, col=c).value
while value != EMPTY:
counter += 1
row += 1
Replace the word EMPTY with a test to see if the cell is empty or not. You could then store this info in a dictionary for example once the while loop is done.

Sqlite - how to iterate through Select Rows, then use in Insert

I'm trying to add on a column in which I calculate a count column. This count columns is at the User>Timestamp level, so if you start with an ordered table, you would go down from top to bottom, incrementing the count by 1, and setting it to 0 every time you get to a new user.
The way I thought I'd do this is using a Select statement to generate the ordered results, then iterate through each row and insert each row back into a new table, but also work out the count in the process.
In this case how do I use the row object returned by
for row in c.execute(sqlStr):
and easily re-insert all the columns in this row back into a new table but also add in a new column in the process?
I'm trying to avoid having to go through all the column names returned by row and construct a messy sql string (i.e. I only want to have to specify the new column and not type out all the existing column names).
Actually think I figured it out, though not sure if it's the best way of doing it.
I've gone with doing something like:
for row in c.execute(sqlStr):
a = str(row)[:-1] +', ' + newValue

Number of Successive Cells of a Same Value in Spotfire

I am wondering if it is possible to created a calculated column that will count how many cells of the same value are successive (i.e., next to each other) so that I can divide it by the total number of cells in that column. (I'm only looking at 1's and 0's in the column. Any help or advice would be greatly appreciated as I've been scratching my head over this for a while,
The percentages at the bottom of the columns is simply = (the number of 1's touching another 1) / (total # of rows) --> my end goal
Ok this has to be done in a few steps.
Insert a calculated column RowId() and name it rid
Insert a calculated column with this expression, and name it [TouchingA]:
If(([Location A]=1) and (([Location A]=First([Location A]) over
(Next([rid]))) or ([Location A]=First([Location A]) over
(Previous([rid])))),1,0)
Insert a calculated column with this expression, and name it [TouchingB]:
If(([Site B]=1) and (([Site B]=First([Site B]) over (Next([rid]))) or
([Site B]=First([Site B]) over (Previous([rid])))),1,0)
At this point, your data will look like this:
Next, insert a CROSS TABLE and set the Horizontal Axis = (Column Names), the Vertical Axis = (None), and the Cell Values = Sum([TouchingA]) / Max([rid]) as [A Percent],
Sum([TouchingB]) / Max([rid]) as [B Percent]
This will show you the values you want, like below. Of course you can sett his in a calculated value in a text area or anywhere else you want with the proper IF or CASE statement. Lastly, you can change the formatting to make the value a % versus decimal.

Using ROW() with structured referencing to return list of selected records by criteria

My task is to return a list of items from the records in one table (with structured referencing), from another table (with structured referencing), if the record in the first table "KitList" has a quantity of 1 or greater.
Currently my closest result is using the following formula
=INDEX(KitList[Item],SMALL(IF(KitList[Quantity]>0,ROW(KitList[Quantity])),ROW(1:1)))
However, this returns incorrect values. Specifically, it returns the row after the row containing 1 (or greater), and skips the first row. i.e.
KitList
[Item]|[Quantity]
Item a | 1
Item b | 0
Item c | 2
Item d | 1
Item e | 0
Return
Item b
Item d
Item e
I think this is due to some interaction of the ROW commands counting the headers of the tables, as well as the data in them, therefore reading the range as a whole with the header, and giving an extra row in the return value. Is there a way, in the final ROW command to specify the row I need through structured referencing? Would that fix the problem?
The ROW function will return the row in the spreadsheet, not the row of the structured data. Easy solution ROW - 1
EDIT: My original answer didn't produce the desired result when copied down.
I think this is what you want:
=INDEX(KitList[Item],SMALL(IF(KitList[Quantity]>0,ROW(KitList[Quantity])-ROW(KitList[#Headers])),ROW(1:1)))
This will also allow you to move the source Table anywhere you want, i.e. the header row doesn't have to be 1:1, and the results can also be located anywhere as well.
{=INDEX(KitList[[#All],[Item]],SMALL(IF(KitList[Quantity]>0,ROW(KitList[Quantity])),ROW(1:1)))}
By specifing to the index that I want to include 'all' of the kit list table, the data and the header, not just the header, I've managed to fix the problem. Still seems awkward though.

Resources