No iterate method on Ordering - julia

I'm implementing the Ordering type according to the docs but I'm getting a missing method error. The docs don't say anything about needing to define iterate?
https://juliacollections.github.io/DataStructures.jl/v0.9/sorted_containers.html#Constructors-for-Sorted-Containers-1
ERROR: LoadError: MethodError: no method matching iterate(::Type{BidOrdering})
using DataStructures
import Base.Ordering
import Base.lt
import DataStructures.eq
struct MBOBookEntity
orderid::Int64
price::String
orderPriority::Int64
displayQty::Int64
end
mutable struct MBOBook
bidBook::SortedSet{MBOBookEntity}
askBook::SortedSet{MBOBookEntity}
function MBOBook()
bidBook = SortedSet{MBOBookEntity}(BidOrdering)
askBook = SortedSet{MBOBookEntity}(AskOrdering)
new(bidBook, askBook)
end
end
struct BidOrdering <: Ordering end
struct AskOrdering <: Ordering end
lt(::BidOrdering, o1::MBOBookEntity, o2::MBOBookEntity) = begin
if o1.price == o2.price
return o1.orderPriority < o2.orderPriority
else
return o2.price < o1.price
end
end
eq(::BidOrdering, o1::MBOBookEntity, o2::MBOBookEntity) = isequal(o1.orderid, o2.orderid)
lt(::AskOrdering, o1::MBOBookEntity, o2::MBOBookEntity) = begin
if o1.price == o2.price
return o1.orderPriority < o2.orderPriority
else
return o1.price < o2.price
end
end
eq(::AskOrdering, o1::MBOBookEntity, o2::MBOBookEntity) = isequal(o1.orderid, o2.orderid)

I think that you provide a type instead of a value :
mutable struct MBOBook
bidBook::SortedSet{MBOBookEntity}
askBook::SortedSet{MBOBookEntity}
function MBOBook()
bidBook = SortedSet{MBOBookEntity}(BidOrdering()) # <- here, forgotten ()
askBook = SortedSet{MBOBookEntity}(AskOrdering()) # <- here, forgotten ()
new(bidBook, askBook)
end
end

Related

Julia, MethodError: no method matching

I wanted to test how abstract type works in "strcutres", so I created a struct below with a constructor, however, the return message displays "ERROR: MethodError: no method matching Rect(::Int64)".
I don't know which part went wrong, although the parameter "5" that I used fits the definition of the constuctor which is a single integer input. Thank you.
abstract type Shape{T<:Integer,F<:AbstractFloat} end
export Shape
struct Rect{T,F} <: Shape{T,F}
a::T
b::T
c::T
v::F
function Rect{T,F}(a::T) where {T<:Integer, F<:AbstractFloat}
b = 10;
c = 10;
v = a*b*c;
return new(a,b,c,v)
end
end
function main()
vol = Rect(5).v;
println(vol)
end
main()
It should return a product of a, b and c with only a being the input variable.
You do not have the appropriate constructor.
You should do:
julia> Rect{Int,Float64}(5)
Rect{Int64, Float64}(5, 10, 10, 500.0)
Other option is to add the constructor to your struct:
function Rect{T}(a::T) where {T<:Integer}
Rect{Int,Float64}(a)
end
Once you add the constructor you can do:
julia> Rect{Int}(5)
Rect{Int64, Float64}(5, 10, 10, 500.0)
Or you can also define:
Rect(a::Int) = Rect{Int,Float64}(a)
and have
julia> Rect(5)
Rect{Int64, Float64}(5, 10, 10, 500.0)

Interpolating literals into each expression in an array using a for loop

