In the following Julia 1.5 code:
a, b = 4, 5
"a=$(a), b=($b)" # "a=4, b=5"
using Markdown
md"a=$(a), b=($b)" # a=a, b=b
# but...
Markdown.parse("a=$(a), b=($b)") # "a=4, b=5"
It seems that the Markdown macro thinks two $ indicate a math expression. But the parse handles it OK.
Can someone explain this? is there a way to use the md"..." form for this.
It's not obvious in my opinion, but I think $ with a non-space before is interpreted as a closing LaTeX $ if there is one before.
Some suggestions:
If you're OK with spaces around your = sign, then this works:
julia> md"a = $a, b = $b"
a = 4, b = 5
Or you could make it a list:
julia> md"""
- a=$a
- b=$b
"""
• a=4
• b=5
Related
In my equations we have many expressions with a^2, and so on. I would like to map "²" to ^2, to obtain something like that:
julia> a² == a^2
true
The above is not however a legal code in Julia. Any idea on how could I implement it ?
Here is a sample macro #hoo that does what you requested in a simplified scenario (since the code is long I will start with usage).
julia> x=5
5
julia> #hoo 3x² + 4x³
575
julia> #macroexpand #hoo 2x³+3x²
:(2 * Main.x ^ 3 + 3 * Main.x ^ 2)
Now, let us see the macro code:
const charsdict=Dict(Symbol.(split("¹²³⁴⁵⁶⁷⁸⁹","")) .=> 1:9)
const charsre = Regex("[$(join(String.(keys(charsdict))))]")
function proc_expr(e::Expr)
for i=1:length(e.args)
el = e.args[i]
typeof(el) == Expr && proc_expr(el)
if typeof(el) == Symbol
mm = match(charsre, String(el))
if mm != nothing
a1 = Symbol(String(el)[1:(mm.offset-1)])
a2 = charsdict[Symbol(mm.match)]
e.args[i] = :($a1^$a2)
end
end
end
end
macro hoo(expr)
typeof(expr) != Expr && return expr
proc_expr(expr)
expr
end
Of course it would be quite easy to expand this concept into "pure-math" library for Julia.
I don't think that there is any reasonable way of doing this.
When parsing your input, Julia makes no real difference between the unicode character ² and any other characters you might use in a variable name. Attempting to make this into an operator would be similar to trying to make the suffix square into an operator
julia> asquare == a^2
The a and the ² are not parsed as two separate things, just like the a and the square in asquare would not be.
a^2, on the other hand, is parsed as three separate things. This is because ^ is not a valid character for a variable name and it is therefore parsed as an operator instead.
This is the source code I got from https://inventwithpython.com/hacking
import math, pyperclip
def main():
myMessage = 'Cenoonommstmme oo snnio. s s c'
myKey = 8
plaintext = decryptMessage(myKey, myMessage)
print(plaintext + '|')
pyperclip.copy(plaintext)
def decryptMessage(key, message):
numOfColumns = math.ceil(len(message) / key)
numOfRows = key
numOfShadedBoxes = (numOfColumns * numOfRows) - len(message)
plaintext = [''] * int(numOfColumns)
col = 0
row = 0
for symbol in message:
plaintext[col] += symbol
col += 1
if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
col = 0
row += 1
return ''.join(plaintext)
if __name__ == '__main__':
main()
What this Should be returning is
Common sence is not so common.|
What im getting back is
Coosmosi seomteonos nnmm n. c|
I cant figure out where the code is failing to send back the phrase
The code is OK. The problem is that you're using the wrong version of Python. As the 'Installation' chapter of that website says:
Important Note! Be sure to install Python 3, and not Python 2. The
programs in this book use Python 3, and you’ll get errors if you try
to run them with Python 2. It is so important, I am adding a cartoon
penguin telling you to install Python 3 so that you do not miss this
message:
You are using Python 2 to run the program.
The result is incorrect because the program depends on a feature that behaves differently in Python 2 than in Python 3. Specifically, dividing two integers in Python 3 produces a floating-point result but in Python 2 it produces a rounded-down integer result. So this expression:
(len(message) / key)
produces 3.75 in Python 3 but produces 3 in Python 2, and therefore this expression:
math.ceil(len(message) / key)
produces 4 (3.75 rounded up is 4) in Python 3 but produces 3 (3 rounded up is 3) in Python 2. This means that your numOfColumns is incorrect and therefore the decryption procedure produces an incorrect result.
You can fix this specific issue by changing (len(message) / key) to (float(len(message)) / key) to force Python 2 to treat that calculation as a floating-point division that will give the desired 3.75 result. But the real solution is to switch to using Python 3, because these differences in behaviour between Python 3 and Python 2 are just going to keep causing trouble as you proceed through the rest of the book.
I have a Julia function in a file. Let's say it is the below. Now I want to pass arguments into this function. I tried doing
julia filename.jl randmatstat(5)
but this gives an error that '(' token is unexpected. Not sure what the solution would be. I am also a little torn on if there is a main function / how to write a full solution using Julia. For example what is the starting / entry point of a Julia Program?
function randmatstat(t)
n = 5
v = zeros(t)
w = zeros(t)
for i = 1:t
a = randn(n,n)
b = randn(n,n)
c = randn(n,n)
d = randn(n,n)
P = [a b c d]
Q = [a b; c d]
v[i] = trace((P.'*P)^4)
w[i] = trace((Q.'*Q)^4)
end
std(v)/mean(v), std(w)/mean(w)
end
Julia doesn't have an "entry point" as such.
When you call julia myscript.jl from the terminal, you're essentially asking julia to execute the script and exit. As such, it needs to be a script. If all you have in your script is a function definition, then it won't do much unless you later call that function from your script.
As for arguments, if you call julia myscript.jl 1 2 3 4, all the remaining arguments (i.e. in this case, 1, 2, 3 and 4) become an array of strings with the special name ARGS. You can use this special variable to access the input arguments.
e.g. if you have a julia script which simply says:
# in julia mytest.jl
show(ARGS)
Then calling this from the linux terminal will give this result:
<bashprompt> $ julia mytest.jl 1 two "three and four"
UTF8String["1","two","three and four"]
EDIT: So, from what I understand from your program, you probably want to do something like this (note: in julia, the function needs to be defined before it's called).
# in file myscript.jl
function randmatstat(t)
n = 5
v = zeros(t)
w = zeros(t)
for i = 1:t
a = randn(n,n)
b = randn(n,n)
c = randn(n,n)
d = randn(n,n)
P = [a b c d]
Q = [a b; c d]
v[i] = trace((P.'*P)^4)
w[i] = trace((Q.'*Q)^4)
end
std(v)/mean(v), std(w)/mean(w)
end
t = parse(Int64, ARGS[1])
(a,b) = randmatstat(t)
print("a is $a, and b is $b\n")
And then call this from your linux terminal like so:
julia myscript.jl 5
You can try running like so:
julia -L filename.jl -E 'randmatstat(5)'
Add the following to your Julia file:
### original file
function randmatstat...
...
end
### new stuff
if length(ARGS)>0
ret = eval(parse(join(ARGS," ")))
end
println(ret)
Now, you can run:
julia filename.jl "randmatstat(5)"
As attempted originally. Note the additional quotes added to make sure the parenthesis don't mess up the command.
Explanation: The ARGS variable is defined by Julia to hold the parameters to the command running the file. Since Julia is an interpreter, we can join these parameters to a string, parse it as Julia code, run it and print the result (the code corresponds to this description).
I have a list of products:
1, 2, 3, 4...
Which depends on a different list of sources:
z, y, x, w...
The dependence is one-to-one (the nth element of the first list has the nth element of the second list as its source), and the recipe is the same in all cases. There is, for all intents and purposes, no structure to the lists - it's not possible to write a simple expression which allows the nth element of the list to be generated from n. The solution that I know will work is
1 : z
[recipe]
2 : y
[identical recipe]
3 : x
[identical recipe]
4 : w
[identical recipe]
...but I don't like this because it makes it easier to make a mistake when modifying the lists or the recipe. I would prefer to take advantage of the correspondence pattern and begin with
SRCLIST = z y x w
DSTLIST = 1 2 3 4
And then somehow have a general rule like
DSTLIST_n : SRCLIST_n
[recipe]
Is there any way of doing something like this?
This is a bit ugly but I believe it should work. (There are probably slightly better ways but this was the first thing I came up with.)
SRCLIST = z y x w
DSTLIST = 1 2 3 4
# Create a list of : the length of SRCLIST
MIDLIST = $(foreach s,$(SRCLIST),:)
$(info SRCLIST:$(SRCLIST))
$(info DSTLIST:$(DSTLIST))
$(info MIDLIST:$(MIDLIST))
# Join the three lists together (in two passes since $(join) only takes two lists)
JOINLIST = $(join $(join $(DSTLIST),$(MIDLIST)),$(SRCLIST))
$(info joined:$(JOINLIST))
# eval each of the created strings to create the prerequisite entries
$(foreach r,$(JOINLIST),$(eval $r))
# Set the rules to build all the targets.
$(DSTLIST):
echo '$# for $^'
$ touch z y x w
$ make
SRCLIST:z y x w
DSTLIST:1 2 3 4
MIDLIST:: : : :
joined:1:z 2:y 3:x 4:w
echo '1 for z'
1 for z
echo '2 for y'
2 for y
echo '3 for x'
3 for x
echo '4 for w'
4 for w
I should note that this will not deal with spaces in any of the entries at all well (but that's generally true of make so nothing specific to this solution).
You could also always just create a Canned Recipe and then just stick that in each explicitly written out target as in your original idea.
Inspired by Etan, here is what I found worked:
SRCLIST = z y x w
DSTLIST = 1 2 3 4
# Make a list of ":" for combining
SEPARATOR = $(foreach s,$(SRCLIST),:)
# Define a parameterized rule which accepts the dst:src info as an argument
define dst-src
$1
[rule]
endef
# Define the list of dependencies
DST_SRC_RELNS = $(join $(join $(DSTCLIST),$(SEPARATOR)),$(SRCLIST))
# ^ DST_SRC_RELNS evaluates to z:1 y:2 x:3 w:4
# Print a preview of the rules the makefile generates itself
$(info $(foreach r,$(DST_SRC_RELNS),$(call dst-src,$r)))
# Generate the rules
$(foreach r,$(DST_SRC_RELNS),$(eval $(call dst-src,$r)))
I think that you could get away with not defining the parameterized rule dst-src by actually writing the rule out inside the $(eval ...), but I didn't like this for two reasons:
you need to define a newline macro for the result to be something that make will recognize as a rule
adding more text within the $(foreach ...) makes it even harder for a human reader to figure out what's really going on
Nice problem. You didn't mention which version of make you are using, but .SECONDEXPANSION often works well for these sorts of source lookup tables.
A sketch:
srcs := z x y w
targets := 1 2 3 4
.SECONDEXPANSION:
pairs := $(join ${targets},$(addprefix :,${srcs}))
lookup-src = $(patsubst $1:%,%,$(filter $1:%,${pairs}))
${targets}: $$(call lookup-src,$$#)
echo '[$^] -> [$#]'
I am using z3's python API to solve see if a set of constraint is satisfiable or not.
I have the conditions as string and I want to directly pass them to z3 whenever possible, just to save processing time of transcoding it.
If the constraint is an assignment like a = b what is the best way to enter it.
I want something like
str1 = "a = b"
a = BitVec('a', 3)
b = BitVec('b', 3)
s = Solver()
s.push()
s.add(str1)
This program gives error as "True, False or Z3 Boolean expression expected"
Please let me know the best way to do it.
You need to pass Z3 expressions to the majority of the API functions (like Solver.add(expr)), not strings. For your example (z3py link: http://rise4fun.com/Z3Py/iu0 ):
str1 = "a = b"
a = BitVec('a', 3)
b = BitVec('b', 3)
constraint1 = a == b # sets constraint1 to be the z3 expression a == b
s = Solver()
s.push()
# s.add(str1) # error: 'True, False or Z3 Boolean expression expected'
s.add(constraint1)
print constraint1
If you want to pass strings encoded in infix notation (like "a = b"), you should be able to use Python's eval, although this may not work with full generality, so you may have to write a parser, and you cannot use eval on rise4fun due to the sanitizer:
constraint2 = eval(str1)
Here's some more details on using eval: z3python: converting string to expression
If you have strings encoded in the SMT-LIB standard (which uses prefix notation, e.g., "(= a b)"), you can use the parse_smt2_string API function. Here's an example continuing from the above:
cstr1 = "(assert (= a b))"
ds = { 'a' : a, 'b' : b }
constraint3 = parse_smt2_string(cstr1, decls=ds)
print constraint3
prove(constraint1 == constraint3)
Here's the API documentation for parse_smt2_string: http://research.microsoft.com/en-us/um/redmond/projects/z3/z3.html#-parse_smt2_string
See also this related question and answer on using infix for output of Z3 expressions: how to convert z3 expression to infix expression?