ERROR: invalid redefinition of constant FXQuote in Julia - julia

I am new in Julia. I didn't redifining types. And here is the error message:
ERROR: invalid redefinition of constant FXQuote
Stacktrace:
[1] top-level scope
# /home/ex002.jl:5
Here is the code.
using HTTP
using JSON
mutable struct FXQuote
AskPrice::String
BidPrice::String
Currency::String
end
function Retrive_WebData(_url)
_headers = Dict("User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36")
_content = String(HTTP.get(_url, _headers).body)
_data = JSON.parse(_content)["records"]
return _data
end
_url = "https://finance.yahoo.com/quote/"
_data = Retrive_WebData(_url)
_dict_Data = Dict()
for i in _data
_key = i["ccyPair"]
_fxquote = FXQuote(i["askPrc"], i["bidPrc"], i["ccyPair"])
_dict_Data[_key] = _fxquote
end
println(_dict_Data["USD/CNY"].BidPrice)
The version of Julia is 1.8.5.
How do I solve this. Thanks.

Just restart your Julia session and run the code again.
To me, the root of the problem can be modifying the struct definition after the first run. Example:
julia> mutable struct FXQuote
AskPrice::String
BidPrice::String
Currency::String
end
julia> struct FXQuote
AskPrice::String
BidPrice::String
Currency::String
end
ERROR: invalid redefinition of constant FXQuote
Stacktrace:
[1] top-level scope
# REPL[3]:1
I modified the FXQuote struct in the second run into an immutable struct, and the expected error occurred. In the following example, I'll alter the struct in the second run by changing the type of the Currency param:
julia> mutable struct FXQuote
AskPrice::String
BidPrice::String
Currency::String
end
julia> mutable struct FXQuote
AskPrice::String
BidPrice::String
Currency::Int64
end
ERROR: invalid redefinition of type FXQuote
Stacktrace:
[1] top-level scope
# REPL[2]:1
As you can see, modification causes the error.

Related

Julia: how to get an error message and stacktrace as string?

