Energy curve plotter 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 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 + b*x + c*x**2 + d*x**3

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("{:&lt;10f} {:&lt;15f} {:&lt;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.scatter(latp, etot, s=60)
plt.scatter(res['x'], f(res['x'], *popt), color='red', s=80)
plt.savefig(pout)
plt.show()


This works fine, i.e. gives me proper/correct result. But I wonder if this is a good way of writing Python. If I take this as my standard example (most of my Python interaction is like this: read a file, fetch some data, post-process it and plot), how I can make it better? By "better", I mean, optimized, reusable and readable.

Like, as I already said, most of my python involves reading a line that matched a string. So, I would like to have it as a function (in C/fortran sense) etc.
"Better" is obviously fairly subjective. After a quick glance I would like to make a few suggestions:


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.