Julia. Strings and Metaprogramming

 3r33877. 3r3-31. 3r33854. Julia. Strings and Metaprogramming Lines
3r33855.  3r33877. 3r33854. String variables are created using a frame of characters in double quotes, single characters of the same type are defined as
char
. Concatenation of strings is performed using multiplication "*":
3r33855.  3r33877. 3r3822. cats = 4
s1 = "How many cats"; 3r33877. s2 = "is too many cats?"; 3r33877. s3 = s1 * s2
3r33877. Out[]: "How many cats are too many cats?" 3r33850. 3r33851. 3r33855.  3r33877. 3r33854. That is, the exponentiation works like this:
3r33855.  3r33877. 3r3822. s1 ^ 3
Out[]: "How many cats How many cats"
3r33851. 3r33855.  3r33877. 3r33854. On the other hand, indexing is extended to strings: 3r33865. 3r33855.  3r33877. 3r3822. s1[3]3r33877. Out[]: 'w': ASCII /Unicode U + 0077 (category Ll: Letter, lowercase) 3r37777. 3r33877. s1[5:13]3r33877. Out[]: "many cats"
3r33877. s1[13:-1:5]3r33877. Out[]: "stac ynam"
3r33877. s2[end]3r33877. Out[]: '?': ASCII /Unicode U + 003f (category Po: Punctuation, other)
3r33851. 3r33855.  3r33877. 3r33854. Strings can be created from strings and other types: 3r33865. 3r33855.  3r33877. 3r3822. s4 = string (s? "- I don't know, but", cats, "is too few.") 3r33877. # or so s4 = "$ s3 - I don't know, but $ cats is too few." 3r33877. 3r33877. Out[]: "How many cats are too many cats? - I don't know, but 4 is too few." 3r33850. 3r33851. 3r33855.  3r33877. 3r33854. In the arsenal there are many all sorts of useful features r3r3864. For example, the search element:
3r33855.  3r33877. 3r3822. findfirst (isequal ('o'), s4)
Out[]: 4 3r37777. 3r33877. findlast (isequal ('o'), s4)
Out[]: 26 3r3r777. 3r33877. findnext (isequal ('o'), s? 7) # look for a match after the seventh element
Out[]: 11 rr350. 3r33851. 3r33855.  3r33877. 3r33854. And this is how you can easily implement
Caesar cipher
3r33865. 3r33855.  3r33877. 3r3822. caesar (X, n) = prod ([x += n for x in X]) 3r37777. 3r33877. str3 = "hatifnatty are vicious lifestyle"; 3r33877. 3r33877. caesar (str? 3)
Out[]: "Shghlchrghhyu # eizkhh # tsusyryum # sudgk # ylkrl"
3r33877. str4 = caesar (str? -32)
Out[]: "KhATIFNATTY877. 3r3822. eval (Meta.parse (ans))
Out[]: 42 3r350. 3r33851. 3r33855.  3r33877. 3r33854. Why all these difficulties? The trick is that when we have
expression
, we can modify it in various interesting ways: 3r33838. 3r33855.  3r33877. 3r3822. x = replace (x, "*" => "+")
eval (Meta.parse (x)) 3r33877. Out[]: 13 3r350. 3r33851. 3r33855.  3r33877. 3r33854. To avoid messing around with strings, an operator of a gloomy face is provided for :() 3r33850. 3r33865. 3r33855.  3r33877. 3r3822. y =: (2 ^ 8-1)
Out[]::: (2 ^ 8-1)
3r33877. eval (y)
Out[]: 255 r3r3877. 3r33850. 3r33851. 3r33855.  3r33877. 3r33854. You can "quote" an expression, function, code block 3r33838. 3r33855.  3r33877. 3r3822. quote
x = 2 + 2
hypot (x, 5)
end
3r33877. Out[]: quote
# = In[13]: 2 = #
x = 2 + 2
# = In[13]: 3 = #
hypot (x, 5)
end
3r33877. : (function mysum (xs)
sum = 0
for x in xs
sum + = x
end
end)
3r33877. Out[]:: (function mysum (xs)
# = In[14]: 2 = #
sum = 0
# = In In[14]: 3 = #
for x = xs
# = In[14]: 4 = #
Sum + = x
End
End)
3r33851. 3r33855.  3r33877. 3r33854. And now let's parse the previously calculated matrix (it is better to start a new session after the previous section, my ugly overloads could easily conflict with the connected packages): 3r33865. 3r33855.  3r33877. 3r3822. X =["cos(ϕ)"
"sin(ϕ)"
0
0;
"cos(ϕ)*(-sin(ϕ))"
"cos(ϕ)*(cos(ϕ))"
"sin(ϕ)" 0;
"-sin(ϕ)*(-sin(ϕ))" "-sin(ϕ)*(cos(ϕ))"
"cos(ϕ)" 0;
"x0"
"y0"
"z0"
1; ]3r33877. 3r33877. for i = 1: size (X, 1), j = 1: size (X, 2)
if typeof (X[i,j]) == String
X[i,j]= Meta.parse (X[i,j])
end
end
X 3r3r777 3r33877. Out[]: 4 × 4 Array {Any, 2}:
: (cos (ϕ)): (sin (ϕ)) ???r3r3877. : (cos (ϕ) * - (sin (ϕ))): (cos (ϕ) * cos (ϕ)): (sin (ϕ)) 0
: (- (sin (ϕ)) * - (sin (ϕ))): (- (sin (ϕ)) * cos (ϕ)): (cos (ϕ)) 0
: x0: y0: z???r3r3850. 3r33851. 3r33855.  3r33877. 3r33854. As some have guessed, this is a transformation matrix, we are already 3r3-3534. This is taken apart , only now for three-dimensional coordinates. We will carry out the calculation for specific values: 3r33855.  3r33877. 3r3822. ϕ = 20 * pi /180
x0 = 4
y0 = -???r3r3877. z0 = ???r3r3877. 3r33877. Xtr =[eval(x) for x in X]3r33877. 3r33877. Out[]: 4 × 4 Array {Real, 2}:
???.???
-???.??? 0
???-???.???r3r3877. 4 -???.???r3r3850. 3r33851. 3r33855.  3r33877. 3r33854. This matrix produces a rotation around the axes. X 3r3-3560. and 3r33559. Z 3r3-3560. on 3r33714. 3r? 3562. 3r33737. and carry over to r3r3714. 3r33565. 3r33737. 3r33865. 3r33855.  3r33877. 3r3822. x =[-1 -1 1 1 -1 -1 1 1 -1 -1]; 3r33877. y =[-1 -1 -1 -1 -1 1 1 1 1 -1]; 3r33877. z =[1 -1 -1 1 1 1 1 -1 -1 -1]3r33877. R =[x' y' z' ones( length(x) ) ]3r33877. plot (x ', y', z ', w = 3) 3r33851. 3r33855.  3r33877. 3r33854. R2 = R * Xtr
plot! (R2[:,1], R2[:,2], R2[:,3], w = 3)
3r33851. 3r33855.  3r33877. 3r33854. 3r? 3593. 3r33865. 3r33855.  3r33877. 3r? 3597. Fruit of the Expression Tree 3r33855.  3r33877. 3r33854. As we’ve found out, strings support “interpolation”, which allows us to easily create large strings from smaller components. 3r33865. 3r33855.  3r33877. 3r3822. x = "million"
print ("$ x $ x $ x red roses ")
3r33877. Out[]: million million million scarlet roses
3r33851. 3r33855.  3r33877. 3r33854. With quotes (quotes) - the same story: 3r33865. 3r33855.  3r33877. 3r3822. x =: (6 * 7)
y =: ($ x + $ x)
Out[]:: (6 * 7 + 6 * 7)
3r33877. eval (y)
Out[]: 84 3r350. 3r33851. 3r33855.  3r33877.

