how do we iterate and store the results in a variable in kdb - kdb

I have a string say example "https://www.google.com" and a count of paging say 5
how do i iterate the URL to append p/page=incrementing numbers of paging and store the result in a variable as list?
"https://www.google.com/page=1"
"https://www.google.com/page=2"
"https://www.google.com/page=3"
"https://www.google.com/page=4"
"https://www.google.com/page=5"
So the end result will look like this having a variable query_var which will hold a list of string example below
query_var:("https://www.google.com/page=1";"https://www.google.com/page=2";"https://www.google.com/page=3";"https://www.google.com/page=4";"https://www.google.com/page=5");
count query_var \\5

You can use the join function , with the each-right adverb /:
query_var: "https://www.google.com/page=" ,/: string 1_til 6
Make it a function to support a varied count of pages:
f:{"https://www.google.com/page=" ,/: string 1_til x+1}
q)10=count f[10]
1b

Q1
You don’t even need a lambda to make this a function. It’s a sequence of unary functions, so you can compose them.
q)f: "https://www.google.com/page=",/: string ::
q)f 1+til 6
"https://www.google.com/page=1"
"https://www.google.com/page=2"
"https://www.google.com/page=3"
"https://www.google.com/page=4"
"https://www.google.com/page=5"
"https://www.google.com/page=6"
Q2
q)("https://www.google.com";;"info/history")
enlist["https://www.google.com";;"info/history"]
q)"/"sv'("https://www.google.com";;"info/history")#/: string `aapl`msft`nftx
"https://www.google.com/aapl/info/history"
"https://www.google.com/msft/info/history"
"https://www.google.com/nftx/info/history"
List notation is syntactic sugar for enlist. The list with a missing item is a projection of enlist and can be iterated.
Again, a sequence of unaries is all composable without a lambda:
q)g: "/"sv'("https://www.google.com";;"info/history")#/: string ::
q)g `aapl`msft`nftx
"https://www.google.com/aapl/info/history"
"https://www.google.com/msft/info/history"
"https://www.google.com/nftx/info/history"

If you can assume a unique character that doesn't appear elsewhere in your url (e.g. #) then ssr is a simple and easily-readable approach:
ssr["https://www.google.com/page=#";"#";]each string 1+til 5
ssr["https://www.google.com/#/info/history";"#";]each string`aapl`msft`nftx

Related

Regex expression in q to match specific integer range following string

Using q’s like function, how can we achieve the following match using a single regex string regstr?
q) ("foo7"; "foo8"; "foo9"; "foo10"; "foo11"; "foo12"; "foo13") like regstr
>>> 0111110b
That is, like regstr matches the foo-strings which end in the numbers 8,9,10,11,12.
Using regstr:"foo[8-12]" confuses the square brackets (how does it interpret this?) since 12 is not a single digit, while regstr:"foo[1[0-2]|[1-9]]" returns a type error, even without the foo-string complication.
As the other comments and answers mentioned, this can't be done using a single regex. Another alternative method is to construct the list of strings that you want to compare against:
q)str:("foo7";"foo8";"foo9";"foo10";"foo11";"foo12";"foo13")
q)match:{x in y,/:string z[0]+til 1+neg(-/)z}
q)match[str;"foo";8 12]
0111110b
If your eventual goal is to filter on the matching entries, you can replace in with inter:
q)match:{x inter y,/:string z[0]+til 1+neg(-/)z}
q)match[str;"foo";8 12]
"foo8"
"foo9"
"foo10"
"foo11"
"foo12"
A variation on Cillian’s method: test the prefix and numbers separately.
q)range:{x+til 1+y-x}.
q)s:"foo",/:string 82,range 7 13 / include "foo82" in tests
q)match:{min(x~/:;in[;string range y]')#'flip count[x]cut'z}
q)match["foo";8 12;] s
00111110b
Note how unary derived functions x~/: and in[;string range y]' are paired by #' to the split strings, then min used to AND the result:
q)flip 3 cut's
"foo" "foo" "foo" "foo" "foo" "foo" "foo" "foo"
"82" ,"7" ,"8" ,"9" "10" "11" "12" "13"
q)("foo"~/:;in[;string range 8 12]')#'flip 3 cut's
11111111b
00111110b
Compositions rock.
As the comments state, regex in kdb+ is extremely limited. If the number of trailing digits is known like in the example above then the following can be used to check multiple patterns
q)str:("foo7"; "foo8"; "foo9"; "foo10"; "foo11"; "foo12"; "foo13"; "foo3x"; "foo123")
q)any str like/:("foo[0-9]";"foo[0-9][0-9]")
111111100b
Checking for a range like 8-12 is not currently possible within kdb+ regex. One possible workaround is to write a function to implement this logic. The function range checks a list of strings start with a passed string and end with a number within the range specified.
range:{
/ checking for strings starting with string y
s:((c:count y)#'x)like y;
/ convert remainder of string to long, check if within range
d:("J"$c _'x)within z;
/ find strings satisfying both conditions
s&d
}
Example use:
q)range[str;"foo";8 12]
011111000b
q)str where range[str;"foo";8 12]
"foo8"
"foo9"
"foo10"
"foo11"
"foo12"
This could be made more efficient by checking the trailing digits only on the subset of strings starting with "foo".
For your example you can pad, fill with a char, and then simple regex works fine:
("."^5$("foo7";"foo8";"foo9";"foo10";"foo11";"foo12";"foo13")) like "foo[1|8-9][.|0-2]"

