patternpythonMinor
Energy curve plotter
Viewed 0 times
plottercurveenergy
Problem
I am not much experienced in Python, just write some small script. All my codes are procedural. They work fine, and I always check them with
One of them is:
```
#!/usr/bin/python3
import os
import sys
import numpy as np
import scipy as sp
import scipy.optimize
import matplotlib.pyplot as plt
def f(x, a, b, c, d):
return a + bx + cx2 + d*x3
data = []
fout = "tmpft" # sys.argv[1] + "_trial.dat"
with open(fout, "w") as of:
for subdir, dirs, files in os.walk(sys.argv[1]):
for inp in files:
if inp.endswith("SCF.out"):
fsys = subdir + "/" + inp
# print(fsys)
with open(fsys) as finp:
for line in finp:
if "lattice constant ALAT" in line:
lata = float(line.strip()[-7:])/1.88973
if " ERR " in line:
mom = line.strip()[61:70]
if "SCF - cycle converged" in line:
etot = float(line.lstrip()[10:25])
of.write("{:<10f} {:<15f} {:<15f}\n"
.format(lata, etot, float(mom)))
ffout = sys.argv[1]+".dat"
with open(ffout, "w") as ff:
ff.write("#lat(A) ETOT MOM\n")
with open(fout, "r") as uns:
for line in sorted(uns):
ff.write(line)
values = np.genfromtxt(fout, dtype=None, delimiter=' ', usecols=[0, 1, 2])
os.remove(fout)
etot = values[:, 1]
latp = values[:, 0]
popt, pcov = sp.optimize.curve_fit(f, latp, etot)
res = sp.optimize.minimize(lambda x: f(x, *popt), 2.8)
print('Function is minimized for {0}.'.format(float(res['x'])))
with open(ffout, 'a') as ff:
ff.write('#Function is minimized for {0}\n'.format(float(res['x'])))
# Plot data
pout = sys.argv[1]+".png"
x = sp.linspace(2.80, 3.05, 100)
y = f(x, *popt)
plt.plot(x, y, lw=3)
plt.xlabel("Lattice Parameter")
plt.ylabel("Energy")
plt.title(sys.argv[1])
plt.
pep8.One of them is:
```
#!/usr/bin/python3
import os
import sys
import numpy as np
import scipy as sp
import scipy.optimize
import matplotlib.pyplot as plt
def f(x, a, b, c, d):
return a + bx + cx2 + d*x3
data = []
fout = "tmpft" # sys.argv[1] + "_trial.dat"
with open(fout, "w") as of:
for subdir, dirs, files in os.walk(sys.argv[1]):
for inp in files:
if inp.endswith("SCF.out"):
fsys = subdir + "/" + inp
# print(fsys)
with open(fsys) as finp:
for line in finp:
if "lattice constant ALAT" in line:
lata = float(line.strip()[-7:])/1.88973
if " ERR " in line:
mom = line.strip()[61:70]
if "SCF - cycle converged" in line:
etot = float(line.lstrip()[10:25])
of.write("{:<10f} {:<15f} {:<15f}\n"
.format(lata, etot, float(mom)))
ffout = sys.argv[1]+".dat"
with open(ffout, "w") as ff:
ff.write("#lat(A) ETOT MOM\n")
with open(fout, "r") as uns:
for line in sorted(uns):
ff.write(line)
values = np.genfromtxt(fout, dtype=None, delimiter=' ', usecols=[0, 1, 2])
os.remove(fout)
etot = values[:, 1]
latp = values[:, 0]
popt, pcov = sp.optimize.curve_fit(f, latp, etot)
res = sp.optimize.minimize(lambda x: f(x, *popt), 2.8)
print('Function is minimized for {0}.'.format(float(res['x'])))
with open(ffout, 'a') as ff:
ff.write('#Function is minimized for {0}\n'.format(float(res['x'])))
# Plot data
pout = sys.argv[1]+".png"
x = sp.linspace(2.80, 3.05, 100)
y = f(x, *popt)
plt.plot(x, y, lw=3)
plt.xlabel("Lattice Parameter")
plt.ylabel("Energy")
plt.title(sys.argv[1])
plt.
Solution
"Better" is obviously fairly subjective. After a quick glance I would like to make a few suggestions:
scipy.optimize separately. You can either limit the importing by just
importing the (sub)modules you need, which is cleaner. Or you can
import the entire module and just use what you need.
Right now pep8 only checks that your lines aren't too long. I would concentrate a little more on making sure someone who didn't write the code (or you in a few months) can read what it's doing based on the flow, comments where needed and the variable names.
- If you already imported scipy, you don't need to import
scipy.optimize separately. You can either limit the importing by just
importing the (sub)modules you need, which is cleaner. Or you can
import the entire module and just use what you need.
- Especially in terms of usability and readability for later (especially rereading your own code), I would suggest adding some docstring to describe what it does: https://www.python.org/dev/peps/pep-0257/#id16
- Similarly I would use a clearer naming convention. The program won't run faster if you call it "energy_curve_calculator_function_using_curve_fit" or "f", but when you look into your files, you will know the difference.
- Lastly, I would also advise you add a comment block (or one line) between each section of code explaining what it does.
Right now pep8 only checks that your lines aren't too long. I would concentrate a little more on making sure someone who didn't write the code (or you in a few months) can read what it's doing based on the flow, comments where needed and the variable names.
Context
StackExchange Code Review Q#111905, answer score: 3
Revisions (0)
No revisions yet.