I have a function within which I would like to evaluate a list of expressions using interpolated literals passed as arguments to the function and assign the result to a new array. Previously I've been able to do this fairly simply:
array_of_expr = Any[:(A * 5), :(B * 6 * T)]
arglist = [:A; :B; :T]
test_input = [1e5, 1e1, 100]
#eval begin
function interpolate_all($(arglist...))
result_array = $(Expr(:vcat, array_of_expr...))
end
end
interpolate_all(test_input...)
which returns the expected result:
2-element Array{Float64,1}:
500000.0
6000.0
(I know the code seems needlessly complicated with the #eval--it's because in the full version of the code, arglist is ~500 items long. This has been causing some compiler errors in the full version of the code, so my attempts here to loop over array_of_expr are part of my testing to find out the exact error, and also help me better understand metaprogramming/variable scope while I'm at it.)
I can index array_of_expr and evaluate an individual elements manually in this MWE:
#eval begin
function interpolate_one($(arglist...))
result_array = similar(array_of_expr)
println("evaluating $(array_of_expr[2])")
result_array = $(array_of_expr[2])
println(result_array)
end
end
interpolate_one(test_input...)
which returns:
evaluating B * 6 * T
6000.0
Which is the expected behavior. But if I try to loop over array_of_expr, I encounter various errors. The following ignores the iterator i and just prints the symbolic expression:
#eval begin
function interpolate_1by1($(arglist...))
result_array = similar(array_of_expr)
# this doesn't work, it just gives the symbolic expression, basically ignoring the $:
for i in range(1, length=length(array_of_expr))
result_array[i] = ($array_of_expr[i])
end
println(result_array)
end
end
interpolate_1by1(test_input...)
The following reports that i is not defined, which I understand is because expressions are evaluated in the global scope, not local:
#eval begin
function interpolate_1by1($(arglist...))
result_array = similar(array_of_expr)
# this doesn't work, i is undefined:
for i in range(1, length=length(array_of_expr))
result_array[i] = $(array_of_expr[i])
end
end
end
interpolate_1by1(test_input...)
Is there any way to make this work? I have tried the tactics in the cited SE answer, but did not have success.
you may unroll the loop at compile time:
#eval begin
function interpolate_1by1($(arglist...))
result_array = similar($array_of_expr)
$((quote
result_array[$i] = $(array_of_expr[i])
end for i in 1:length(array_of_expr))...)
return result_array
end
end
which after expansion is similar to
function interpolate_1by1($(arglist...))
result_array = similar($array_of_expr)
result_array[1] = $(array_of_expr[1])
result_array[2] = $(array_of_expr[2])
...
return result_array
end

Changing the input (i.e. x+2y) of a macro to an expression ( :(x+2y)), How to produce the same output?

The code at the end of this post constructs a function which is bound to the variables of a given dictionary. Furthermore, the function is not bound to the actual name of the dictionary (as I use the Ref() statement).
An example:
julia> D = Dict(:x => 4, :y => 5)
julia> f= #mymacro4(x+2y, D)
julia> f()
14
julia> DD = D
julia> D = nothing
julia> f()
14
julia> DD[:x] = 12
julia> f()
22
Now I want to be able to construct exactly the same function when I only have access to the expression expr = :(x+2y).
How do I do this? I tried several things, but was not able to find a solution.
julia> f = #mymacro4(:(x+2y), D)
julia> f() ### the function evaluation should also yield 14. But it yields:
:(DR.x[:x] + 2 * DR.x[:y])
(I actually want to use it within another macro in which the dictionary is automatically created. I want to store this dictionary and the function within a struct, such that I'm able to call this function at a later point in time and manipulate the objects in the dictionary. If necessary, I may post the complete example and explain the complete problem.)
_freevars2(literal) = literal
function _freevars2(s::Symbol)
try
if typeof(eval(s)) <: Function
return s
else
return Meta.parse("DR.x[:$s]")
end
catch
return Meta.parse("DR.x[:$s]")
end
end
function _freevars2(expr::Expr)
for (it, s) in enumerate(expr.args)
expr.args[it] = _freevars2(s)
end
return expr
end
macro mymacro4(expr, D)
expr2 = _freevars2(expr)
quote
let DR = Ref($(esc(D)))
function mysym()
$expr2
end
end
end
end

In Julia: How to declare the type of a function parameter that is a function? [duplicate]

Can I add type information to arguments that are functions?
Consider the following example:
function f{T} (func, x::Int)
output = Dict{Int, Any}()
output[x] = func(x)
return output
end
I don't like that I have to say Any for the value type of the dictionary. I'd much rather do the following:
function f{T} (func::Function{Int->T}, x::Int)
output = Dict{Int, T}()
output[x] = func(x)
return output
end
Can I provide type hints of functions like this? I kind of want to say the following
f :: (Int -> T), Int -> Dict{Int, T}
Not currently. We may add something along those lines in the future, however.
This is not an answer to the main question, but more a really ugly workaround the Any in the Dict issue:
function f(func, x::Int)
T = code_typed(func, (Int,))[1].args[3].typ
output = Dict{Int, T}()
output[x] = func(x)
return output
end
That is probably not efficient and will probably work only on simple cases (which do not even include anonymous functions) like
>>> g(x) = x*2
>>> typeof(f(g, 1234))
Dict{Int64,Int64}
>>> h(x) = x > zero(x) ? x : nothing
>>> typeof(f(h, 1234))
Dict{Int64,Union(Int64,Nothing)}
EDIT:
This works better:
function f(func, x::Int)
[x => func(x)]
end
>>> dump( f(x->2x, 3) )
Dict{Int64,Int64} len 1
3: Int64 6

HttpServer and Julia error with match method

I'm trying to understand how to work with this package for Julia.
Im using the following code (is an example from the package):
using HttpServer
function fibonacci(n)
if n == 1 return 1 end
if n == 2 return 1 end
prev = BigInt(1)
pprev = BigInt(1)
for i=3:n
curr = prev + pprev
pprev = prev
prev = curr
end
return prev
end
http = HttpHandler() do req::Request, res::Response
m = match(r"^/fibo/(\d+)/?$",req.resource)
if m == nothing
return Response(404)
end
number = BigInt(m.captures[1])
if number < 1 || number > 100_000
return Response(500)
end
return Response(string(fibonacci(number)))
end
http.events["error"] = (client, err) -> println(err)
http.events["listen"] = (port) -> println("Listening on $port...")
server = Server(http)
run(server, 8031)
And trying to access to the server with this link:
http://localhost:8031/fibo/100
But i get the next error:
MethodError(convert,(BigInt,"100"))
ERROR: MethodError: Cannotconvert an object of type
SubString{String} to an object of type BigInt
What im doing wrong?
I have problems to figure out what r"^/fibo/(\d+)/? does, maybe there is my problem...
You get this error because method BigInt(s::AbstractString) is deprecated and was remove in julia 0.5. Use number = parse(BigInt,m.captures[1]) instead.

Resources