How to convert a number into a string in Maple?

I want to have something like this code from Python
num=3
res=str(num)
but in Maple. I couldn't find any appropriate constructors for this. Are there any?
num:=3:
convert(num,string);
"3"
sprintf("%a",num);
"3"
The best way is to use convert as already exists in #acer's answer. Just to name one more possibility here is another way.
num := 3:
res := cat( "", num );
You will get "3" for res of type string. What cat here does is concatenating 3 to the empty string "", and when there exists at least one string in the arguments of cat, the output becomes a string. You can even have something like sqrt(2) instead of 3 in num, in that case res becomes this string; "2^(1/2)". But sometimes it may give you a non-string object, for example if the number in num is of the form RootOf. See the help page to read more.

Underscore fill in KDB

Is there another way to fill _ to either left or right of the given string than the following?
q)a:"Apple"
q)"_"^rotate[5;a#til 12]
"_______Apple"
q)"_"^a#til 12
"Apple_______"`
The $ operator is overloaded to pad the string with null(space):
q)"_"^12$"Apple"
"Apple_______"
q)"_"^-12$"Apple"
"_______Apple"
You can append any string by using ","
q) (12#"-"),"Apple"
"____________Apple"
q) "Apple",12#"_"
"Apple____________"

q - string representation of list

I have a list
filter:((in;`name;`betsy`robert`tom);(>;`age;43));
and I would like to get the following list representation out of it
"((in;`name;`betsy`robert`tom);(>;`age;43))"
What I found so far is this:
flatten:{[alist]
$[(count alist)~count raze alist;:alist;:flatten raze alist];
};
";" sv string raze flatten[filter]
/ gives: "in;name;betsy;robert;tom;>;age;43"
which loses the nested lists in the filter list.
credits to: https://lifeisalist.wordpress.com/2009/07/10/p07-flatten-a-nested-list-structure/
Thanks!
I think the command you are looking for is .Q.s or .Q.s1 which return kdb code in plain text:
q).Q.s1 filter
"((in;`name;`betsy`robert`tom);(>;`age;43))"
It should be noted that the output of these functions is limited by \c.

Function to split string in matlab and return second number

I have a string and I need two characters to be returned.
I tried with strsplit but the delimiter must be a string and I don't have any delimiters in my string. Instead, I always want to get the second number in my string. The number is always 2 digits.
Example: 001a02.jpg I use the fileparts function to delete the extension of the image (jpg), so I get this string: 001a02
The expected return value is 02
Another example: 001A43a . Return values: 43
Another one: 002A12. Return values: 12
All the filenames are in a matrix 1002x1. Maybe I can use textscan but in the second example, it gives "43a" as a result.
(Just so this question doesn't remain unanswered, here's a possible approach: )
One way to go about this uses splitting with regular expressions (MATLAB's strsplit which you mentioned):
str = '001a02.jpg';
C = strsplit(str,'[a-zA-Z.]','DelimiterType','RegularExpression');
Results in:
C =
'001' '02' ''
In older versions of MATLAB, before strsplit was introduced, similar functionality was achieved using regexp(...,'split').
If you want to learn more about regular expressions (abbreviated as "regex" or "regexp"), there are many online resources (JGI..)
In your case, if you only need to take the 5th and 6th characters from the string you could use:
D = str(5:6);
... and if you want to convert those into numbers you could use:
E = str2double(str(5:6));
If your number is always at a certain position in the string, you can simply index this position.
In the examples you gave, the number is always the 5th and 6th characters in the string.
filename = '002A12';
num = str2num(filename(5:6));
Otherwise, if the formating is more complex, you may want to use a regular expression. There is a similar question matlab - extracting numbers from (odd) string. Modifying the code found there you can do the following
all_num = regexp(filename, '\d+', 'match'); %Find all numbers in the filename
num = str2num(all_num{2}) %Convert second number from str