String interpolation - string

In scala, you easily include the content of a variable inside a string, like this:
val nm = "Arrr"
println(s"my name is , $nm")
Is this possible in nim, and in that case, how?

The strfmt module features some experimental string interpolation:
import strfmt
let nm = "Arrr"
echo interp"my name is $nm"

Adding your own string interpolation is not particularly had, since the standard library already provides most of the necessary pieces:
import macros, parseutils, sequtils
macro i(text: string{lit}): expr =
var nodes: seq[PNimrodNode] = #[]
# Parse string literal into "stuff".
for k, v in text.strVal.interpolatedFragments:
if k == ikStr or k == ikDollar:
nodes.add(newLit(v))
else:
nodes.add(parseExpr("$(" & v & ")"))
# Fold individual nodes into a statement list.
result = newNimNode(nnkStmtList).add(
foldr(nodes, a.infix("&", b)))
const
multiplier = 3
message = i"$multiplier times 2.5 is ${multiplier * 2.5}"
echo message
# --> 3 times 2.5 is 7.5
proc blurb(a: int): string =
result = i"param a ($a) is not a constant"
when isMainModule:
for f in 1..10:
echo f.blurb

The strformat module is now considered the go-to way to do it:
import strformat
let nm = "Arrr"
echo fmt"my name is , {nm}"

Related

How to write multiline strings in SML?

