Julia: Console Input Validation - console

How do you guys handle console input validation? In C++, case/switch is my goto...
I was trying a recursive function but was getting locked in lower levels. Plus that might be overdoing it. I did manage a while loop with an "exclusive or" but, that is not really scalable.
function prob6()
println("Pick a number; any number:")
x = readline(stdin)
y = parse(Int64, x)
z = 0
println("Select 1 or 2")
p1 = readline(stdin)
p2 = parse(Int64, p1)
select = p2
while xor((p2 == 1), (p2 == 2)) == false
println("Select 1 or 2")
p1 = readline(stdin)
p2 = parse(Int64, p1)
select = p2
end
if select == 1
for i in 1:y
print("$i ")
z = z + i
end
else
z = 1
for i in 1:y
print("$i ")
z = z * i
end
end
println(z)
end
Any alternatives?

There are many ways. I usually create a validation loop to check the type of the input item, and will use tryparse instead of parse, since it will not throw an error if input is malformed:
function queryprompt(query, typ)
while true
print(query, ": ")
choice = uppercase(strip(readline(stdin)))
if (ret = tryparse(typ, choice)) != nothing
return ret
end
println()
end
end
n = queryprompt("Integer please", Int64)
println(n)
x = queryprompt("Float please", Float64)
println(x)

Related

How can i setup Gurobi environment in Julia by a function?

i am trying to use a code in a paper but the code for gurobi seems changed these days, it showed some error and i want to put the gurobi environment setting below into my optimization.
the gurobi environment setting is below :
function setup_gurobi_env(; quiet_mode = true, method_type = :barrier, use_time_limit = true, time_limit = 60.0)
env = Gurobi.Env()
if quiet_mode
setparams!(env; OutputFlag = 0)
end
if method_type == :barrier
setparams!(env; Method = 2)
elseif method_type == :method3
setparams!(env; Method = 3)
elseif method_type != :default
error("Enter a valid method type for Gurobi.")
end
if use_time_limit
setparams!(env; TimeLimit = time_limit)
end
return env
end
the author of the paper use the method below to use this setting:
function portfolio_simplex_jump_setup(Sigma::Matrix{Float64}, gamma::Float64; gurobiEnv = setup_gurobi_env(method_type = :default, use_time_limit = false))
(d, d2) = size(Sigma)
if d != d2
error("Sigma dimensions don't match")
end
mod = Model(with_optimizer(Gurobi.Optimizer, gurobiEnv))
#variable(mod, w[1:d] >= 0)
#constraint(mod, sum(w[i] for i = 1:d) <= 1)
#constraint(mod, w'*Sigma*w <= gamma)
function local_portfolio_oracle(c::Vector{Float64})
#objective(mod, Min, dot(c, w))
optimize!(mod)
z_ast = objective_value(mod)
w_ast = value.(w)
return (z_ast, w_ast)
end
return c -> local_portfolio_oracle(c)
end
i changed the function into this but it still showed error for not be able to use gurobi since my coding is too old.
function portfolio_simplex_jump_setup(; gurobiEnv = setup_gurobi_env(method_type = :default, use_time_limit = false))
mod = Model(Gurobi.Optimizer)
#variable(mod, 0 <=w[1:d] <= 1)
#constraint(mod, sum(w[i] for i = 1:d) <= 3)
function local_portfolio_oracle(c::Vector{Float64})
#objective(mod, Min, dot(c, w))
optimize!(mod)
z_ast = objective_value(mod)
w_ast = value.(w)
return (z_ast, w_ast)
end
return c -> local_portfolio_oracle(c)
end
i think the problem is in here
mod = Model(with_optimizer(Gurobi.Optimizer, gurobiEnv))
maybe gurobi just upload the new coding method?
Thank you to everyone who replied to me~
This is the current pattern to use Gurobi (taken from one of my academic codes):
const GRB_ENV = Gurobi.Env()
m = Model(()->Gurobi.Optimizer(GRB_ENV))
set_optimizer_attribute(m, "OutputFlag", 0)
set_optimizer_attribute(m, "TimeLimit", 100)
set_optimizer_attribute(m, "MIPGap", 0.001)
set_optimizer_attribute(m, "Threads", min(length(Sys.cpu_info()),16))

