How to increment count id for each insert and every loop iteration? - coldfusion

I have for loop that should increment count_id for every query and each loop iteration. Here is example of my code:
qryCode = queryExecute("SELECT max(display_order) AS maxdisplay FROM type_ref",{},{datasource: application.datasource}); // Result set of the query is: 58
qryItems = queryExecute("SELECT DISTINCT type_id, label, type_shortcode FROM types gtr WHERE item_id = :item_id",{item_id: {cfsqltype: "cf_sql_numeric",value: arguments.item_id}},{datasource: application.datasource});
// Result set of qryItems:
TYPE_ID LABEL TYPE_SHORTCODE
1 2012-1 HOA
2 2012-1 HOC
5 2012-1 HOR
local.display_count = qryCode.maxdisplay;
for ( row in qryItems ) {
local.sqlInsert &= " INSERT INTO type_ref (display_order) VALUES (?) ";
qryParams.append({cfsqltype="CF_SQL_NUMERIC", value: display_count+1});
local.sqlInsert &= " INSERT INTO type_ref (display_order) VALUES (?) ";
qryParams.append({cfsqltype="CF_SQL_NUMERIC", value: display_count+2});
display_count++;
}
The code above will increment first two values correct (59 & 60) but for the second iteration it will start from 60 instead of 61. The code should produce count_id's int his order: 59,60,61,62,63,64. There are three records in qryItems. The qryCode has max value of 58. The first query in first iteration should start from 58 + 1 = 59. The next one should be 58 + 2 = 60. In the second iteration the first count_id should be 61 and so on. I'm not sure why the code I have above starts second iteration from 60 instead of 61. I do have this line that should increase the count_id at the end of each iteration: display_count++;.

It's because you're doing 2 inserts per iteration, therefore you should increment display_count by 2 instead of 1. So your for loop should look like this instead.
for ( row in qryItems ) {
local.sqlInsert &= " INSERT INTO type_ref (display_order) VALUES (?) ";
qryParams.append({cfsqltype="CF_SQL_NUMERIC", value: display_count+1});
local.sqlInsert &= " INSERT INTO type_ref (display_order) VALUES (?) ";
qryParams.append({cfsqltype="CF_SQL_NUMERIC", value: display_count+2});
display_count +=2;
}

How about
for ( row in qryItems ) {
local.sqlInsert &= " INSERT INTO type_ref (display_order) VALUES (?),(?) ";
qryParams.append({cfsqltype="CF_SQL_NUMERIC", value: ++display_count});
qryParams.append({cfsqltype="CF_SQL_NUMERIC", value: ++display_count});
}
Also see: Inserting multiple rows in a single SQL query?

Related

google sheets Get the last non-empty cell in a ROW

this is the simplified version of my data.
How can I calculate E and F columns? the address format of E column is not important.
put this custom formula to E2 =last_item_index(A2:D)
and here is the custom function code:
/**
* #customfunction
*/
function last_item_index(range) {
const colCount = range[0].length
const lastItemIndices = range.map(row=>{
const indexFirstNonEmpty = row.reverse().findIndex(cell=>cell)
const indexLastNonEmpty = colCount - 1 - indexFirstNonEmpty
return indexFirstNonEmpty>=0? [indexLastNonEmpty, row[indexFirstNonEmpty]] : ['','']
})
return lastItemIndices
}
The value returned in column E will be the zero-based index of the last non-empty item. You can easy convert it to A1-formatted range with ADDRESS function.
try:
=INDEX(IFNA(REGEXEXTRACT(" "&TRIM(FLATTEN(QUERY(TRANSPOSE(IF(A2:D="",,
ADDRESS(ROW(A2:A), COLUMN(A:D), 4))),,9^9))), " (.{1,3}\d+)$")))
and:
=INDEX(IFNA(SUBSTITUTE(REGEXEXTRACT(" "&TRIM(FLATTEN(QUERY(TRANSPOSE(IF(A2:D="",,
SUBSTITUTE(A2:D, " ", "♦"))),,9^9))), "((?:[^ ]+ *){1})$"), "♦", " ")))

Displaying results from ranksum

