Issue with using pyimport in Julia 1.1.0 - julia

I made a module with an if condition on the number of cores.
module mymodule
import Pkg
import PyCall
using Distributed
if nworkers() > 1
#everywhere using Pkg
#everywhere Pkg.activate(".")
#everywhere Pkg.instantiate()
#everywhere using PyCall
#everywhere #pyimport scipy.signal as ss
function parallel()
....
end
else
using Pkg
Pkg.activate(".")
Pkg.instantiate()
using PyCall
#pyimport scipy.signal as ss
function serial()
....
end
end
end #mymodule
Code throws the following error on execution
ERROR: LoadError: LoadError: UndefVarError: #pyimport not defined
Stacktrace:
[1] top-level scope
[2] include at ./boot.jl:326 [inlined]
[3] include_relative(::Module, ::String) at ./loading.jl:1038
[4] include(::Module, ::String) at ./sysimg.jl:29
[5] include(::String) at ./client.jl:403
[6] top-level scope at none:0
in expression starting at /storage/work/s/mymodule.jl:81
in expression starting at /storage/work/s/mymodule.jl:30
where line 81 is the line in else condition corresponding to #pyimport scipy.signal as ss and line 30 corresponds to if nworkers() > 1.
Before this problem, the code had an issue with the line #everywhere #pyimport scipy.signal as ss but that disappeared by using import PyCall; bizarrely though, it didn't solve the former problem.
Has anyone experienced a similar issue or aware of such issues?

You need to use pyimport function instead. Macro definition (comes from your using) and usage of that macro in the same block does not work due to the parsing/evaluation order.
Simply change the code
#pyimport scipy.signal as ss
to
ss = pyimport("scipy.signal")
You can also divide the blocks into two, first for the definitions and the second for usage. However, I would not do that as #pyimport macro is already deprecated.

Related

Can't plot in Julia