How can I write a string that spans multiple lines?
I tried to use the line continuation character \ at the end like many other languages, but it does not seem to work. The following:
val s = "line1\
line2";
generates an error:
/tmp/...:1: error: unexpected character l in \ ... \
/tmp/...:1: error: no matching quote found on this line
Not using any line continuation as follows generates a similar error:
val s = "line1
line2";
What's the correct way to write a multiline string?
You have to put the backslash at the beginning of the next lines as well :
print "this is\
\ a string on\
\ 3 lines\n";
If you're using SML/NJ and you don't care much about portability, there's a lesser known feature that could give you not only multiline strings, but also variable interpolation. SML/NJ supports an extensible quotation mechanism, which is described in more detail here: https://www.smlnj.org/doc/quote.html
Now, to solve your problem, we could define the following quotation parser. I'm calling it s to draw a parallel with Scala's s"..." syntax, which will become clearer in a few moments.
val s : string SMLofNJ.frag list -> string =
let
fun fold (SMLofNJ.QUOTE s, acc) = acc ^ s
| fold (SMLofNJ.ANTIQUOTE s, acc) = acc ^ s
in
List.foldl fold ""
end
Notice that it makes use of the SMLofNJ structure to access compiler-specific datatypes and values (frag, QUOTE and ANTIQUOTE).
We can now use the above like this (make sure you're using the command line option -Cparser.quotations=true):
$ sml -Cparser.quotations=true
- val a = "var";
val a = "var" : string
-
- val b = `this is a raw quotation using ^a`;
val b = [QUOTE "this is a raw quotation using ",ANTIQUOTE "var",QUOTE ""] :
string SMLofNJ.frag list
-
- val c = s`this is an interpolated string: ^a`;
val c = "this is an interpolated string: var" : string
-
- print c;
this is an interpolated string: varval it = () : unit
-
- val d = s`this
… is
… a
… multiline string: ^a`;
val d = "this\nis\na\nmultiline string: var" : string
-
- print d;
this
is
a
multiline string: varval it = () : unit
As you can see, using quotations in conjunction with a very simple custom parser (the s function), we can get multiline interpolated strings in SML/NJ.
In my personal library, I've defined it in a bit more structured way:
structure Strings =
struct
structure Interpolated =
struct
local
open SMLofNJ
in
(**
* Support for multiline, interpolated strings.
*
* NB: requires SML/NJ quotations: sml -Cparser.quotations=true.
*
* ```sml
* - open Strings.Interpolated;
* - val v = "val";
* val v = "val" : string
* - val j = s`{
* = "key": "^v"
* = }`;
* val j = "{\n \"key\": \"val\"\n}" : string
* ```
*)
val s : string frag list -> string =
let
fun fold (QUOTE s, acc) = acc ^ s
| fold (ANTIQUOTE s, acc) = acc ^ s
in
List.foldl fold ""
end
end
end
end

LUA: Generating Unique Mac from given Number Value

I am trying to generate a unique MAC id from given a number value. The length on the number is between 1 to 5 digit. I have formatted the MAC table to place each digit starting from first value of MAC.
local MacFormat ={[1] = "0A:BC:DE:FA:BC:DE",[2] = "00:BC:DE:FA:BC:DE",[3] = "00:0C:DE:FA:BC:DE",[4] = "00:00:DE:FA:BC:DE",[5] = "00:00:0E:FA:BC:DE"}
local idNumbers = {[1] = "1",[2]="12",[3]="123",[4]="1234",[5]="12345"}
for w in string.gfind(idNumbers[3], "(%d)") do
print(w)
str = string.gsub(MacFormat[3],"0",tonumber(w))
end
print(str)
---output 33:3C:DE:FA:BC:DE
--- Desired Output 12:3C:DE:FA:BC:DE
I have tried multiple Patterns with *, +, ., but none is working.
for w in string.gfind(idNumbers[3], "(%d)") do
print(w)
str = string.gsub(MacFormat[3],"0",tonumber(w))
end
print(str)
Your loop body is equivalent to
str = string.gsub("00:0C:DE:FA:BC:DE", "0",1)
str = string.gsub("00:0C:DE:FA:BC:DE", "0", 2)
str = string.gsub("00:0C:DE:FA:BC:DE", "0", 3)
So str is "33:3C:DE:FA:BC:DE"
MacFormat[3] is never altered and the result of gsub is overwritten in each line.
You can build the pattern and replacement dynamically:
local MacFormat ={[1] = "0A:BC:DE:FA:BC:DE",[2] = "00:BC:DE:FA:BC:DE",[3] = "00:0C:DE:FA:BC:DE",[4] = "00:00:DE:FA:BC:DE",[5] = "00:00:0E:FA:BC:DE"}
local idNumbers = {[1] = "1",[2]="12",[3]="123",[4]="1234",[5]="12345"}
local p = "^" .. ("0"):rep(string.len(idNumbers[3])):gsub("(..)", "%1:")
local repl = idNumbers[3]:gsub("(..)", "%1:")
local str = MacFormat[3]:gsub(p, repl)
print(str)
-- => 12:3C:DE:FA:BC:DE
See the online Lua demo.
The pattern is "^" .. ("0"):rep(string.len(idNumbers[3])):gsub("(..)", "%1:"): ^ matches the start of string, then a string of zeros (of the same size a idNumbers, see ("0"):rep(string.len(idNumbers[3]))) follows with a : after each pair of zeros (:gsub("(..)", "%1:")).
The replacement is the idNumbers item with a colon inserted after every second char with idNumbers[3]:gsub("(..)", "%1:").
In this current case, the pattern will be ^00:0 and the replacement will be 12:3.
See the full demo here.

Python 3 unicode ZWJ error with String replace

I need to replace ANSII characters with UNICODE (Sinhala). I use lists with a loop to do that as follows,
for i in range (len(charansi)):
for j in range (len(charUni)):
s = charansi[i] + ansimod[j]
v = charUni[i] + modUni[j]
textSource = textSource.replace(s, v)
if we use n + uu as ANSII input, it should give නූ as Unicode out put. But instead of that, it gives න ූ
to clarify more,
charansi = n
ansimod = uu
charUni = න
modUni = ූ
this න and ූ must join without spaces. I think ZWJ (\u200D) plays a role here. so i tried
v = u"\u200D".join((consonantsUni[i], vowelModifiersUni[j]))
gives same result.
How do I fix this issue?
Your question is a bit confusing, but this simply works:
#coding:utf8
charansi = 'n'
ansimod = 'uu'
charUni = 'න'
modUni = 'ූ'
v = s.replace(charansi+ansimod,charUni+modUni)
print(v)
Output:
නූ
Create a working example of the problem if this isn't what you want.
You could also use the following to make the characters more clear. At least on my browser, the modifier didn't display very well.
charUni = '\N{SINHALA LETTER DANTAJA NAYANNA}'
modUni = '\N{SINHALA VOWEL SIGN DIGA PAA-PILLA}'

Optional capture of balanced brackets in Lua

Let's say I have lines of the form:
int[4] height
char c
char[50] userName
char[50+foo("bar")] userSchool
As you see, the bracketed expression is optional.
Can I parse these strings using Lua's string.match() ?
The following pattern works for lines that contain brackets:
line = "int[4] height"
print(line:match('^(%w+)(%b[])%s+(%w+)$'))
But is there a pattern that can handle also the optional brackets? The following does not work:
line = "char c"
print(line:match('^(%w+)(%b[]?)%s+(%w+)$'))
Can the pattern be written in another way to solve this?
Unlike regular expressions, ? in Lua pattern matches a single character.
You can use the or operator to do the job like this:
line:match('^(%w+)(%b[])%s+(%w+)$') or line:match('^(%w+)%s+(%w+)$')
A little problem with it is that Lua only keeps the first result in an expression. It depends on your needs, use an if statement or you can give the entire string the first capture like this
print(line:match('^((%w+)(%b[])%s+(%w+))$') or line:match('^((%w+)%s+(%w+))$'))
LPeg may be more appropriate for your case, especially if you plan to expand your grammar.
local re = require're'
local p = re.compile( [[
prog <- stmt* -> set
stmt <- S { type } S { name }
type <- name bexp ?
bexp <- '[' ([^][] / bexp)* ']'
name <- %w+
S <- %s*
]], {set = function(...)
local t, args = {}, {...}
for i=1, #args, 2 do t[args[i+1]] = args[i] end
return t
end})
local s = [[
int[4] height
char c
char[50] userName
char[50+foo("bar")] userSchool
]]
for k, v in pairs(p:match(s)) do print(k .. ' = ' .. v) end
--[[
c = char
userSchool = char[50+foo("bar")]
height = int[4]
userName = char[50]
--]]

MATLAB generate combination from a string

I've a string like this "FBECGHD" and i need to use MATLAB and generate all the required possible permutations? In there a specific MATLAB function that does this task or should I define a custom MATLAB function that perform this task?
Use the perms function. A string in matlab is a list of characters, so it will permute them:
A = 'FBECGHD';
perms(A)
You can also store the output (e.g. P = perms(A)), and, if A is an N-character string, P is a N!-by-N array, where each row corresponds to a permutation.
If you are interested in unique permutations, you can use:
unique(perms(A), 'rows')
to remove duplicates (otherwise something like 'ABB' would give 6 results, instead of the 3 that you might expect).
As Richante answered, P = perms(A) is very handy for this. You may also notice that P is of type char and it's not convenient to subset/select individual permutation. Below worked for me:
str = 'FBECGHD';
A = perms(str);
B = cellstr(reshape(A,7,[])');
C = unique(B);
It also appears that unique(A, 'rows') is not removing duplicate values:
>> A=[11, 11];
>> unique(A, 'rows')
ans =
11 11
However, unique(A) would:
>> unique(A)
ans =
11
I am not a matlab pro by any means and I didn't investigate this exhaustively but at least in some cases it appears that reshape is not what you want. Notice that below gives 999 and 191 as permutations of 199 which isn't true. The reshape function as written appears to operate "column-wise" on A:
>> str = '199';
A = perms(str);
B = cellstr(reshape(A,3,[])');
C = unique(B);
>> C
C =
'191'
'199'
'911'
'919'
'999'
Below does not produce 999 or 191:
B = {};
index = 1;
while true
try
substring = A(index,:);
B{index}=substring;
index = index + 1;
catch
break
end
end
C = unique(B)
C =
'199' '919' '991'

Resources