I'm trying to modify the code posted by #Nick Cox in my previous question but I have some issues.
I have set my varlist and my group variable. I have also changed the col option to fit my varname. I would like to add the number of observations for each group r(N 1) / r(N 2) and put over the results list some "titles".
I am trying to study the display command but I cannot figure out a solution.
My code is the following:
foreach v of var BVCAlogMAR AvgSSI L1DensityWholeImage {
quietly ranksum `v', by(G6PDcarente) porder
scalar pval = 2*normprob(-abs(r(z)))
di "`v'{col 34}" %05.3f pval " " %6.4e pval " " %05.3f r(porder) ///
" " %05.3f r(N 1) " " %05.3f r(N 2)
}
I am not able to put in the results list the values of r(N 1) and r(N 2) . Moreover, I have no idea how to show a column header with the following title:
P-Value, PValue2, Porder- Observ. group 1 - Observ. group 2
Can you please help me?
You are incorrectly referring to r(N_1) and r(N_2) as r(N 1) and r(N 2) respectively.
In the toy example provided in your previous post, i have corrected this mistake and i inserted six additional lines in bold, which achieve what you want:
sysuse auto, clear
local i = 0
foreach v of var mpg price weight length displacement {
local ++i
quietly ranksum `v', by(foreign) porder
scalar pval = 2*normprob(-abs(r(z)))
if `i' == 1 {
display %20s "P-Value", %5s "PValue2", %5s "Porder1", %5s "group 1", %5s "group 2"
display ""
}
display "`v'{col 14}" %05.3f pval " " %6.4e pval " " %05.3f r(porder) ///
" " %05.3f r(N_1) " " %05.3f r(N_2)
}
The first display command acts as a header, but you will have to play with the values to get the desired spacing. The second merely adds a blank line.
The counter macro i serves to display the header and blank lines only in the first step of the for loop instead of them repeating for each variable.
The results are illustrated below:
P-Value PValue2 Porder1 group 1 group 2
mpg 0.002 1.9e-03 0.271 52.000 22.000
price 0.298 3.0e-01 0.423 52.000 22.000
weight 0.000 3.8e-07 0.875 52.000 22.000
length 0.000 9.4e-07 0.862 52.000 22.000
displacement 0.000 1.1e-08 0.921 52.000 22.000
For more information about output formatting using the display command, type help format in Stata's command prompt.

Coldfusion/Lucee - Loop over 3D array to insert into database using multiple inserts using one query

I know the title is a mouth-full - sorry about that but trying to be specific here.
DB: MySql (technically Maria)
ColdFusion (technically Lucee: 5.x)
The array looks like the following:
NOTE: the outter most array only shows part of 2 and could continue through into the 30's.
I'm looking to perform a loop over the array to insert the elements marked as "string" in the image into the database using one query. Query has been trimmed for the sake of clarity and conciseness:
for (outer = 1; outer <= ArrayLen(myArray); outer++) {
local.currentrow = local.currentrow + 1;
for (inner = 1; inner <= ArrayLen(myArray[outer]); inner++) {
local.sql = "
INSERT INTO table (uuid, typeID, menuId, activityID, userID)
VALUES (
'#local.uuid#',
#myArray[outer][inner][1]#,
#myArray[outer][inner][2]#,
#myArray[outer][inner][3]#,
#arguments.formDataStruct.userID#
)";
queryExecute(local.sql);
}
}
I'm looking for something along this line but as written, it isn't working:
local.sql = "
INSERT INTO table (uuid, typeID, menuId, activityID, userID)
VALUES (
if (local.currentrow gt 1) {
,
}
for (outer = 1; outer <= ArrayLen(myArray); outer++) {
local.currentrow = local.currentrow + 1;
for (inner = 1; inner <= ArrayLen(myArray[outer]); inner++) {
'#local.uuid#',
'#myArray[outer][inner][1]#',
'#myArray[outer][inner][2]#',
'#myArray[outer][inner][3]#',
'#arguments.formDataStruct.userID#'
}
})
";
queryExecute(local.sql);
The error message I'm getting is
Element at position [1] doesn't exist in array
but if I perform a writedump[1][3][3] (e.g.), I'll get the value 24.
I would recommend against looping over an INSERT statement and rather just loop over VALUES to generate a single INSERT statement. A single INSERT will perform significantly faster, plus it will minimize the connections to your database.
Build out the list of values with something like:
for (var outer in arguments.inArray) {
for (var inner in outer) {
// Concat elements of inner array to a SQL VALUE string. If UUID is supposed to be a unique identity for the row, use Maria's uuid() instead of CF (or skip the UUID insert and let Maria do it).
// inArray elements and inUserID should be sanitized.
local.values &= "( uuid(), '" & inner[1] & "','" & inner[2] & "','" & inner[3] & "'," & local.userID & ")," ;
}
}
local.values = left(local.values,len(local.values)-1) ; // Get rid of the last comma.
local.sql = "INSERT INTO table (uuid, typeID, menuId, activityID, userID) VALUES " & local.values ;
After you've built up the SQL INSERT string, execute the query to INSERT the records. (You would probably build the above function differently to handle building the query string and parameters and then executing it all in one place.)
Don't forget to sanitize your array and other inputs. Does the array come from a source you control or is it user input?
https://trycf.com/gist/7ad6af1e84906b601834b0cc5ff5a392/lucee5?theme=monokai
http://dbfiddle.uk/?rdbms=mariadb_10.2&fiddle=d11f45f30723ba910c58a1e3f7a7c30b

