Trying to modify text file with if statements

I have a text file that I am reading in, and based on certain conditions modifying specific lines and rewriting the file to a new text file. My present code mostly works but one of the elif statements seems to be simply ignored by Python as there are no run time errors. A MWE is as follows:

energy = .1
source = str('source  x y z energy=%f' %energy)
c = energy - 0.001
c_string = str("1010 %f %f" %(c, energy))


f = open("file.txt", "r+")
with open ("newfiletxti", 'w') as n:
    d = f.readlines()
    for line in d:
        if not line.startswith("source"):
            if not line.startswith("xyz"):
                n.write(line)
        elif line.startswith("source"):
            n.write(source + "\n")
        elif line.startswith("xyz"):
            n.write(c_string + "\n")
    n.truncate()
    n.close()

The code:

elif line.startswith("source"):
    n.write(source + "\n")

Works as expected where the line in the text file is replaced with the string titled "source" however the next block:

elif line.startswith("xyz"):
    n.write(c_string + "\n")

Has no effect. The new text file is simply missing the line that starts with xyz. My guess is my syntax for multiple elif statements is incorrect but I am uncertain as to why.

3 answers

  • answered 2018-01-11 20:38 DaLord

    Try your if block like this:

        if line.startswith("source"):
            n.write(source + "\n")
        elif line.startswith("xyz"):
            n.write(c_string + "\n")
        else:
            n.write(line)
    

  • answered 2018-01-11 20:41 Gabe

    The third elif will never be reached. Here is the code reduced for clarity:

    if not line.startswith("source"):
    # suff
    elif line.startswith("xyz"):
    # stuff
    

    Something that starts with "xyz" does not start with "source".

  • answered 2018-01-11 21:45 Barmar

    The first if and elif handle all the cases -- either the line starts with source or it doesn't. I think you need to combine the first if and its nested if into a single condition:

    if not line.startswith("source") and not line.startswith("xyz"):
        n.write(line)
    

    or the equvivalent (by de Morgan's Laws):

    if not(line.startswith("source") or line.startswith("xyz")):
        n.write(line)
    

    Or you can make it clearer by reordering your conditions:

    if line.startswith("source"):
        n.write(source + "\n")
    elif line.startswith("xyz"):
        n.write(c_string + "\n")
    else:
        n.write(line)