chakolatemilk
chakolatemilk

Reputation: 883

Search for specific string, copy into text file, if not there, produce error

This is similar to a previous question I asked. But I've decided to make it a little bit more complex.

I'm making a program that can read a textfile and copy a specific portion of the textfile into another textfile. However, I want to produce error messages as well.

For example, my textfile looks like this:

* VERSION_1_1234
#* VERSION_2_1234
* VERSION_3_1234
#* VERSION_2_4321

So far, my program looks through the lines for "VERSION_2" and copies the line into another text file.

But now, I want it to search for "VERSION_3" and if it finds BOTH "VERSION_2" and "VERSION_3", it'll produce an error.

Here's what I have so far:

with open('versions.txt', 'r') as verFile:
    for line in verFile:
        # if pound sign, skip line
        if line.startswith('#'):
            continue
        # if version_3 there, copy
        if 'VERSION_3_' in line:
            with open('newfile.txt', 'w') as wFile:
            wFile.write(line.rpartition('* ')[-1])
        # if version_2 there, copy
        if 'VERSION_2_' in line:
            with open('newfile.txt', 'w') as wFile:
            wFile.write(line.rpartition('* ')[-1])
        # if both versions there, produce error
        if ('VERSION_3_' and 'VERSION_2_') in line:
            print ('There's an error, you have both versions in your text file')
        # if no versions there, produce error
        if not ('VERSION_3_' and 'VERSION_2_') in line:
            print ('There's an error, you don't have any of these versions in your text file')

Sorry if it looks a little cluttered. However, when I run the program, it works as is, but even when there's a VERSION_3 line, it'll print out the last two error messages. I don't understand why. There's something I'm doing wrong.

Please help.

Upvotes: 0

Views: 1296

Answers (2)

Briana
Briana

Reputation: 40

Ignoring syntax errors because Martijn did a lovely job clarifying that, you need some kind of logic to keep track of whether or not the text has been found in the file. Right now you're checking to see if both of them are in the same line, which is not what you said you wanted to do.

with open('versions.txt', 'r') as verFile, open('newfile.txt', 'w') as wFile:
    version2,version3 = '',''
    for line in verFile:
        # if pound sign, skip line
        if line.startswith('#'):
            continue
        # if version_2 there, store
        if 'VERSION_2_' in line:
            version2 = line
        # if version_3 there, store
        if 'VERSION_3_' in line:
            version3 = line
        # if both versions there, produce error and stop
        if version2 and version3:
            print "There's an error, you have both versions in your text file"
            break
    else:
    # write out found version
        if version2:
            wFile.write(version2.rpartition('* ')[-1])
        elif version3:
            wFile.write(version3.rpartition('* ')[-1])
        else:
            print "There's an error, you don't have any of these versions in your text     file"

If there are multiple finds for either of the versions, this will return the last one. If there's only one of each that doesn't matter, but if you need the first one, or want to return an error if you have multiple finds for the same version, you'll have to change it up a bit.

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121486

Your logic is flawed; ('VERSION_3_' and 'VERSION_2_') in line does not do what you think it does.

You want:

'VERSION_3_' in line and 'VERSION_2_' in line

instead. Similarly:

not ('VERSION_3_' and 'VERSION_2_') in line

should be:

'VERSION_3_' not in line and 'VERSION_2_' not in line

The expression ('VERSION_3_' and 'VERSION_2_') in line instead can is interpreted as 'VERSION_2_' in line, because any non-empty string is considered True in a boolean context, so the 'VERSION_3_' and 'VERSION_2_' returns just 'VERSION_2_' as the and operator returns the second string, which is then tested against the in operator:

>>> bool('VERSION_3_' and 'VERSION_2_')
True
>>> 'VERSION_3_' and 'VERSION_2_'
'VERSION_2_'

I do suspect that your code will not work even with these fixes; you test one line at a time, and your input example has the VERSION_ strings on separate lines.

Upvotes: 5

Related Questions