Sorting of numeric values in python

Here i get the input from the user.
This is my code
num_array=list()
x=int(raw_input('Enter the numbers:'))
for i in range(int(x)):
n=raw_input("")
num_array.append(int(n))
print("\nThe numbers in ascending order are:%d" %(num_array.sort())
And when i want to print the numbers ,it is showing me an error.
I want output to look like this
Enter the number:
5
4
3
2
1
The numbers in ascending order are 1 2 3 4 5
Here is your code
num_array=list()
x=int(raw_input('Enter the numbers:'))
for i in range(int(x)):
n=raw_input("")
num_array.append(int(n))
#print(sorted(num_array))
arr = sorted(num_array)
output = ""
for x in arr:
output = output + str(x) + " "
print(output)
this may be what you want (replaced % print statement with .format() syntax).
num_array.sort() will sort your array but will return None (and that is what your print statement will try to print). sorted on the other hand returns a list.
num_array = []
x = int(raw_input('Enter length of the array: '))
for i in range(int(x)):
n = raw_input("number '{}': ".format(i))
num_array.append(int(n))
print("\nThe numbers in ascending order are: {}".format(sorted(num_array)))
if you do not want the output to look like a python list you could to this:
sorted_str = ' '.join(str(n) for n in sorted(num_array))
print("\nThe numbers in ascending order are: {}".format(sorted_str))

C++ Data Parsing query

Hello guys i hope you could enlighten me with this issue i am facing!
Initial Output:
The sample text file is below and the format is as follow (Item Desc:Price:Quantity:Date).
STRAW:10:10:11NOV1991
BARLEY:5.10:5:19OCT1923
CHOCOLATE:50:50:11NOV1991
I am required to print out a daily summary report of the total amt of sales on that day. Based on the sample above, the result will be on 11 NOV 1991 the total amt of sales(2 items) will be 60 while on 19OCT1923 the total amt of sales(1 item) will be 5.
Desired Output:
11Nov1991 Total amt of sales:60
19Oct1923 Total amt of sales:5
My question is, how do i generate the code to show only one unique date with the total amount of sales? I have created a loop to check if that a certain year exist for testing purposes but it isn't working. I want it to be able to iterate through a file and check if a certain year exist and if it exist already, the next vector element that has the same year won't be written to a file but instead only the item price will be added. Below is the code i am trying to implement.
ifstream readReport("DailyReport.txt");
ofstream writeDailyReport("EditedDailyReport.txt");
string temp1 = "";
//Read from empty report.txt
while(getline(readReport,temp1))
{
for(int i=0; i < itemDescVec.size(); i++)
{
stringstream streamYearSS;
streamYearSS << itemDescVec[i].dateYear;
string stringYear = streamYearSS.str();
size_t found1 = temp1.find(stringYear);
//If can find year
if (found1 != string::npos )
{
cout << "Can find" << endl;
}
//If cannot find year
else if (found1 == string::npos )
{
cout << "Cannot find" << endl;
writeDailyReport << itemDescVec[i].itemDescription << ":" << itemDescVec[i].unitPrice << ":"
<< itemDescVec[i].quantity << ":" << itemDescVec[i].dateDay << "/" << itemDescVec[i].dateMonth << "/" << itemDescVec[i].dateYear
<< endl;
}
}
}
readReport.close();
writeDailyReport.close();
remove("DailyReport.txt");
rename("EditedDailyReport.txt", "DailyReport.txt");
It would be better to use your own object to store the data - then you can write, for example, salesRecord.quantity (or salesRecord.getQuantity() if you have written a getter) instead of salesrecord.at(2). This is a lot more readable and is better practice than remembering that 2 = quantity (etc.).
Now as to your actual question... I would say something like this:
Iterate over the list. For each item:
Check if the date of the item has already been added to your new list.
If the date does not already exist, simply add the item in its entireity.
If it does already exist, edit the existing item such that previousQuantity += quantityToAdd
On the sorted list
BARLEY:5.10:5:19OCT1923
STRAW:10:10:11NOV1991
CHOCOLATE:50:50:11NOV1991
this would work as follows:
Try to add barley data - nothing for that date so far, so add it:
19OCT1923 - 5 units
Try to add strawberry data - nothing for that date so far, so add it:
19OCT1923 - 5 units
11NOV1991 - 10 units
Try to add chocolate data - 11NOV1991 already exists, so add 50 to the 10 that's already there:
19OCT1923 - 5 units
11NOV1991 - 60 units