Reputation: 175
I need to read input from the following input file and initialise all the variables.
Input File
A=1.0
B=1.0
C=2.0
I use following Julia
code to read this.
# Read the delemited file
in = readdlm("inputFile.in",'=');
# Declare all the variables before initialising them with the data from input file.
A=0.0; B=0.0; C=0.0;
# Parsing
for i in 1:length(in[:,1])
if in[i,1] == "A"
A=in[i,2]
elseif in[i,1] == "B"
B=in[i,2]
elseif in[i,1] == "C"
C=in[i,2]
else
println(STDERR,in[i,1],"\tKeyword not recognised.")
exit()
end
end
This method is not scalable to large number of input variables. As you will notice, I want to read the variable names and initialise them to the value given in the input file.
Is there a more elegant/short way of doing this? I want to save the names of the variables in an array and use a for
loop to read them from the file.
Thank you for your help.
Upvotes: 4
Views: 1431
Reputation: 515
If the input file contains Julia code only, you can just include it:
include("inputFile.in")
println("A", A)
Depending on your workflow, it may be easier than using JLD, since your input file remains a single human-readable text file, rather than a binary file generated by a another text file.
The main con is that you cannot refer to the set of input variables programmatically, e.g. list them, check for existence, etc...
Upvotes: 1
Reputation: 4181
If you want to have your variables in a text file in the format you have them then this will work nicely (it just parse/eval's each line).
inputfile = readlines("inputFile.in")
eval.(parse.(inputfile))
I just realised this doesn't use a for loop, is that a requirement? if so then something like this would also be good:
open("inputFile.in", "r") do f
for line in eachline(f)
eval(parse(line))
end
end
But if you don't need to save your variables in a text file then the JLD package is the most convenient option & will be much more scale-able.
using JLD
A=1.0
B=1.0
C=2.0
@save "myfirstsave.jld" A B C
@load "myfirstsave.jld"
Upvotes: 1
Reputation: 2035
Maybe like this?
Basic approach
I'm going to read values from file config.txt
which contains the following
A=1.0
B = 2.1
C= 3.3
D =4.4
I do not want to hardcode what variables could be there, so I'm going to keep all of them in one Dict, like this:
julia> vars = Dict{String, Float64}()
Dict{String,Float64} with 0 entries
julia> f = open("config.txt")
IOStream(<file config.txt>)
julia> for line in eachline(f)
var, val = split(line, "=")
vars[strip(var)] = parse(Float64, val)
end
julia> vars
Dict{String,Float64} with 4 entries:
"B" => 2.1
"A" => 1.0
"C" => 3.3
"D" => 4.4
julia> vars["A"]
1.0
Reading only some variables
If you want to limit the set of variables which should be read, it's easy to do as well:
julia> vars = Dict{String, Float64}()
Dict{String,Float64} with 0 entries
julia> allowed = ["A", "B", "C"]
3-element Array{String,1}:
"A"
"B"
"C"
julia> f = open("config.txt")
IOStream(<file config.txt>)
julia> for line in eachline(f)
var, val = split(line, "=")
stripped = strip(var)
if stripped in allowed
vars[stripped] = parse(Float64, val)
end
end
julia> vars
Dict{String,Float64} with 3 entries:
"B" => 2.1
"A" => 1.0
"C" => 3.3
Now D=...
from config.txt
is ignored, as the name was not in allowed
.
Having variables as variables, not as Dict
One more approach would be:
function go(;A=0.0, B=0.0, C=0.0)
println("A = $A, B = $B, C = $C")
end
vars = Dict{Symbol, Float64}()
f = open("config.txt")
allowed = ["A", "B", "C"]
for line in eachline(f)
var, val = split(line, "=")
stripped = strip(var)
if stripped in allowed
vars[Symbol(stripped)] = parse(Float64, val)
end
end
go(;vars...)
Running this with the same config.txt
prints
A = 1.0, B = 2.1, C = 3.3
Upvotes: 4