以读取的相同格式写入已解析的文件

时间:2019-05-04 12:38:00

标签: python-3.x text-parsing

我正在做什么的一些概述:我正在读取并解析具有非常特定格式的.cube文件,然后我想对解析后的数据进行一些操作,并以相同格式写出新文件。 / p>

我正在解析的文件如下:

apollo: {
    search: { 
        query: () => contactSearchGQL,
        variables() { 
            return { 
                searchText: this.searchText, 
            };
        },
        debounce: 300,
        update(data) { 
            console.log("received data: " + JSON.stringify(data));
        },
        result({ data, loading, networkStatus }) {
            console.log("We got some result!")
        },
        error(error) {
            console.error('We\'ve got an error!', error)
        },
        prefetch() { 
            console.log("contact search, in prefetch");
            if ( this.searchText == null ) return false;
            return true;
        },
    },
},

出于问题的考虑,内容并不是很重要。

阅读后,我试图按原样写入文件,以便与“ diff”进行比较,以确保即时保持格式不变。我在执行过程中遇到了一些麻烦,因此我写文件的代码是(我用格式值播放但没有运气):

 OT-RSH
 Total Density
   12   -9.448633   -9.448633   -3.779453
  101    0.188973    0.000000    0.000000
  101    0.000000    0.188973    0.000000
   41    0.000000    0.000000    0.188973
    6    6.000000   -1.869343    1.869343    0.000000
    6    6.000000    0.684227    2.553571    0.000000
    6    6.000000    2.553571    0.684227    0.000000
    6    6.000000    1.869343   -1.869343    0.000000
    6    6.000000   -0.684227   -2.553571    0.000000
    6    6.000000   -2.553571   -0.684227    0.000000
    1    1.000000   -3.340623    3.340623    0.000000
    1    1.000000    1.222753    4.563376    0.000000
    1    1.000000    4.563376    1.222753    0.000000
    1    1.000000    3.340623   -3.340623    0.000000
    1    1.000000   -1.222753   -4.563376    0.000000
    1    1.000000   -4.563376   -1.222753    0.000000
  0.43578E-08  0.48992E-08  0.54452E-08  0.59816E-08  0.64918E-08  0.69577E-08
  0.73600E-08  0.76792E-08  0.78964E-08  0.79941E-08  0.79570E-08  0.77736E-08
  0.74361E-08  0.69419E-08  0.62937E-08  0.54998E-08  0.45742E-08  0.35359E-08

产生以下输出:

        with open(file_name, 'w') as output_file:
            for line_num in range(6 + self.num_atoms):
                if line_num == 0 or line_num == 1:
                    # comment line
                    output_file.write("{:s}".format(self.comments[line_num]))
                if line_num == 2:
                    # number of total atoms, and the origin coordinates
                    output_file.write("{:4d} {:5.6f} {:5.6f} {:5.6f}\n".format(self.num_atoms, *self.origin))
                if line_num == 3:
                    # number of x grid points and step size in x,y,z
                    output_file.write("{:4d} {:.6f} {:.6f} {:.6f}\n".format(self.num_x, *self.x))
                if line_num == 4:
                    # number of y grid points and step size in x,y,z
                    output_file.write("{:4d} {:.6f} {:.6f} {:.6f}\n".format(self.num_y, *self.y))
                if line_num == 5:
                    # number of z grid points and step size in x,y,z
                    output_file.write("{:4d} {:.6f} {:.6f} {:.6f}\n".format(self.num_z, *self.z))
                if line_num in range(6, 6 + self.num_atoms):
                    # atomic number, charge and coordinates of the atom
                    output_file.write("{:4d}\t{:.6f} {:.6f} {:.6f} {:.6f}\n".format(self.atoms[line_num - 6],
                                                                                   self.atoms_charge[line_num - 6],
                                                                                   *self.atoms_xyz[line_num - 6]))
            # the calculated quantity
            for idx_x in range(self.num_x):
                for idx_y in range(self.num_y):
                    for idx_z in range(self.num_z):
                        output_file.write("{:4e} ".format(self.calc_data[idx_x, idx_y, idx_z]))
                        if (np.mod(idx_z, 6) == 5): output_file.write("\n")
                    output_file.write("\n")
        output_file.close()

可以看到数据几乎相同,但是我在试图避免的行中进行了移动,最后一行的打印是X.XXXE-09而不是0.XXXE-08

不胜感激一些格式正确的帮助

谢谢

1 个答案:

答案 0 :(得分:0)

我无法找到您想要的一种格式化打印方式。但是,我能做的最一般的方法如下:

首先,该函数将浮点数格式化为+ -0.XXXE-Y:

