Using meta.parse
and eval
for variable names means your editor can’t know you’re accessing the variables. It’s also a big code smell, much better to stay inside Julia if possible.
(Also, can I interest you in Unitful
, so you don’t have to check if the use supplies Ångström or not?)
Welcome to discourse and wonder no more by reading the guidelines to better post questions here.
NB: and hi to you too.
Thanks for your reply. I would like to use Unitful to customize the unit convertion part in my program. However, it seems even I remove the mate programming part. This error seems to be still there.
What editor are you using? And could you maybe show your current code (or ideally a shortened version)?
Look’s like a bug. Can you share your code in a copyable form?
Sorry for my late reply. I have tried some ways to solve this problem but the outcome turns out to be very baffling.
I simplify the meta programming part as follow:
using Printf
real_a = [2.7605462334516533, 0.0, 0.0]
real_b = [5.0000000000000000, 0.0, 0.0]
# true
@printf "Real Space Axis %s: %20.10f %20.10f %20.10f\n" string(:real_a)[end] eval(:real_a)[1] eval(:real_a)[2] eval(:real_a)[3]
# true
n = :real_a
@printf "Real Space Axis %s: %20.10f %20.10f %20.10f\n" string(n)[end] eval(n)[1] eval(n)[2] eval(n)[3]
for n in (:real_a, :real_b)
@printf "Real Space Axis %s: %20.10f %20.10f %20.10f\n" string(n)[end] eval(n)[1] eval(n)[2] eval(n)[3]
end
and it works well.
This makes me think that maybe it’s not the meta programming part’s problem. Because at the former part , the situation has already gotten strange.
It seems that I have done something not lawful since I open the input file. I can’t figure it out.
The code is attached.
function In( InFile :: String = "adphonon.in" )
@printf "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INPUT INFORMATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
@warn "Input Must be Carefully Checked. Our Journey Begins Here."
tags = keys(InTags)
open(InFile) do f
keys = []; values = []
lines = strip.(readlines(f))
lines = [ line for line in lines if !startswith(line, "#") && length(line)!=0]
for line in lines
ls = split(line)
temptag = ls[1]; tempvalue = ls[3]
if temptag ∈ tags
typ = InTags[temptag]
try
tempvalue = Convert(typ, tempvalue)
catch
exit()
end
push!(keys, temptag)
push!(values, tempvalue)
end
end
return Dict(zip(keys,values))
end
end
function StructureIn( InFile :: String = "structure.in" )
open(InFile) do f
lines = [x for x in strip.(readlines(f)) if length(x) != 0 ]
if lines[1] ∉ ("Ang", "A")
error("Line 1 is not lawful\nJob Stops Here.")
exit()
else
RealUnit = "Angstrom"
end
real_a = parse.(Float64,split(lines[2]))
real_b = parse.(Float64,split(lines[3]))
real_c = parse.(Float64,split(lines[4]))
@printf
# println(real_a)
# # @printf "Real Space Axis %s: %20.10f %20.10f %20.10f\n" string(:real_a)[end] eval(:real_a)[1] eval(:real_a)[2] eval(:real_a)[3]
# for n in (:real_a, :real_b, :real_c)
# println(eval(n))
# @printf "Real Space Axis %s: %20.10f %20.10f %20.10f\n" string(n)[end] eval(n)[1] eval(n)[2] eval(n)[3]
# end
@info "Generating Reciporcal Space Axis ..."
recip_a = 2 * π * LinearAlgebra.cross(real_b,real_c) / (dot(real_a, LinearAlgebra.cross(real_b,real_c)))
recip_b = 2 * π * LinearAlgebra.cross(real_c,real_a) / (dot(real_b, LinearAlgebra.cross(real_c,real_a)))
recip_c = 2 * π * LinearAlgebra.cross(real_a,real_b) / (dot(real_c, LinearAlgebra.cross(real_a,real_b)))
# for n in ["recip_a", "recip_b", "recip_c"]
# name = Meta.parse(n)
# @printf "Reciporcal Space Axis %s: %20.10f %20.10f %20.10f\n" n[end] eval(name)[1] eval(name)[2] eval(name)[3]
# end
@info "Getting Atoms' Positions"
positions = []; species = []; numbers = []
@printf "%2s %3s %15s %20s %20s\n" "ele" "ind" "a" "b" "c"
for (ii,line) in enumerate(lines[6:end])
specie = split(line)[1]; push!(species, specie)
position = parse.(Float64, split(line)[2:end])
@printf "%2s %3d %20.10f %20.10f %20.10f\n" specie ii position[1] position[2] position[3]
push!(positions, position)
end
unispecies = unique(species)
for spe in species
push!(numbers, findfirst(x->x==spe, unispecies))
end
return RealUnit, real_a, real_b, real_c, recip_a, recip_b, recip_c, numbers, positions
end
end
The code has been attached. Thanks!
Thanks for your response again and sorry for my slow reply. I’m from China, so it’s not so convenient to connect this forum.
Do you get an error, is it running poorly or is it a formatting thing? I don’t know what editor you’re using, and it’s definitely not the one I use, so if it’s a problem with the formatting I’m not sure I can help, at least not without a description of which part of it is wrong and what you’re expecting.
Actually, the julia says the variable is not defined.
Why
instead of simply
real_a[1]
?
I have three variables like real_a, real_b and real_c. So I try on writting it in a “for” loop using metaprogramming.
OK, but it still seems like the hard way of doing it. Beware that eval works in the global scope and you may get unintended side effects.
Oh, I think that is the root of my problem. Thanks for your advice.
Using a named tuple is probably a better approach.