devendra
devendra

Reputation: 175

Easier way to read input from a file

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

Answers (3)

mdavezac
mdavezac

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

Alexander Morley
Alexander Morley

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

avysk
avysk

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

Related Questions