def formatFloat(float_num):
    """
        Format a float to be in the form 0.XXXX-E(Y-1) instead of X.XXXX-E(Y)
    """
    zero_pad = ['','','0','00','000','0000','00000','000000','0000000','00000000']
    neg_float_len = 12
    pos_float_len = 11
    if float_num == 0.0:
        return "0.00000E+00"

    neg_flag = True if (float_num < 0 ) else False
    float_str = f"{float_num:.8n}"
    original_exp=np.int(np.abs(np.floor(np.log10(np.abs(float_num)))))
    exp_str = "e-0{:d}".format(original_exp)
    desired_exp_str = "E+0{:d}".format(original_exp-1) if original_exp == 1 else "E-0{:d}".format(original_exp-1)
    if original_exp <= 4:
        float_str = float_str.replace("0","",original_exp)
        if neg_flag:
            float_str = float_str.replace("-", "-0") + exp_str
            float_str = float_str.replace(exp_str,
                                          "{:s}{:s}".format(zero_pad[neg_float_len-len(float_str)+1],exp_str))
        else:
            float_str = float_str.replace(".", "0.") + exp_str
            float_str = float_str.replace(exp_str,
                                          "{:s}{:s}".format(zero_pad[pos_float_len - len(float_str)+1], exp_str))
    else:
        if neg_flag:

            if float_str[2] == "." and float_str.endswith(exp_str):
                float_str = float_str.replace("-", "", 1)
                float_str = "-0." + float_str.replace(".", "").replace(exp_str,
                                                                       "{:s}{:s}".format(zero_pad[neg_float_len-len(float_str)-1],exp_str))
            elif not float_str[2] == "." and float_str.endswith(exp_str):
                float_str = float_str.replace("-", "", 1)
                float_str = "-0." + float_str.replace(exp_str,"{:s}{:s}".format(zero_pad[neg_float_len - len(float_str) - 2], exp_str))
        else:
            if float_str[1] == "." and float_str.endswith(exp_str):
                float_str = "0." + float_str.replace(".","").replace(exp_str,
                                                                     "{:s}{:s}".format(zero_pad[pos_float_len-len(float_str)],exp_str))
            elif not float_str[1] == "." and float_str.endswith(exp_str):
                float_str = "0."+float_str.replace(exp_str,"{:s}{:s}".format(zero_pad[pos_float_len - len(float_str)-1],exp_str))

    float_str = float_str.replace(exp_str, desired_exp_str)
    return float_str

具有以下功能后,您可以将代码更改为:

    with open(file_name, 'w') as output_file:
        for line_num in range(6 + self.num_atoms):
            if line_num == 0 or line_num == 1:
                # comment line
                output_file.write("{:s}".format(self.comments[line_num]))
            if line_num == 2:
                # number of total atoms, and the origin coordinates
                output_file.write("{:5d}".format(self.num_atoms))
                for i in range(3):
                    if self.origin[i] < 0:
                        output_file.write("   {:.6f}".format(self.origin[i]))
                    else:
                        output_file.write("    {:.6f}".format(self.origin[i]))
                output_file.write("\n")
                # output_file.write("{:4d} {:5.6f} {:5.6f} {:5.6f}\n".format(self.num_atoms, *self.origin))
            if line_num == 3:
                # number of x grid points and step size in x,y,z
                output_file.write("{:5d}".format(self.num_x))
                for i in range(3):
                    if self.x[i] < 0:
                        output_file.write("   {:.6f}".format(self.x[i]))
                    else:
                        output_file.write("    {:.6f}".format(self.x[i]))
                output_file.write("\n")
                # output_file.write("{:4d} {:.6f} {:.6f} {:.6f}\n".format(self.num_x, *self.x))
            if line_num == 4:
                # number of y grid points and step size in x,y,z
                output_file.write("{:5d}".format(self.num_y))
                for i in range(3):
                    if self.y[i] < 0:
                        output_file.write("   {:.6f}".format(self.y[i]))
                    else:
                        output_file.write("    {:.6f}".format(self.y[i]))
                output_file.write("\n")
                # output_file.write("{:4d} {:.6f} {:.6f} {:.6f}\n".format(self.num_y, *self.y))
            if line_num == 5:
                # number of z grid points and step size in x,y,z
                output_file.write("{:5d}".format(self.num_z))
                for i in range(3):
                    if self.z[i] < 0:
                        output_file.write("   {:.6f}".format(self.z[i]))
                    else:
                        output_file.write("    {:.6f}".format(self.z[i]))
                output_file.write("\n")
                # output_file.write("{:4d} {:.6f} {:.6f} {:.6f}\n".format(self.num_z, *self.z))
            if line_num in range(6, 6 + self.num_atoms):
                # atomic number, charge and coordinates of the atom
                output_file.write("{:5d}".format(self.atoms[line_num - 6]))
                if self.atoms_charge[line_num - 6] < 0:
                    output_file.write("   {:.6f}".format(self.atoms[line_num - 6]))
                else:
                    output_file.write("    {:.6f}".format(self.atoms[line_num - 6]))
                temp = self.atoms_xyz[line_num - 6]
                for i in range(3):
                    if temp[i] < 0:
                        output_file.write("   {:.6f}".format(temp[i]))
                    else:
                        output_file.write("    {:.6f}".format(temp[i]))
                output_file.write("\n")
                # output_file.write("{:4d}\t{:.6f} {:.6f} {:.6f} {:.6f}\n".format(self.atoms[line_num - 6],
                #                                                                self.atoms_charge[line_num - 6],
                #                                                                *self.atoms_xyz[line_num - 6]))
        # the calculated quantity
        for idx_x in range(self.num_x):
            for idx_y in range(self.num_y):
                for idx_z in range(self.num_z):
                    if (self.calc_data[idx_x, idx_y, idx_z] < 0):
                        output_file.write(" {:s}".format(formatFloat(self.calc_data[idx_x, idx_y, idx_z])))
                    else:
                        output_file.write("  {:s}".format(formatFloat(self.calc_data[idx_x, idx_y, idx_z])))
                    if (np.mod(idx_z, 6) == 5): output_file.write("\n")
                output_file.write("\n")
    output_file.close()

这将产生所需的输出