Let's suppose I have a table with 30 columns, and want to use QSqlTableModel/QTableView and show only 5 columns. Is there some other way besides 25 times calling a setColumnHidden() function?
model = QSqlTableModel(self)
model.setTable("table")
...
view = QTableView()
view.setModel(model)
...
#insane:
view.setColumnHidden(0, True)
view.setColumnHidden(4, True)
view.setColumnHidden(6, True)
view.setColumnHidden(7, True)
view.setColumnHidden(9, True)
view.setColumnHidden(10, True)
view.setColumnHidden(11, True)
...
view.setColumnHidden(29, True)
And what if DBA add some new columns that I don't want user to see. Making changes to all installed apps to add some new view.setColumnHidden(n, True) rows? Not so practical.
Maybe there is some Qt function like view.setColumnsShown([1,2,3,5,8]) I'm not aware of?
You could define your own setColumnsShown() function:
from sets import Set
def setColumnsShown(view, showcols):
allcols = Set(range(0, view.model().columnCount()))
for col in allcols.difference(showcols):
view.setColumnHidden(col, True)
To handle the case where new columns may be added, you could connect the columnsInserted() signal of QSqlTableModel to a handler function that re-calls setColumnsShown.
I think that there isn't this function, but if you want do this automatically you can write your own function or code snippet, whick will work as you want. Unfortunately I don't familiar with Qt+Python but in C++ it can be done with this code. It is a few loops, so I think that you be able to write same code with Python syntaxis. Also I wrote comments, to show how exactly this code works.
QList<int> list;//create list where we set number of columns to be shown
list<< 1<<2;//write in list numbers of columns
int c = ui->tableView->model()->columnCount();//get count of columns
for (int i = 0; i < c; ++i)
{
ui->tableView->setColumnHidden(i,true);//hide all columns
}
for (int i = 0; i < list.length(); ++i)
{
if(list.at(i) < c)
ui->tableView->setColumnHidden(list.at(i),false);//show columns which we want
}
Related
The problem is as such:
given an array of N numbers, find two numbers in the array such that they will have a range(max - min) value of K.
for example:
input:
5 3
25 9 1 6 8
output:
9 6
So far, what i've tried is first sorting the array and then finding two complementary numbers using a nested loop. However, because this is a sort of brute force method, I don't think it is as efficient as other possible ways.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), k = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
int count = 0;
int a, b;
for(int i = 0; i < n; i++) {
for(int j = i; j < n; j++) {
if(Math.max(arr[i], arr[j]) - Math.min(arr[i], arr[j]) == k) {
a = arr[i];
b = arr[j];
}
}
}
System.out.println(a + " " + b);
}
}
Much appreciated if the solution was in code (any language).
Here is code in Python 3 that solves your problem. This should be easy to understand, even if you do not know Python.
This routine uses your idea of sorting the array, but I use two variables left and right (which define two places in the array) where each makes just one pass through the array. So other than the sort, the time efficiency of my code is O(N). The sort makes the entire routine O(N log N). This is better than your code, which is O(N^2).
I never use the inputted value of N, since Python can easily handle the actual size of the array. I add a sentinel value to the end of the array to make the inner short loops simpler and quicker. This involves another pass through the array to calculate the sentinel value, but this adds little to the running time. It is possible to reduce the number of array accesses, at the cost of a few more lines of code--I'll leave that to you. I added input prompts to aid my testing--you can remove those to make my results closer to what you seem to want. My code prints the larger of the two numbers first, then the smaller, which matches your sample output. But you may have wanted the order of the two numbers to match the order in the original, un-sorted array--if that is the case, I'll let you handle that as well (I see multiple ways to do that).
# Get input
N, K = [int(s) for s in input('Input N and K: ').split()]
arr = [int(s) for s in input('Input the array: ').split()]
arr.sort()
sentinel = max(arr) + K + 2
arr.append(sentinel)
left = right = 0
while arr[right] < sentinel:
# Move the right index until the difference is too large
while arr[right] - arr[left] < K:
right += 1
# Move the left index until the difference is too small
while arr[right] - arr[left] > K:
left += 1
# Check if we are done
if arr[right] - arr[left] == K:
print(arr[right], arr[left])
break
I've recently made a simple for loop that outputs the Max and Min of the past 5 prices and it works perfectly, creating 2 new columns showing MaxH and MinL:
for(i in 5:nrow(XBTUSD_df_s)){
XBTUSD_df_s$MaxH[i] = max(XBTUSD_df_s$Price[(i-(5-1)):i])
XBTUSD_df_s$MinL[i] = min(XBTUSD_df_s$Price[(i-(5-1)):i])
}
I then put this for loop into a function so that I can adjust how many prices I want the Max and Min to be based off like so (the print lines were added as a sanity check):
FindMaxMin = function(x){
for(i in x:nrow(XBTUSD_df_s)){
XBTUSD_df_s$MaxH[i] = max(XBTUSD_df_s$Price[(i-(x-1)):i])
XBTUSD_df_s$MinL[i] = min(XBTUSD_df_s$Price[(i-(x-1)):i])
print(XBTUSD_df_s$MaxH[i])
print(XBTUSD_df_s$MinL[i])
}
}
But after for example:
FindMaxMin(x = 10)
The console will spit out all the expected results but unlike the for loop by itself, my dataframe will not automatically add on the MaxH and MinL columns.
I've tried return() and I think most likely it is a global environment problem but can't seem to wrap my head around it.
Thanks in advance!
You need to return the object from the function and then assign it later:
FindMaxMin = function(x, XBTUSD_df_s){
for(i in x:nrow(XBTUSD_df_s)){
XBTUSD_df_s$MaxH[i] = max(XBTUSD_df_s$Price[(i-(x-1)):i])
XBTUSD_df_s$MinL[i] = min(XBTUSD_df_s$Price[(i-(x-1)):i])
print(XBTUSD_df_s$MaxH[i])
print(XBTUSD_df_s$MinL[i])
}
return (XBTUSD_df_s)
}
new = FindMaxMin(10, XBTUSD_df_s)
I want to get only first 10 or possibly n rows in-memory as java list using copyFromRealm method. Consider like this:
RealmResults<RecentViewItem> results = realm.where(RecentViewItem.class).findAllSorted("updatedAt", Sort.DESCENDING);
// This will load all rows in-memory list
List<RecentViewItem> list = realm.copyFromRealm(results);
// But I want only first n rows without running any loop.
UPDATE:
Since RealmResult extends AbstractList -
RealmResults<RecentViewItem> results =
realm.where(RecentViewItem.class)
.findAllSorted("updatedAt", Sort.DESCENDING);
List<RecentViewItem> temp = results.subList(0, maxNoRecentViewItem); // Still list of RealmProxyObject
List<RecentViewItem> list = realm.copyFromRealm(temp); // List of RecentViewItem Object
I am stuck at creating a matrix of a matrix (vector in this case)
What I have so far
index = zeros(size(A)) // This is some matrix but isn't important to the question
indexIndex = 1;
for rows=1:length(R)
for columns=1:length(K)
if(A(rows,columns)==x)
V=[rows columns]; // I create a vector holding the row + column
index(indexIndex) = V(1,2) // I want to store all these vectors
indexIndex = indexIndex + 1
end
end
end
I have tried various ways of getting the information out of V (such as V(1:2)) but nothing seems to work correctly.
In other words, I'm trying to get an array of points.
Thanks in advance
I do not understand your question exactly. What is the size of A? What is x, K and R? But under some assumptions,
Using list
You could use a list
// Create some matrix A
A = zeros(8,8)
//initialize the list
index = list();
// Get the dimensions of A
rows = size(A,1);
cols = size(A,2);
x = 0;
for row=1:rows
for col=1:cols
if(A(row,col)==x)
// Create a vector holding row and col
V=[row col];
// Append it to list using $ (last index) + 1
index($+1) = V
end
end
end
Single indexed matrices
Another approach would be to make use of the fact an multi-dimensional matrix can also be indexed by a single value.
For instance create a random matrix named a:
-->a = rand(3,3)
a =
0.6212882 0.5211472 0.0881335
0.3454984 0.2870401 0.4498763
0.7064868 0.6502795 0.7227253
Access the first value:
-->a(1)
ans =
0.6212882
-->a(1,1)
ans =
0.6212882
Access the second value:
-->a(2)
ans =
0.3454984
-->a(2,1)
ans =
0.3454984
So that proves how the single indexing works. Now to apply it to your problem and knocking out a for-loop.
// Create some matrix A
A = zeros(8,8)
//initialize the array of indices
index = [];
// Get the dimensions of A
rows = size(A,1);
cols = size(A,2);
x = 0;
for i=1:length(A)
if(A(i)==x)
// Append it to list using $ (last index) + 1
index($+1) = i;
end
end
Without for-loop
If you just need the values that adhere to a certain condition you could also do something like this
values = A(A==x);
Be carefull when comparing doubles, these are not always (un)equal when you expect.
Attempting to set up a targeting array for a MMO-style game in GameMaker8 Pro, I have this code in the create event for the player's character, which is and has been running perfectly fine:
j = 0
i = 0
g = 0
for (i=100000; i<1000000; i+=1) if instance_exists(i) {if i.object_index = enemy {global.ttarget[j] = i j+=1} if i.object_index = rk or i.object_index = sage {global.etarget[g] = i g += 1}}
global.rmtargets = j
global.etargets = g
Then running this code in the step event for the player character:
h = 0
g = 0
i = 0
for (i=0; i<global.rmtargets; i+=1) global.target[i] = 0
global.target[0]=101139
for (h = 0; h<global.rmtargets; h+=1){hv = -1
for (g = 0; g<global.rmtargets; g+=1){if global.ttarget[g].range > hv {hv = global.ttarget[g].range}}
global.target[h] = hv
global.ttarget[h] = -1}
Returns this error message:
ERROR in
action number 1
of Step Event
for object rk:
Error in code at line 8: for (g = 0; g<global.rmtargets; g+=1){if global.ttarget[g].range > hv {hv = global.ttarget[g].range}}
at position 61: Unknown variable range
Even though I have this in the create event for the enemy:
range = 0
range = distance_to_object(rk)
And I've used this sort of syntax all over:
global.target[target].threat[s] += damage
Help? Any ideas why Game Maker won't recognize the variable?
My best guess is that one or more of the enemy instances have been destroyed between the player create event and the step event where the error happens. Maybe a better solution would be to iterate over all the enemies using the with() construct, that is faster and you can be sure that all the instances you are working with actually exist.
try putting brackets around the object variable. I have had trouble references from a reference extension before.
(global.ttarget[g]).range
or even save it to a new variable
for (g = 0; g<global.rmtargets; g+=1)
{
curr_target = global.ttarget[g]
curr_target.range
}
Instead of using global. before each instance of the variable in the code, you could also initialize it with the command:
globalvar (variable), (variable2);
Then you would be able to use the variable without global. in front of it :)
If object rk is not the enemy then there is no global range variable detectable by object rk. Variables initialized without var or globalvar only apply for the object it was defined in.
First of all, put round brackets in if conditions.
Second you should give more informations about your environment and programming logic and IMO stop using all these global variables.
Anyway, from what i understood of what you're doing, try to use the with keyword:
with(global.ttarget[g]) {
other.hv = range;
}