AVK
AVK

Reputation: 23

How to change multiple lines in a file using Python

I am new to python. I am using python 3.9.6. I have a working code which goes to a file I want to modify and changes a specific value in a specific line within that file. The lines in the file look as follows: reaction('h + o2 <=> o + oh', [3.547000e+15, -0.406, 16599.0]), the numbers and reactions change for each line but this is a rough idea of what the data in the file looks like. The goal of y first code was to multiply the first value within the square brackets by a random number between 0.5 and 2. I made a list of values which refer to specific lines in the file I want to change. The lines are all stated in the list called lines_to_perturb. My first code worked exactly the way I wanted it to. It went to a specific line, generated a random number between 0.5 and 2, multiplied the first number in square brackets by this value, saved a new file with this new "modified" line, ran the calculations, then entered the loop again and did the same for the next line in the list. A part of the code can be seen below.

lines_to_perturb = [7406, 7409, 7749, 7752, 7755, 7758, 7761, 7764, 7767, 7770, 7773, 7827, 7830, 7988, 8049, 8052, 8062, 8065, 8850, 8853, 8856, 8859, 8862, 8865, 8868, 8871, 8874, 8877, 8880, 8883, 8886, 8889, 8892, 8895, 8898, 8901, 8904, 8907, 8910, 8913, 8916, 8919, 8922, 8925, 8928, 8931, 8934, 8937, 8940]

for j in range(len(lines_to_perturb)):
    print(lines_to_perturb[j])

    data = []
    with open("chem_clean.cti", "r") as f:
        data = f.readlines()
        print(data[lines_to_perturb[j]])

    random_float = numpy.random.uniform(0.5, 2, 1)
    print(random_float)

    with open("chem_clean.cti", "r")as f:   
        with open("chem_clean_perturbed.cti", 'w') as new_f:
            for i, line in enumerate(f,0):
                if i == (lines_to_perturb[j]):
                    num1 = re.search("\[(.*?),", line)[1]
                    num2 = random_float * float(num1)
                    num2 = float(num2)
                    new_line = line.replace(num1, str(num2))
                    new_f.write(new_line)
                    print(new_line)
                else:
                    new_f.writelines(line)

Now I want to modify this code. I want to be able to change all 48 lines in the list of lines_to_perturb by a random value (a different random value for each line) and save all these modified lines to ONE new file before continuing to the next steps in my code. The way the code is setup now, it saves the changes made for a specific line but when it enters the loop again to modify the next line, it only saves a new file with the last line in the list modified, all other lines are saved in the file as what they were originally. I believe it has to do with the fact that my code opens the original file "chem_clean.cti" each time it enters the loop again which contains all the original, non modified lines. Is there a way for me to still use this code and the loop to generate random numbers to be multiplied to each line in my file but save ONE file which includes all these modifications? I have tried different things, but have not been able to figure it out. Any help would be greatly appreciated. Thank you.

Upvotes: 0

Views: 475

Answers (1)

RufusVS
RufusVS

Reputation: 4137

Simplify your life with a single pass through the file:

with open("chem_clean.cti", "r")as f:   
    with open("chem_clean_perturbed.cti", 'w') as new_f:
        for i, line in enumerate(f):
            if i in lines_to_perturb:
                random_float = numpy.random.uniform(0.5, 2, 1)
                num1 = re.search("\[(.*?),", line)[1]
                num2 = random_float * float(num1)
                num2 = float(num2)
                new_line = line.replace(num1, str(num2))
                new_f.writeline(new_line)
                print(new_line)
            else:
                new_f.writeline(line)

(this code entered without testing. Forgive typos)

Upvotes: 1

Related Questions