I am trying to get an error message of a caught exception for use in a warning.
For example, while following
julia> a = 3+b
ERROR: UndefVarError: b not defined
Stacktrace:
[1] top-level scope
# REPL[1]:1
says that the problem is that b is not defined, the following method of handling exception has much less helpful message:
julia> try
a = 3+b
catch e
#warn "Bad thing happend: $e"
end
┌ Warning: Bad thing happend: UndefVarError(:b)
└ # Main REPL[2]:4
How do I get the error message and stacktrace from the exception as String?
While a bit wordy, the answer seems to be by using the Base.showerror(io::IO, err::MyException) function defined for builtin exceptions:
julia> try
a = 3+b
catch e
io = IOBuffer();
showerror(io, e)
error_msg = String(take!(io))
#warn "Trouble doing things:\n$(error_msg)"
end
┌ Warning: Trouble doing things:
│ UndefVarError: b not defined
└ # Main REPL[3]:7
To also get the stacktrace:
use stacktrace(catch_backtrace()) to get the stacktrace vector from the place exception was thrown (see docs)
use show(io, mime, x) to format the vector nicely (see this SO answer)
Combining the two with the sprint that handles the IOBuffer for us, we get to:
julia> try
a = 3+b
catch e
error_msg = sprint(showerror, e)
st = sprint((io,v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
#warn "Trouble doing things:\n$(error_msg)\n$(st)"
end
┌ Warning: Trouble doing things:
│ UndefVarError: b not defined
│ 13-element Vector{Base.StackTraces.StackFrame}:
│ top-level scope at REPL[4]:2
│ eval at boot.jl:373 [inlined]
│ ...
└ # Main REPL[4]:6

Why I cannot create a simple dictionary here

I am trying to create and use a simple dictionary using TFPGmap:
program rnTFPGmap;
{$mode objfpc}
uses fgl;
var
mydict: specialize TFPGmap<string, string>;
key: string;
i: longint;
begin
mydict.create;
mydict.add('k1','v1');
mydict.add('k2','v2');
mydict.add('k3','v3');
//for key in mydict.keys do {does not work either;}
for i := 1 to length(mydict) do {line 17: first error from here. }
writeln(mydict[i]);
end.
However, it is giving following error:
$ fpc soq_rntfpgmap
Free Pascal Compiler version 3.0.0+dfsg-11+deb9u1 [2017/06/10] for x86_64
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling soq_rntfpgmap.pas
soq_rntfpgmap.pas(17,16) Error: Type mismatch
soq_rntfpgmap.pas(18,19) Error: Incompatible type for arg no. 1: Got "LongInt", expected "ShortString"
soq_rntfpgmap.pas(22) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Edit: I tried to modify the code according to documentation and came up with following version:
program rnTFPGmap;
{$mode objfpc}
uses fgl;
type
tuple = specialize TFPGmap<string, string>;
mydict = Array of tuple;
var
dict: mydict;
i: tuple;
item: string;
begin
setlength(dict, length(dict)+3);
dict.add('k1','v1'); {error on this line: "CREATE" expected but "ADD" found}
dict.add('k2','v2');
dict.add('k3','v3');
writeln('dict.count: ', dict.count);
for i in dict do
writeln(i);
end.
But I am now getting following error:
$ fpc soq_rntfpgmap
Free Pascal Compiler version 3.0.0+dfsg-11+deb9u1 [2017/06/10] for x86_64
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling soq_rntfpgmap.pas
soq_rntfpgmap.pas(13,25) Warning: Variable "dict" of a managed type does not seem to be initialized
soq_rntfpgmap.pas(14,7) Fatal: Syntax error, "CREATE" expected but "ADD" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Not able to sort this out.
Following code works. See comments for some explanations:
program rnTFPGmap;
{$mode objfpc}
uses fgl;
type
Rndict = specialize TFPGmap<string, string>;{define type under type}
var
dict: Rndict; {define object under var}
i: integer;
{main: }
begin
dict := Rndict.Create; {create object in main}
dict.add('k1','v1');
dict.add('k2','v2');
dict.add('k3','v3');
for i := 0 to (dict.count-1) do begin
writeln('i: ',i, '; key: ', dict.getkey(i), '; value: ', dict.getdata(i));
end;
end.
Output:
i: 0; key: k1; value: v1
i: 1; key: k2; value: v2
i: 2; key: k3; value: v3
I thank #DavidHeffernan for his guidance.

How can I type a function argument as native function

I have a helper function to use in python repl to move variables to global for easy debugging. But there is a mypy error:
class stepin(object): # pylint: disable=R0903
def __init__(self, func: Callable) -> None:
self.func = func
self.args = func.__code__.co_varnames
if hasattr(func, "__defaults__") and func.__defaults__:
self.defaults = dict(zip(reversed(self.args), reversed(func.__defaults__)))
else:
self.defaults = None
def __call__(self, *args, **kwargs):
result_dict = {x: None for x in self.args}
if self.defaults:
result_dict.update(self.defaults)
result_dict.update(dict(zip(self.args, args)))
result_dict.update(kwargs)
for x in result_dict.keys():
if result_dict[x] is None:
raise ValueError('Missing args: ', self.func.__qualname__, x)
globals().update(result_dict)
Now, the line
if hasattr(func, "__defaults__") and func.__defaults__:
self.defaults = dict(zip(reversed(self.args), reversed(func.__defaults__)))
raises a mypy error that says func has no __defaults__
Now I understand that the BDFL has said he despises the "hasattr" check so it's probably not gonna be solved inside mypy; then my question is, is there a way to change the __init__ typing signature to get rid of the error?
What have I tried: Callable doesn't work, understandable: not all Callables have __defaults__.
But where is the type "function"? If I type() a function it says "function" but "function" is not in preamble or "typing". I see that some people mention "FunctionType" but it's not in "typing" either.
The type of a function is types.FunctionType (in the types module).
If you modify the annotation for func from Callable to types.FunctionType, mypy no longer complains about __defaults__.

Julia function timeout using async and remotecall_fetch fails to find function

I'm trying to kill execution of a function when it times out. Tried to leverage the post here: Julia: Can you set a time limit on eval
It errored on RemoteRef is undefined (I'm using v0.6.0). Replaced RemoteRef with Channel(1). Now the error is
MethodError: no method matching remotecall_fetch
(::Int64, ::#test, ::String, ::String, ::String)
addprocs(1)
#everywhere include("test.jl")
response = Channel(1)
#async put!(response, remotecall_fetch(2, test, arg1, arg2, arg3))
start=time()
while !isready(response) && (time() - start) < timeoutDuration
sleep(0.1)
end
elapsedtime = time()-start
ERROR (unhandled task failure): MethodError: no method matching remotecall_fetch(::Int64, ::#test,
::String, ::String, ::String)
Also tried
#async put!(response, remotecall_fetch(2, ()->test(arg1, arg2, arg3)))
ERROR (unhandled task failure): MethodError: no method matching remotecall_fetch(::Int64, ::##10#12)
Is the second worker unable to find test()?
According to the documentation:
help?> remotecall_fetch
search: remotecall_fetch remotecall_wait
remotecall_fetch(f, id::Integer, args...; kwargs...)
Perform fetch(remotecall(...)) in one message. Keyword arguments,
if any, are passed through to f. Any remote exceptions are captured
in a RemoteException and thrown.
See also fetch and remotecall.
remotecall_fetch(f, pool::AbstractWorkerPool, args...; kwargs...) -> result
WorkerPool variant of remotecall_fetch(f, pid, ....). Waits for and
takes a free worker from pool and performs a remotecall_fetch on it.
You'd need to do it like this:
#async put!(response, remotecall_fetch(test, 2, arg1, arg2, arg3))
Syntax issue, worker# should be at the end
#async put!(response, remotecall_fetch(()->test(a1,a2,a3),2) )

Type or Class for a Pointer in a Linked List in Fortran

I am confused about the usage of TYPE and CLASS in defining a linked list with type bound procedure in Fortran. The following simple program causes segmentation fault in get_num_nodes function. However, if I change the declaration of the pointer next from CLASS to TYPE, the program ends normally.
The segmentation fault occurs when I build it with ifort (version 14.0.2).
If I build it with gfortran (version 4.8.4 and 7.2.0), both cases of CLASS and TYPE end normally.
What is wrong about using CLASS in declaring the next pointer? How can I understand the problem? Or, is something wrong in a different part of the code?
tll.f90
MODULE tll
IMPLICIT NONE
PRIVATE
PUBLIC LLnode, add_node_at_head
TYPE LLnode
PRIVATE
INTEGER :: idx
!TYPE(LLnode), POINTER :: next => null()
! .. using this declaration with TYPE works.
CLASS(LLnode), POINTER :: next => null()
! .. this declaration with CLASS causes segmentation fault with
! ifort.
CONTAINS
PROCEDURE :: get_num_nodes
END type LLnode
! ================================================================
CONTAINS
! ================================================================
! ****************************************************************
SUBROUTINE add_node_at_head(p_head, idx_arg)
! ****************************************************************
TYPE(LLnode), POINTER, INTENT(INOUT) :: p_head
INTEGER, INTENT(IN) :: idx_arg
!
TYPE(LLnode), POINTER :: p_new_head
write(*,*) 'entered add_node_at_head..'
allocate(p_new_head)
p_new_head%idx = idx_arg
p_new_head%next => p_head
p_head => p_new_head
write(*,*) '.. leaving add_node_at_head'
END SUBROUTINE add_node_at_head
! ****************************************************************
FUNCTION get_num_nodes(self) RESULT(num_nodes)
! ****************************************************************
INTEGER :: num_nodes
CLASS(LLnode), TARGET, INTENT(IN) :: self
!
CLASS(LLnode), POINTER :: p_node
write(*,*) 'entered get_num_nodes ..'
num_nodes = 0
p_node => self
do while (associated(p_node))
num_nodes = num_nodes+1
p_node => p_node%next
end do
write(*,*) '.. leaving get_num_nodes'
END FUNCTION get_num_nodes
END MODULE tll
main.f90
PROGRAM main
USE tll, ONLY : LLnode, add_node_at_head
IMPLICIT NONE
TYPE(LLnode), POINTER :: p_head=>null()
INTEGER :: num_nodes
call add_node_at_head(p_head, 10)
num_nodes= p_head%get_num_nodes()
write(*,*) 'num_nodes=', num_nodes
write(*,*) 'Normal End.'
END PROGRAM main
Compilation and execution:
$ ifort -c tll.f90
$ ifort -c main.f90
$ ifort -o exe main.o tll.o
$ ./exe
entered add_node_at_head..
.. leaving add_node_at_head
entered get_num_nodes ..
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
exe 000000000046DF09 Unknown Unknown Unknown
exe 000000000046C7DE Unknown Unknown Unknown
exe 000000000043E3B2 Unknown Unknown Unknown
exe 0000000000422FC3 Unknown Unknown Unknown
exe 0000000000402A3B Unknown Unknown Unknown
libpthread.so.0 00002B8FDBB48330 Unknown Unknown Unknown
exe 00000000004026D2 Unknown Unknown Unknown
exe 0000000000402402 Unknown Unknown Unknown
exe 0000000000402336 Unknown Unknown Unknown
libc.so.6 00002B8FDBD77F45 Unknown Unknown Unknown
exe 0000000000402229 Unknown Unknown Unknown
$

Resources