Error map-functions.lua:42: bad argument #2 to 'draw' (Quad expected, got nil) , any idea what's wrong?

I'm very new to love and lua and I don't know why I keep getting this message, any ideas? here's my code, hope you guys know what I could do.
in maps-functions.lua
function loadMap(path)
love.filesystem.load(path)()
end
function newMap(tileW, tileH, tilesetPath, tileString, quadInfo)
TileW = tileW
TileH = tileH
Tileset = love.graphics.newImage(tilesetPath)
local tilesetW, tilesetH = Tileset:getWidth(), Tileset:getHeight()
Quads = {}
for _,info in ipairs(quadInfo) do
-- info[1] = the character, info[2] = x, info[3] = y
Quads[info[1]] = love.graphics.newQuad(info[2], info[3], TileW, TileH, tilesetW, tilesetH)
end
TileTable = {}
local width = #(tileString:match("[^\n]+"))
for x = 1,width,1 do TileTable[x] = {} end
local x,y = 1,1
for row in tileString:gmatch("[^\n]+") do
assert(#row == width, 'Map is not aligned: width of row ' .. tostring(y) .. ' should be ' .. tostring(width) .. ', but it is ' .. tostring(#row))
x = 1
for tile in row:gmatch(".") do
TileTable[x][y] = tile
x = x + 1
end
y=y+1
end
end
function drawMap()
for x,column in ipairs(TileTable) do
for y,char in ipairs(column) do
love.graphics.draw(Tileset, Quads[ char ] , (x-1)*TileW, (y-1)*TileH)
end
end
end
Perhaps it has something to do with the map I drew or the image?

Passing tables as parameters in Nim

hopefully an easy question.. I've been playing around with Nim and have realised I need to pass a table (dictionary, map, in some other languages), but I can't seem to figure out the syntax for declaring it in doStuff()
import tables
proc doStuff(n:int, t:[int, int]) = # How should I declare 't' here?
if n == 0:
return
t[n] = (n * 10)
echo "length of t = " & ($len(t))
doStuff(n+1, t)
proc main() =
var tbl = initTable[int, int]()
echo "length of tbl = " & ($len(tbl))
tbl[0] = 0
doStuff(5, tbl)
echo "length of tbl = " & ($len(tbl))
main()
The above gets me Error: type expected, but got: [int, int]
Sorry if this is basic, but my Googling hasn't given me an answer yet
Many TIA
You almost got it, it should be like below:
import tables
proc doStuff(n: int, t: var Table[int, int]) =
if n == 0:
return
t[n] = n * 10
echo "length of t = " & $len(t)
doStuff(n + 1, t)
proc main() =
var tbl = initTable[int, int]()
echo "length of tbl = " & $len(tbl)
tbl[0] = 0
doStuff(5, tbl)
echo "length of tbl = " & $len(tbl)
main()
You have to use var Table[int, int] instead of Table[int, int] because you are mutating the tbl variable recursively, so you need to pass by reference instead of by value.

Vector of vector re-size

So I have two vector of vectors like:
matchings_vec = Vector{Vector{Vector{Vector{Any}}}}(num_tilt1)
Minfoall_vec = Vector{Vector{Vector{Vector{Vector{Vector{Float64}}}}}}(num_tilt1)
I defined it as:
matchings_vec = [Vector{Any}() for i in 1:num_tilt1]
Minfoall_vec = [Vector{Float64}() for i in 1:num_tilt1]
Then I am trying to resize the inner vectors like:
for tt = 1:num_tilt1
t_tt = t[tt] #; t1 = t_tt; t2 = 1;
if t_tt == 1
num_rot1 = 1
else
num_rot1 = round(Int, num_rot_t2 * t_tt/2)
if rem.(num_rot1, 2) == 1.0
num_rot1 += 1
end
num_rot1 /= 2
end
num_rot1 = round(Int, num_rot1)
#resize!(matchings_vec[tt], num_rot1)
matchings_vec[tt] = Vector{Any}(num_rot1)
#resize!(Minfoall_vec[tt], num_rot1)
Minfoall_vec[tt] = Vector{Float64}(num_rot1)
for rr = 1:num_rot1
num_tilt2 = round(Int, num_tilt2)
#resize!(matchings_vec[tt][rr], num_tilt2)
matchings_vec[tt][rr] = Vector{Any}(num_tilt2)
#resize!(Minfoall_vec[tt][rr], num_tilt2)
Minfoall_vec[tt][rr] = Vector{Float64}(num_tilt2)
for tt2 = 1:num_tilt2
t_im2 = t[tt2]
#t_im2_1 = t_im2; t_im2_2 = 1;
if t_im2 == 1
num_rot1_2 = 1
else
num_rot1_2 = round(Int, num_rot_t2 * t_im2/2)
if rem.(num_rot1_2, 2) == 1.0
num_rot1_2 += 1
end
num_rot1_2 /= 2
end
num_rot1_2 = round(Int, num_rot1_2)
#resize!(matchings_vec[tt][rr][tt2], num_rot1_2)
matchings_vec[tt][rr][tt2] = Vector{Any}(num_rot1_2)
#resize!(Minfoall_vec[tt][rr][tt2], num_rot1_2)
Minfoall_vec[tt][rr][tt2] = Vector{Float64}(num_rot1_2)
end
end
end
I am getting this error:
MethodError: Cannot convert an object of type Array{Float64,1} to an
object of type Float64 This may have arisen from a call to the
constructor Float64(...), since type constructors fall back to convert
methods.
Stacktrace: [1] setindex!(::Array{Float64,1}, ::Array{Float64,1},
::Int64) at ./array.jl:578 [2] macro expansion at ./In[32]:22
[inlined] [3] anonymous at ./:?
Can you suggest what I am doing wrong? Thanks!

Loss function in chainer remains zero

Im using chainer and im try to do topic modeling. The code for the training phase contains the following:
optimizer = O.Adam()
optimizer.setup(self.train_model)
clip = chainer.optimizer.GradientClipping(5.0)
optimizer.add_hook(clip)
j = 0
msgs = defaultdict(list)
for epoch in range(epochs):
print "epoch : ",epoch
data = prepare_topics(cuda.to_cpu(self.train_model.mixture.weights.W.data).copy(),
cuda.to_cpu(self.train_model.mixture.factors.W.data).copy(),
cuda.to_cpu(self.train_model.sampler.W.data).copy(),
self.words)
top_words = print_top_words_per_topic(data)
if j % 100 == 0 and j > 100:
coherence = topic_coherence(top_words)
for j in range(self.n_topics):
print j, coherence[(j, 'cv')]
kw = dict(top_words=top_words, coherence=coherence, epoch=epoch)
data['doc_lengths'] = self.doc_lengths
data['term_frequency'] = self.term_frequency
for d, f in utils.chunks(self.batchsize, self.doc_ids, self.flattened):
t0 = time.time()
self.train_model.cleargrads()
l = self.train_model.fit_partial(d.copy(), f.copy(), update_words = update_words, update_topics = update_topics)
prior = self.train_model.prior()
loss = prior * self.fraction
loss.backward()
optimizer.update()
msg = ("J:{j:05d} E:{epoch:05d} L:{loss:1.3e} "
"P:{prior:1.3e} R:{rate:1.3e}")
prior.to_cpu()
loss.to_cpu()
t1 = time.time()
dt = t1 - t0
rate = self.batchsize / dt
msgs["E"].append(epoch)
msgs["L"].append(float(l))
j += 1
logs = dict(loss=float(l), epoch=epoch, j=j, prior=float(prior.data), rate=rate)
print msg.format(**logs)
print "\n ================================= \n"
#serializers.save_hdf5("lda2vec.hdf5", self.model)
msgs["loss_per_epoch"].append(float(l))
whn i execute the code i get for example:
J:00200 E:00380 L:0.000e+00 P:-2.997e+04 R:2.421e+04
only the L(loss) dont change, can someone please help to know why this value remain zero?

Resources