Propper working with arrays and variables - autoit

Good morning all together!
I'm quite new to this language and I got a question about arrays. Normally I'm working with Python, so for me it is really something new, especially with arrays many things I could easily do before are not working anymore.
My problem is:
I'm spliting a string and I will get 4 new strings back. Now I could do a Dim[4] and everything would be fine, but the thing is I only need the last two values.
Normally I would make sure that only the last two values of the array are returning from the function and then just put them into my two variables, all in one line. But here in AutoIt I can't figure out a simple way.
Big thanks for all help you can give me about arrays, apparently they are the new villain in my life

That's easy with StringSplit. It even creates the array with the correct dimension for you:
#include <array.au3>
$sString = "alpha,beta,gamma,delta"
$aString = StringSplit($sString, ",")
_ArrayDisplay($aString, "StringSplit")
ConsoleWrite("From StringSplit, third: " & $aString[3] & #CRLF)
ConsoleWrite("From StringSplit, fourth: " & $aString[4] & #CRLF)
; extract the last two elements:
$aString = _ArrayExtract($aString, UBound($aString) - 2)
_ArrayDisplay($aString, "Extracted")
ConsoleWrite("From Extracted, first: " & $aString[0] & #CRLF)
ConsoleWrite("From Extracted, second: " & $aString[1] & #CRLF)

Related

Need help in identifying what this piece of code does EXACTLY (I have a general idea)

let $removeLastCR:=fn:replace($output.output_FileContent , '(\r?\n|\r)$', '')
let $lines := tokenize($removeLastCR, '\n')
return
for $line at $counter in $lines
let $x :=
for $i in fn:tokenize($line,'"')
return
if(fn:starts-with($i,',') and fn:ends-with($i,','))
then fn:substring($i,2,fn:string-length($i)-2)
else
if(fn:starts-with($i,','))
then fn:substring-after($i,',')
else
if(fn:ends-with($i,','))
then fn:substring($i,1,fn:string-length($i)-1)
else $i
let $fields :=
for $j at $k in $x
return
if(fn:starts-with($line,'"'))
then
if($k mod 2 = 0)
then fn:tokenize($j,',')
else $j
else
if($k mod 2 = 0)
then $j
else fn:tokenize($j,',')
return
The real issue is that I am trying to understand why the parsing fails for the below data record, but works for the rest of the data in the file (File is a .CSV file):
xyz#example.com,XYZ LastName,Merchant,15/08/2022,199.98,USD,199.98,USD,61001,,,xyz#example.com | R1111111,"Qty 10- 4"" X 4"" X 5.7"" - Color: Custom Box 1",,XYZ,CC 1 August,R1111111,P&E \: PS mama,,policyid,CCP,https://www.example.com/report?reportID=R1111111,cdf,1234XXXXXX5678,https://example.com,
For the above record, the code should have parsed each comma separated value into it's own field,(Field1: xyz#example.com, Field2: XYZ LastName etc) but I think it falls apart on the field value "Qty 10- 4"" X 4"" X 5.7"" - Color: Custom Box 1". It SHOULD parse this whole value into 1 field, but it only gets "Qty 10- 4" into Field#13. And all the fields after this are also all not parsed properly.
So I was trying to better understand this code (someone else wrote it) so i can make the appropriate changes to handle this scenario.
There are many variants of CSV syntax, and it looks as if this data file is using a convention of escaping " within a quoted field by doubling the quotation marks. But the query code that parses the CSV is making no attempt to handle such escaped quotation marks.
It's easy to tell you what each line of code does, but I suspect that's not your problem. What's harder is to understand the overall logic.
The first part creates a variable $x by tokenizing on " and removing leading and trailing commas from every token. That makes no sense to me. The second part then takes the tokens that weren't in quotes and splits them on "," separators.
I think this code is already fairly broken, and it certainly can't be extended to handle quotes that are escaped by doubling. It needs to be rewritten. I don't think it can be done with simple tokenisation.
A bit of googling shows a variety of attempts at CSV to XML converters. Unfortunately few of them are very explicit about exactly what flavour of CSV they handle, and many don't even attempt to handle commas within quoted fields. Not very satisfactory, but I'm afraid that writing a better one isn't possible within the 10 minutes I allow myself for answering StackOverflow questions.

Marklogic collate sequence in XQuery

Is there a way to modify the elements a sequence so only collated versions of the items are returned?
let $currencies := ('dollar', 'Dollar', 'dollar ')
return fn:collated-only($currencies, "http://marklogic.com/collation/en/S1/T00BB/AS")
=> ('dollar', 'dollar', 'dollar')
The values that are stored in the range index (that feeds the facets) are literally the first value that was encountered that compared equal to the others. (Because, the collation says you don't care...)
You can get a long way by calling
fn:replace(fn:lower-case(xdmp:diacritic-less(fn:normalize-unicode($str,"NFKC"))),"\p{P}","")
This won't be exactly the same in that it overfolds some things and underfolds others, but it may be good for your purposes.
Is this the expected output? There is no fn:collated-only function, so I'm assuming you're asking how to write such a function or whether there is such a function.
The thing is, there isn't a mapping from one string to another in collation comparisons, there is only a comparison algorithm (the Unicode Collation Algorithm) so there really is no canonical kind of string to return to you, and therefore no API to do so.
Stepping back, what is the problem you are actually trying to solve? By the rules of that collation, "dollar" and "Dollar" are equivalent, and by using it you declare you don't care which form you use, so you could use either one.
If these values are in XML elements and you have a range index using http://marklogic.com/collation/en/S1/T00BB/AS, you can do something like this:
let $ref := cts:element-reference(xs:QName("currency"), "collation=http://marklogic.com/collation/en/S1/T00BB/AS")
for $curr in cts:values($ref, (), "frequency-order")
return $curr || ": " || cts:frequency($curr)
This will produce results like:
"dollar: 15",
"euro: 12"
... and so on. The collation will disregard the differences among your sample inputs. These results could be formatted however you want. Is that what you're looking to do?

R: "Which" function gives unexpected (and unwanted) results when using a comparison (>=)

I do not understand why the "which" function is not giving the right result here. I just want to select airports in Pennsylvania with more than 5,000 commercial service operations, and the result always contains a number of commercial service operations inferior to 5,000, as seen below.
I have read several questions indicating issues with "which", but I have seen none of that sort, and I have not had this issue before using this function.
Test4<-Airports[which(Airports$LAN_FA_TY=="AIRPORT" &
Airports$STATE_NAME=="PENNSYLVANIA" &
Airports$COMM_SERV>= "5000")
, ]
Test4$COMM_SERV
# [1] 77680 73 71
In this code snippet Airports$COMM_SERV>= "5000" you're using " " around a numeric value (the 5000) which turns the number into a character and hence you can no longer use mathematical operations like >= with that character. Just remove the "" and it should work as expected. (The use of comparison operators for character objects is allowed and meaningful. See ?'>='. It's just that the results may not be what were expected.)
Looking at your code, you could also profit from using with() to reduce the typing and improve readability:
with(Airports, Airports[which(LAN_FA_TY == "AIRPORT" & STATE_NAME == "PENNSYLVANIA" & COMM_SERV >= 5000),])

Request.Querystring(variablevalue) possible?

I'm creating an application which uses request.querystring to transfer variables between pages. However at the moment I am setting variable names in the URL dynamically in accordance with an array and I want to retrieve these values on another page using (essentially) the same array. So I came up with what I thought would be the simple solution:
For Each x In AnswerIDs
response.write(x)
ctest = Request.Querystring(x)
response.write(ctest)
Next
However this doesn't seem to work as it looks like you can't use Request.Querystring() with a variable as it's parameter. Has anyone got any idea how I could do this?
This is the query string:
QuizMark.asp?11=1&12=1
In this case AnswerIDs consists of "11" & "12" so in my loop I want it to write "1" & "1".
You can loop through the querystring like this:
For Each Item in Request.QueryString
Response.Write Item & ": " & Request.QueryString(Item) & "<br/>"
Next
Item contains the name of the querystring parameter, with Request.Querystring(Item) you retrieve the value of the parameter.
Your method will work with a simple modification:
For Each x In AnswerIDs
response.write(x)
ctest = Request.Querystring(CStr(x))
response.write(ctest)
Next
If your array might have Null elements, then replace the Cstr(x) with x & "".
If, on the other hand, you can make sure that every element of AnswerIDs has a value (i.e. is neither Empty nor Null), then you can omit the string conversion. In other words, the problem isn't with calling Request.Querystring with a variable, but with calling Request.Querystring with an Empty or a Null.

Why the asp code fail?

HeaderStr = HeaderStr & "<link href="""&HB_ManageFolder&"/Include/ASBox/ASBox.css"" rel=""stylesheet"" type=""text/css"">"&vbcrlf
But if I change &HB_ManageFolder& to & HB_ManageFolder & it will work.
Why?
&H starts a hexadecimal number
I don't really know VBScript (which you are probably using with ASP) but as far as I know, it's quite similar to VBA.
And I know this issue from VBA: if you build strings with "&" and you don't leave blanks in between, VBA won't compile until you put the blanks in.
Probably it's the same issue here.
So, you just always have to use " & " instead of "&" and it will work.

Resources