Julia not operator - julia

I am wondering if there is a way to use somesort of not operator with function such ismissing() or isempty()
For example, if I want to do something like this, How would I go about it.
x = Array[]
y = missing
if x not isempty(x)
# do something
elif not ismissing(y)
# do something
end
This is of course incorrect, and an empty array can be solved with if length(x) >0. But I am wondering if there is a way to do using with not-operator like in python. For example, In python numpy library I can do something like this to achieve this,
y = np.nan
if y is not np.nan:
#do something

This is the !(x) function, e.g. !ismissing(x).

Related

Julia Array to a String (or more complex counter)

I’m trying to count things in a Julia list with the goal of plotting a histogram. These things may be other arrays to simpler objects like Strings or Integers. My function is currently using the counter library, which works great for non-complex objects like strings or integers.
function viz(data::Vector)
counts = counter(data)
k = [x for x in keys(counts)]
v = [x for x in values(counts)]
bar(k, v./sum(v))
end
In Python, I’d just do str(x) for x in the_list To convert the inner element to strings, but I’m having trouble figuring out how to do this in Julia.
Or is there a better way to count complex objects in Julia? (I’m a beginner at Julia)
[string(x) for x in the_list]
# or
[String(x) for x in the_list]
one of them probably gives what you want
Take a look at StatsBase.countmap(x), if it does what you need.

Inclusivity of Julia ranges

I hate that ranges include the end. Here is an example where I've deliberately removed the end of the range.
N = 100
for x in 0.0 : 2*pi/N : 2*pi*(N-1)/N
println(x)
end
Is there any way to avoid the ugliness of this for loop?
Yes, there is
N = 100
for x in range(0; step=2π/N, length=N)
println(x)
end
Maybe not the most elegant way... take the first n-1 elements
r = 0.0 : 2*pi/N : 2*pi
r = Iterators.take(r,length(r)-1)
Unfortunately, inclusive ranges (and 1-based indexing) is baked into the idioms of Julia at a fundamental level.
However, for this specific case, do note that stepping with floating point values can be problematic, as adding N values might be less than, equal to, or greater than the final value, giving different results for the for loop. Although julia tries really hard, there's no way to quite do the right thing in all circumstances. As a bonus, working in integer values only for the ranges simplifies things. You might want to consider:
for ix in 0:N-1
x = ix * 2 * pi / N
println(x)
end
Alternatively, the range() function has a form with a len parameter:
for x in range(0, 2*pi*(N-1)/N, length=n)
println(x)
end
Or indeed, combining this with the other answer of only taking (N-1) could work.
You could actually define your own operator such as:
▷(a,b) = a:b-1
Now you can write:
julia> 3▷6
3:5
Julia also natively supports custom indices for arrays. There is a package CustomUnitRanges that is maybe an overkill here.

Store values generated by a for-loop. JuMP/Julia

It's amazing that the internet is totally void of this simple question (or similar). Or I'm just very bad at searching. Anyway, I simply want to store values generated by a for-loop in an array and print the array. Simple as that.
On every other language Matlab, R, Python, Java etc this is very simple. But in Julia I seem to be missing something.
using JuMP
# t = int64[] has also been tested
t = 0
for i in 1:5
vector[i]
println[vector]
end
I get the error
ERROR: LoadError: BoundsError
What am I missing?
You didn't initialize vector and you should call the method println like this following way, in Julia 1.0 :
vector = Array{Int,1}(undef, 5)
for i in 1:5
vector[i] = i
println(vector[i])
end
Or, more quickly, with a comprehension list :
vector = [i for i in 1:5]
for i in 1:5
println(vector[i])
end
Another possibility using push! method :
vector = []
for i in 1:5
push!(vector, i)
println(vector[i])
end

Accessing values in expression using a macro

I'm wondering whether it's possible to define a macro that can modify the values of an expression only if the values are of a specific type?
Here's a minimal example:
type Special
x::Int
end
f1(s, n::Special) = println("f1", s, n)
f2(s, n::Special) = println("f2", s, n)
x1 = Special(3)
x2 = Special(5)
expr = :(
f1("this is f1", x1),
f2("this is f2", x2)
)
Now a macro might be able to examine the values of the arguments to the functions, determine that x1 and x2 are of type Special, run some function to modify their values, say by changing 3 to 4 and 5 to 2 (it might involve comparing two values), then pass the expression back to the caller. The final result would be equivalent to calling:
f1("this is f1", 4)
f2("this is f2", 2)
I found that it's possible to access the values in a macro via:
eval(eval(filter(x -> typeof(eval(x)) == Special, expr.args[1].args))[1]).x
=> 3
but although this works it looks wrong, and I'm might either be doing it wrong or trying to do something too way out...
No, you should never try to check types or values inside macros. Using eval to figure out the type or value of something in a macro may work in very limited situations, but it'll break in almost every real use. Instead, just have the macro insert a call to a generic function — that's where Julia excels at picking apart types (as method dispatch) and values (within the method):
munge_special(x::Special) = Special(x.x + 42)
munge_special(x) = x
macro do_something_special(x)
return :(munge_special($(esc(x))))
end
julia> #do_something_special Special(2)
Special(44)
julia> #do_something_special 3
3

How can I interpret user input as a function in Julia?

I've been using the following function to take in user input for something I'm writing in Julia:
function input(prompt::AbstractString = "")
println(prompt * " ")
chomp(readline())
end
In my particular case, the input that I'm taking in is in the form of equations such as "y = x^2". After the input() function passes it to me as an ASCIIString, I then use the parse() function to convert it to an Expression:
:(y = x^2)
As an Expression, I can use the .args attribute to do things like counting the number of variables and returning the unique variables, all of which has worked fine. Now, I need to be able to evaluate the right side of the expression as the Function f(x) = x^2. To do so, I began writing the following function (which has some pretty major flaws):
function evalExpression()
L = [1,2,3,4]
equation = parse(input("Enter an equation"))
f = equation.args[2].args[2]
for i in L
x = i
value = eval(f)
println(value)
end
end
This function has two problems that I haven't been able to resolve. The first is that it gives me an UndefVarError for x when I try to run it right now; that's more or less expected. The second is that unless I knew that the user would input a function of only x, I would have no way of figuring out what the variables I needed to assign were. I wrote a recursive function that can take in an expression and return all its variables in the form of [:x, :y, etc.], but I cannot assign :x to a number to evaluate the function--I need to assign it just to x, and I cannot figure out how to access that. Is there anything that I can use to access the variables I need? Or a different approach I could take?
Thank you!
When I run the following:
function evalExpression()
L = [1,2,3,4]
equation = parse(input("Enter an equation"))
global x
for i in L
x = i
f = equation.args[2].args[2]
value = eval(f)
println(value)
end
end
and then putting y = x*x I get
evalExpression()
Enter an equation
y = x*x
1
2
3
4
What is missing, at least for x as a variable, is declaring it globally. When you eval parsed statements, these parsed statements only access global variables
So what you probably need to do after you've invented your recursive function to correctly fetch variables, is to create them globally. Maybe
eval(parse("$variable = 0"))
will do

Resources