I have data that looks like the following (4-columns and tab-separated):
AAA 123 null 0
AAA 124 null 1
BBB 234 null 0
CCC 235 negative -2
CCC 345 negative 2
DDD 346 null -1
EEE 456 positive 4
EEE 457 positive 0
Using this data, I need to write a conditional statement where if the two conditions in Cols 3 and 4 are met, the word "TRUE" is printed in a 5th column, or if not, the word "FALSE" is printed.
Trying to nest "IF" statements using python, I have written the following code:
with open('infile.input', "r") as opened_file:
for gLine in opened_file:
print gLine
oneID, twoID, oneScore, twoScore = gLine.split()
if oneScore == "positive" and twoScore > 0:
if oneScore == "null" and twoScore == 0:
if oneScore == "neutral" and twoScore == 0:
if oneScore == "negative" and twoScore < 0:
print oneID, twoID, oneScore, twoScore, "TRUE"
else:
print oneID, twoID, oneScore, twoScore, "FALSE"
The result of this code is that "FALSE" is assigned to all of the lines, as follows:
AAA 123 null 0 FALSE
AAA 124 null 1 FALSE
BBB 234 null 0 FALSE
CCC 235 negative -2 FALSE
CCC 345 negative 2 FALSE
DDD 346 null -1 FALSE
EEE 456 positive 4 FALSE
EEE 457 positive 0 FALSE
. I have looked here and here for advice to solve the problem, and the code works with just one condition (for instance marking all of the 'positive' and 'x>0' correctly as TRUE). When I add more than one condition it fails to achieve my desired result, which is as follows:
AAA 123 null 0 TRUE
AAA 124 null 1 FALSE
BBB 234 null 0 TRUE
CCC 235 negative -2 TRUE
CCC 345 negative 2 FALSE
DDD 346 null -1 FALSE
EEE 456 positive 4 TRUE
EEE 457 positive 0 FALSE
Using the suggestion below, I have tried to implement this, which only correctly finds the cases of the first condition. All of the other conditions regardless if they are true or not are marked false. How can I make it to recognize all 4 of the conditions?
if ((oneScore == "positive" and twoScore > 0) or
(oneScore == "null" and twoScore == 0) or
(oneScore == "neutral" and twoScore == 0) or
(oneScore == "negative" and twoScore < 0)):
print oneID, twoID, oneScore, twoScore, "TRUE"
else:
print oneScore, twoScore, "FALSE"
4 Answers 4
It sounds like you want or, rather than nested if statements. It's never going to be possible for all of the conditions you're testing to be true simultaneously, so the nested ifs (which work like and in this context) will never all be passed letting your code print True.
Try:
if ((oneScore == "positive" and twoScore > 0) or
(oneScore == "null" and twoScore == 0) or
(oneScore == "neutral" and twoScore == 0) or
(oneScore == "negative" and twoScore < 0)):
print bookID, ID, oneScore, twoScore, "TRUE"
You're still going to have an issue with the comparisons for twoScore, as it's going to be a string, after you split the line you read from the file. You need to call int on it at some point before you do the comparisons.
2 Comments
or conditions seems to only work for the 1st condition. Meaning that when implementing this proposal, it marks TRUE for the first condition when the criteria is met and FALSE for everything else (regardless if it is truly false or not.) See edit in question.intTwoScore = int(twoScore) and replaced all of the twoScore in the logic for intTwoScore and it worked like a charm.What about something like:
twoScore = int(twoScore)
cases = [
oneScore == "positive" and twoScore > 0,
oneScore == "null" and twoScore == 0,
oneScore == "neutral" and twoScore == 0,
oneScore == "negative" and twoScore < 0
]
state = any(cases) and "TRUE" or "FALSE"
It should separate your data from your logic and ease the maintenance of your code.
Comments
You should use if-elif instead of nested if, From your code, it never print 'TRUE'
The correct logic should be something like this
if oneScore == 'positive' and int(twoScore) > 0:
print bookID, ID, oneScore, twoScore, "TRUE"
elif (oneScore == 'neutral' or oneScore == 'null') and int(twoScore) == 0:
print bookID, ID, oneScore, twoScore, "TRUE"
elif oneScore == 'negative' and int(twoScore) < 0:
print bookID, ID, oneScore, twoScore, "TRUE"
else:
print bookID, ID, oneScore, twoScore, "FALSE"
2 Comments
How about this:
print bookID, ID, oneScore, twoScore, (oneScore == "positive" and twoScore > 0) \
or (oneScore == "null" and twoScore == 0) \
or (oneScore == "negative" and twoScore < 0)
1 Comment
or on the next line. Either enclose everything in parenthesis or use a backslash as line continuation marker at the end of the line.Explore related questions
See similar questions with these tags.
if ... elif ...?oneScore == "positive"oneScore == "null"cant be trueif (a and b) or (c and d) or ...