In Julia, if we have a string set to a variable :
a = "hi"
and a function that has the same name as the value of the variable :
function hi()
return "hello"
end
can we like parse the variable and then run, or evaluate, the value in the string? If so , how could it be done using these example variable and function?
You can do this in at least two ways:
julia> eval(Symbol(a))()
"hello"
or
julia> eval(Meta.parse(a*"()"))
"hello"
In the first way we create a Symbol representing the function and a Julia Symbol can be evaluated immediately. Once the symbol is parsed to a Julia object we call immediately the function (that is why there is a trailing ()).
In the second example we parse the Julia code as a String and then evaluate it.
A must-read is the meta-programming manual that can be found here: https://docs.julialang.org/en/v1/manual/metaprogramming/
Related
I am trying to define a string in Julia like I would in Python by doing the following:
'hello world'
However, I am getting the following error:
ERROR: syntax: character literal contains multiple characters
Stacktrace:
[1] top-level scope
# none:1
Any suggestion to resolve this? I searched around for the error but nothing about Julia came up, only C# and other languages.
Your answer is not complete without noting that in Julia you have also """
help?> """
""" is used to delimit string literals. Strings created by triple quotation marks
can contain " characters without escaping and are dedented to the level of the
least-indented line. This is useful for defining strings within code
that is indented.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> """Hello World!"""
"Hello World!"
julia> """Contains "quote" characters"""
"Contains \"quote\" characters"
julia> """
Hello,
world."""
"Hello,\nworld."
In languages like Python, it is possible to define a string with a single quote like this:
'this is a valid python string'
However, in Julia, the single quote can only be used for an individual character. If you have more than one, you need to use double quotes:
"This is a valid Julia string"
#vs
'This is NOT a valid string'
I would like to see a code snippet of julia that will read a file and return lines (string type) that match a regular expression.
I welcome multiple techniques, but output should be equivalent to the following:
$> grep -E ^AB[AJ].*TO' 'webster-unabridged-dictionary-1913.txt'
ABACTOR
ABATOR
ABATTOIR
ABJURATORY
I'm using GNU grep 3.1 here, and the first line of each entry in the file is the all caps word on its own.
You could also use the filter function to do this in one line.
filter(line -> ismatch(r"^AB[AJ].*TO",line),readlines(open("webster-unabridged-dictionary-1913.txt")))
filter applies a function returning a Boolean to an array, and only returns those elements of the array which are true. The function in this case is an anonymous function line -> ismatch(r"^AB[AJ].*TO",line)", which basically says to call each element of the array being filtered (each line, in this case) line.
I think this might not be the best solution for very large files as the entire file needs to be loaded into memory before filtering, but for this example it seems to be just as fast as the for loop using eachline. Another difference is that this solution returns the results as an array rather than printing each of them, which depending on what you want to do with the matches might be a good or bad thing.
My favored solution uses a simple loop and is very easy to understand.
julia> open("webster-unabridged-dictionary-1913.txt") do f
for i in eachline(f)
if ismatch(r"^AB[AJ].*TO", i) println(i) end
end
end
ABACTOR
ABATOR
ABATTOIR
ABJURATORY
notes
Lines with tab separations have the tabs preserved (no literal output of '\t')
my source file in this example has the dictionary words in all caps alone on one line above the definition; the complete line is returned.
the file I/O operation is wrapped in a do block syntax structure, which expresses an anonymous function more conveniently than lamba x -> f(x) syntax for multi-line functions. This is particularly expressive with the file open() command, defined with a try-finally-close operation when called with a function as an argument.
Julia docs: Strings/Regular Expressions
regex objects take the form r"<regex_literal_here>"
the regex itself is a string
based on perl PCRE library
matches become regex match objects
example
julia> reg = r"^AB[AJ].*TO";
julia> typeof(reg)
Regex
julia> test = match(reg, "ABJURATORY")
RegexMatch("ABJURATO")
julia> typeof(test)
RegexMatch
Just putting ; in front is Julia's way to using commandline commands so this works in Julia's REPL
;grep -E ^AB[AJ].*TO' 'webster-unabridged-dictionary-1913.txt'
Using Julia, I'd like to reliably convert any type into type String. There seems to be two ways to do the conversion in v0.5, either the string function or String constructor. The problem is that you need to choose the right one depending upon the input type.
For example, typeof(string(1)) evaluates to String, but String(1) throws an error. On the other hand, typeof(string(SubString{String}("a"))) evaluates to Substring{String}, which is not a subtype of String. We instead need to do String(SubString{String}("a")).
So it seems the only reliable way to convert any input x to type String is via the construct:
String(string(x))
which feels a bit cumbersome.
Am I missing something here?
You should rarely need to explicitly convert to String. Note that even if your type definitions have String fields, or if your arrays have concrete element type String, you can still rely on implicit conversion.
For instance, here are examples of implicit conversion:
type TestType
field::String
end
obj = TestType(split("x y")[1]) # construct TestType with a SubString
obj.field # the String "x"
obj.field = SubString("Hello", 1, 3) # assign a SubString
obj.field # the String "Hel"
Trying to get into Julia after learning python, and I'm stumbling over some seemingly easy things. I'd like to have a function that takes strings as arguments, but uses one of those arguments as a regular expression to go searching for something. So:
function patterncount(string::ASCIIString, kmer::ASCIIString)
numpatterns = eachmatch(kmer, string, true)
count(numpatterns)
end
There are a couple of problems with this. First, eachmatch expects a Regex object as the first argument and I can't seem to figure out how to convert a string. In python I'd do r"{0}".format(kmer) - is there something similar?
Second, I clearly don't understand how the count function works (from the docs):
count(p, itr) → Integer
Count the number of elements in itr for which predicate p returns true.
But I can't seem to figure out what the predicate is for just counting how many things are in an iterator. I can make a simple counter loop, but I figure that has to be built in. I just can't find it (tried the docs, tried searching SO... no luck).
Edit: I also tried numpatterns = eachmatch(r"$kmer", string, true) - no go.
To convert a string to a regex, call the Regex function on the string.
Typically, to get the length of an iterator you an use the length function. However, in this case that won't really work. The eachmatch function returns an object of type Base.RegexMatchIterator, which doesn't have a length method. So, you can use count, as you thought. The first argument (the predicate) should be a one argument function that returns true or false depending on whether you would like to count a particular item in your iterator. In this case that function can simply be the anonymous function x->true, because for all x in the RegexMatchIterator, we want to count it.
So, given that info, I would write your function like this:
patterncount(s::ASCIIString, kmer::ASCIIString) =
count(x->true, eachmatch(Regex(kmer), s, true))
EDIT: I also changed the name of the first argument to be s instead of string, because string is a Julia function. Nothing terrible would have happened if we would have left that argument name the same in this example, but it is usually good practice not to give variable names the same as a built-in function name.
I am writing some code in R to handle errors/warnings.
The condition object i get back is a list of a message as string and a call object, representing the function call, that caused the error. I want to have a string that is the same as if i simply used print() on the call object. However using as.character() or paste() gives back a vector of multiple strings representing the function name and parameters.
Is there an easy way to do this or do i have to build the string myself?
Use deparse:
x <- call("sum",1:10)
as.character(x)
[1] "sum" "1:10"
deparse(x)
[1] "sum(1:10)"