I am currently reading a book (BRML) which has a demo (earthquake demo, exercise 1.22), which is written in Julia. I have never used Julia (although used Python and other languages quite extensively) before so I'm a complete noob.
What exactly does the line plot(x,y,".") do in the following code:
Pkg.add("Pkg")
using Pkg
Pkg.add("PyPlot")
S=5000 # number of points on the spiral
x=zeros(S); y=zeros(S)
for s=1:S
theta=50*2*pi*s/S; r=s/S
x[s]=r*cos(theta); y[s]=r*sin(theta)
end
plot(x,y,".")
I understand everything that is done before that, however I'm not sure what that specific line does. The reason I can't see for myself is because when I'm trying to run it on an online Julia compiler, I get the following error:
INFO: Initializing package repository /home/cg/root/4655378/.julia/v0.6
INFO: Cloning METADATA from https://github.com/JuliaLang/METADATA.jl
ERROR: LoadError: GitError(Code:ERROR, Class:Net, curl error: Could not resolve host: github.com
)
Stacktrace:
[1] macro expansion at ./libgit2/error.jl:99 [inlined]
[2] clone(::String, ::String, ::Base.LibGit2.CloneOptions) at ./libgit2/repository.jl:276
[3] #clone#100(::String, ::Bool, ::Ptr{Void}, ::Nullable{Base.LibGit2.AbstractCredentials}, ::Function, ::String, ::String) at ./libgit2/libgit2.jl:562
[4] (::Base.LibGit2.#kw##clone)(::Array{Any,1}, ::Base.LibGit2.#clone, ::String, ::String) at ./<missing>:0
[5] (::Base.Pkg.Dir.##8#10{String,String})() at ./pkg/dir.jl:55
[6] cd(::Base.Pkg.Dir.##8#10{String,String}, ::String) at ./file.jl:70
[7] init(::String, ::String) at ./pkg/dir.jl:53
[8] #cd#1(::Array{Any,1}, ::Function, ::Function, ::String, ::Vararg{String,N} where N) at ./pkg/dir.jl:28
[9] add(::String) at ./pkg/pkg.jl:117
while loading /home/cg/root/4655378/main.jl, in expression starting on line 1
As the third line indicates, the book is using the PyPlot package, which is basically a Julia wrapper around Python's pyplot.
So, we could refer to pyplot's documentation to figure out how that line of code works. But as mentioned in that page, pyplot is trying to emulate MATLAB's plot function, and for this case their help page is easier to navigate. As mentioned there,
plot(X,Y) creates a 2-D line plot of the data in Y versus the corresponding values in X.
and plot(X,Y,LineSpec) in addition "creates the plot using the specified line style, marker, and color." Clicking on LineSpec, we can see in the second table that '.' is one of the markers, with description Point and the resulting marker a black filled dot. So plot(x,y,".") creates a plot with dots as markers at the points specified by the x- and y-coordinates.
We could also try one of the other markers, for eg. plot(x,y,"+") creates this instead:
where if you look carefully, you can see that the points are marked by + signs instead.

Models.Fitting type failure

I've inherited some old code, which was written for a much earlier version of Julia (~v0.6). I'm running Julia 1.5.4 and I've already adjusted a lot of the existing code, without much trouble.
But when I run:
import Models
type GLMA <: Models.Fitting.AbstractFittingAlgorithm
end
I get
ERROR: syntax: extra token "GLMA" after end of expression
Stacktrace:
[1] top-level scope at none:1
Why is this happening?
(a) Is there an issue with the type part?
Additionally, (b) Why is Models.Fitting missing when I do this:
Models.Fitting
ERROR: UndefVarError: Fitting not defined
Stacktrace:
[1] getproperty(::Module, ::Symbol) at .\Base.jl:26
[2] top-level scope at REPL[4]:1
I think you might have to declare it as an abstract type rather than a "bare" type. For example:
import Models
abstract type GLMA <: Models.Fitting.AbstractFittingAlgorithm; end
I don't see any bare type references, just abstract and primitive:
Types
Abstract Types
So with the following I was able to reproduce your error message:
julia> abstract type X end
julia> type Y <: X end
ERROR: syntax: extra token "Y" after end of expression
Stacktrace:
[1] top-level scope at none:1
A remote possibility is that the old code brought Fitting into scope with import or using and the keyword 'as' and if that renaming is not currently done, then you've lost that link. More here:
https://docs.julialang.org/en/v1/manual/modules/#Renaming-with-as

Julia UndefVarError: subtypes not defined

Unclear why I get
ERROR: LoadError: UndefVarError: subtypes not defined when executing a .jl file, but not when executed from the REPL.
E.g.
abstract type Asset end
abstract type Property <: Asset end
abstract type Investment <: Asset end
abstract type Cash <: Asset end
println(subtypes(Asset))
> 3-element Array{Any,1}:
Cash
Investment
Property
...but put the very same code in test.jl,
julia test.jl
> ERROR: LoadError: UndefVarError: subtypes not defined
Stacktrace:
[1] top-level scope at /.../test.jl:6
[2] include(::Module, ::String) at ./Base.jl:377
[3] exec_options(::Base.JLOptions) at ./client.jl:288
[4] _start() at ./client.jl:484
in expression starting at /.../test.jl:6
Julia version 1.4.1, executing on OSX Catalina (10.15.4)
You need to add using InteractiveUtils before calling subtypes. By default this is already loaded when starting the Julia REPL.
Hence your file should look like this:
shell> more t.jl
using InteractiveUtils
abstract type Asset end
abstract type Property <: Asset end
abstract type Investment <: Asset end
abstract type Cash <: Asset end
println(subtypes(Asset))
shell> julia t.jl
Any[Cash, Investment, Property]

Alternatives to parse and eval to check syntactic correctness for Julia v 1.1

Julia is dynamically typed and certain errors only occur during execution.
For instance:
julia> function foo()
a
5
end
foo (generic function with 1 method)
julia> foo()
ERROR: UndefVarError: a not defined
Stacktrace:
[1] foo() at ./REPL[1]:2
[2] top-level scope at none:0
julia>
Same behaviour using parse in combination with eval:
julia> eval(Meta.parse("function foo()
a
5
end"))
foo (generic function with 1 method)
However, when executing this an error is thrown:
julia> foo()
ERROR: UndefVarError: a not defined
Stacktrace:
[1] foo() at ./none:2
[2] top-level scope at none:0
Does it exist any standard facilities to check against these kinds of errors? Or does it exist any suitable packages for this task?
The VS Code Julia extension has an integrated linter that can detect usage of undefined variables, as in your example.
There is also this linter, Lint.jl, though I am not sure if it's up-to-date for Julia v1.x.

What does it mean when a Julia error references a line number that doesn't exist?

I'm getting an odd error in Julia today, one that references a line number that doesn't exist.
ERROR: LoadError: LoadError: LoadError: UndefVarError: T not defined
in include_from_node1(::String) at ./loading.jl:488 (repeats 3 times)
in eval(::Module, ::Any) at ./boot.jl:234
in require(::Symbol) at ./loading.jl:415
in eval(::Module, ::Any) at ./boot.jl:234
in process_options(::Base.JLOptions) at ./client.jl:239
in _start() at ./client.jl:318
while loading /home/peter/Code/Spark.jl/src/rdd.jl, in expression starting on line 480
while loading /home/peter/Code/Spark.jl/src/core.jl, in expression starting on line 17
while loading /home/peter/Code/Spark.jl/src/Spark.jl, in expression starting on line 19
Now, what's odd here is that it references line 480 of the file rdd.jl, which has only 178 lines.
This can be reproduced by checking out https://github.com/peterjdolan/Spark.jl/tree/type_safety
and running:
julia -e "using Spark"
There is some setup necessary to get that package running, which is documented in the README.md of https://github.com/dfdx/Spark.jl.
Thanks for any insight into this odd error message
The error message suggests that you have a function or type that has a hanging T, ie, T is not declared as a type parameter, but used in the body.
And sure enough, on line 63 of rdd.jl, you have the function defined
function source_eltype(nextrdd::Union{RDD{T}, Void})
That should instead be
function source_eltype{T}(nextrdd::Union{RDD{T}, Void})
Making that change fixes the error.
It is of course unfortunate that the line number is incorrect. There is an issue open about it at: https://github.com/JuliaLang/julia/issues/18764 . It manifests itself as incorrect line numbers when there are errors in functions that have docstrings on them (or more generally, are within macros)

Resources