Reputation: 883
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
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
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