The Root of All Eval

3r33855.  3r33877. 3r33854. 3r33737. eval () 3r33850. not only returns the value of the expression. Let's try to quote the function declaration: 3r33855.  3r33877. 3r3822. ex = :( cats () = println ("Meow!"))
cats () 3r37777. 3r33877. Out[]: UndefVarError: cats not defined
3r33851. 3r33855.  3r33877. 3r33854. And now we will revive her: 3r33855.  3r33877. 3r3822. eval (ex)
Out[]: cats (generic function with 1 method) 3r3r777. 3r33877. cats () 3r37777. Out[]: Meow! 3r33850. 3r33851. 3r33855.  3r33877. 3r33854. Using interpolation, we can construct the definition of a function on the fly; in fact, we can immediately do a number of functions. 3r33865. 3r33855.  3r33877. 3r3822. for name in[:dog, :bird, :mushroom]3r33877. println (: ($ name () = println ($ ("I'm $ (name)!")))
end
3r33877. Out[]: dog () = begin
# = In[27]: 2 = #
println ("i'm dog!")
end
bird () = begin
# = In[27]: 2 = #
println ("I'm a bird!")
end
mushroom () = begin
# = In[27]: 2 = #
println ("I'm mushroom!")
end
3r33877. for name in[:dog, :bird, :mushroom]3r33877. eval (: ($ name () = println ($ ("I'm $ (name)!")))
end
3r33877. dog () 3r33877. Out[]: I'm a dog! 3r33877. 3r33877. mushroom ()
Out[]: I'm mushroom! 3r33850. 3r33851. 3r33855.  3r33877. 3r33854. This can be extremely useful when wrapping an API (say, from the C library or via HTTP). APIs often define a list of available functions, so you can grab them and create an entire shell at once! See Examples Clang.jl, TensorFlow.jl or basic linear algebra. 3r33865. 3r33855.  3r33877. 3r33737. Original sin 3r3702. 3r33855.  3r33877. 3r33854. Here is a more practical example. Consider the following definition of the function sin () based on taylor series: 3r33865. 3r33855.  3r33877. 3r33854. 3r33865. 3r33854. 3r33714. 3r33737. 3r33737. 3r33865. 3r33855.  3r33877. 3r3822. mysin (x) = sum ((- 1) ^ k /factorial (1 + 2 * k) * x ^ (1 + 2k) for k = 0: 5)
mysin (0.5), sin (0.5)
3r33877. Out[]: (???? ???)
3r33877. using BenchmarkTools
@benchmark mysin (0.5)
3r33877. Out[]: BenchmarkTools.Trial:
memory estimate: 112 bytes
allocs estimate: 6
--------------
minimum time: ??? μs (???% GC)
median time: ??? μs (???% GC)
Mean time: ??? μs (???% GC)
maximum time: ??? μs (???% GC)
--------------
samples: 10000 r3r3877. evals /sample: 10 r3r3850. 3r33851. 3r33855.  3r33877. 3r33854. Now it is much slower than it could be. The reason is that we iterate over k, which is relatively expensive. Explicit recording is much faster: 3r33855.  3r33877. 3r3822. mysin (x) = x - x ^ 3/6 + x ^ 5/120 # + 3r350. 3r33851. 3r33855.  3r33877. 3r33854. But it's tedious to write and no longer looks like the original Taylor series. In addition, there is a high risk of ochepyakok. Is there a way to kill a hare with two shots? How about Julia writing us this code? To begin, consider the symbolic version of the + function. 3r33865. 3r33855.  3r33877. 3r3822. plus (a, b) =: ($ a + $ b)
plus (? 2)
3r33877. Out[]::: (1 + 2)
3r33851. 3r33855.  3r33877. 3r33854. From 3r33768. plus ()
we can do many interesting things, for example, the symbolic sum: 3r33855.  3r33877. 3r3822. reduce (+ 1:10)
Out[]: 55 3r37777. 3r33877. reduce (plus, 1:10)
Out[]:: ((((((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9) + 10) 3r33877. 3r33877. eval (ans)
Out[]: 55 3r37777. 3r33877. reduce (plus,[:(x^2), :x, 1])
Out[]:: ((x ^ 2 + x) + 1) 3r3-3850. 3r33851. 3r33855.  3r33877. 3r33854. This gives us an important piece of the puzzle, but we also need to figure out what we summarize. Let's create a symbolic version of the Taylor series above, which interpolates the value of k. 3r33865. 3r33855.  3r33877. 3r3822. k = 2 r3r3877. : ($ ((- 1) ^ k) * x ^ $ (1 + 2k) /$ (factorial (1 + 2k))) 3r3r777. Out[]:: ((1 * x ^ 5) /120) 3r3-3850. 3r33851. 3r33855.  3r33877. 3r33854. Now you can rivet the elements of a row like on a conveyor: 3r33865. 3r33855.  3r33877. 3r3822. terms =[:($((-1)^k) * x^$(1+2k) /$(factorial(1+2k))) for k = 0:5]3r33877. Out[]: 6-element Array {Expr, 1}:
: ((1 * x ^ 1) /1) 3r33877. : ((- 1 * x ^ 3) /6) 3r33877. : ((1 * x ^ 5) /120) 3r33877. : ((- 1 * x ^ 7) /5040)
: ((1 * x ^ 9) /362880)
: ((- 1 * x ^ 11) /39916800) r3r3850. 3r33851. 3r33855.  3r33877. 3r33854. And to summarize them: 3r33855.  3r33877. 3r3822. reduce (plus, ans)
Out[]:: (((((((1 * x ^ 1) /1 + (-1 * x ^ 3) /6) + (1 * x ^ 5) /120) + (-1 * x ^ 7) /5040 ) + (1 * x ^ 9) /362880) + (-1 * x ^ 11) /39916800) 3r37777. 3r33877. : (mysin (x) = $ ans)
3r33877. Out[]:: ((mysin (x) = begin
# = In[52]: 1 = #
(((((1 * x ^ 1) /1 + (-1 * x ^ 3) /6) + (1 * x ^ 5) /120) + (-1 * x ^ 7) /5040) + (1 * x ^ 9) /362880) + (-1 * x ^ 11) /39916800
end)
3r33877. eval (ans)
mysin (0.5), sin (0.5)
Out[]: (???? ???)
3r33877. @benchmark mysin (0.5)
3r33877. Out[]: BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: ??? ns (???% GC)
median time: ??? ns (???% GC)
Mean time: ??? ns (???% GC)
maximum time: ??? μs (???% GC)
--------------
samples: 10000 r3r3877. evals /sample: 201
3r33851. 3r33855.  3r33877. 3r33854. Not bad for a naive implementation! The photon will not have time to run one and a half hundred meters, and the sine is calculated! 3r33855.  3r33877. This is the time to finish. For those who want to continue exploring this topic I will recommend interactive tutorial executable in Jupyter , the translation of which was mostly used here, 3r33859. video course
from the official website, and 3r33861. The corresponding section is 3r36464. documentation. For only arrivals, I advise you to go for 3r33863. Hub 3r33864. , the benefit here is already an acceptable amount of materials. 3r33865. 3r33873. 3r33877. 3r33877. 3r33877. 3r33838. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o -;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33871. 3r33877. 3r33873. 3r33877. 3r33877. 3r33877. 3r33877.
+ 0 -

Add comment