2

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"
Community
  • 1
  • 1
owwoow14
  • 1,694
  • 8
  • 28
  • 43

4 Answers4

5

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.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • Using the `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. – owwoow14 Sep 09 '15 at 15:18
  • Sorry, I did not finish reading everything. I made another variable `intTwoScore` = int(twoScore) and replaced all of the `twoScore` in the logic for `intTwoScore` and it worked like a charm. – owwoow14 Sep 09 '15 at 15:46
0

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)
user2804197
  • 354
  • 5
  • 13
  • 2
    This is illegal pyhton syntax, you can't simply continue with `or` on the next line. Either enclose everything in parenthesis or use a backslash as line continuation marker at the end of the line. – mata Sep 09 '15 at 13:54
0

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"
  • A solution like this results in the same issues that I mentioned in the edited question and updated code. See above. – owwoow14 Sep 09 '15 at 15:21
  • 1
    I just notice that 'twoScore' is not an integer. That's why it mess up with the condition evaluation. I think you have to put "int(twoScore)" in the condition too. – Prawit Chaivong Sep 09 '15 at 16:35
0

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.

Jordi Riera
  • 101
  • 1
  • 5