0

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.

2
  • If not a terribly long file, why don't you read the entire file in as a list of lines, modify the lines you want to change within the array, then write the entire new array to the new file? Commented Jan 11, 2022 at 15:36
  • 1
    But the reason you are seeing the the behavior of only getting your last update, is you are rewriting your file for each pass of your inner loop. Commented Jan 11, 2022 at 15:38

1 Answer 1

1

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)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for your response, this worked perfectly, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.