Ends-with and Starts-with in if statements: Python 3

13.9k Views Asked by At

I am new to python and I have to create a program that validates a DNA sequence. (background on DNA sequences really quick) in order to be valid: • The number of characters is divisible by 3 • The first 3 characters are ATG • The last 3 characters are TAA, TAG, or TGA.

my problem comes in with using Boolean terms in an if statement.

        endswith=(DNA.endswith("TAA"))
endswith2=(DNA.endswith("TAG"))
endswith3=(DNA.endswith("TGA"))
if length%3==0 and startswith==true and endswith==true or endswith2==true or endswith3==true:
    return ("true")

this code returns the error of: global name 'true' is not defined

How do I fix this, and also just on a last note I am really sorry. The answer to this question is probably SO stupidly simple that in your mind a 2 year old could code it :/ I did research around but I had no luck at all. So I thank you for taking your time to even read my stupid question.

5

There are 5 best solutions below

0
On

In python, true is not a keyword but True.

And in python you don't have to compare a variable with True obviously, just use

if length%3==0 and startswith and endswith or endswith2 or endswith3:
1
On

type: true --> True

you'd better refer to manual before you ask question.

Actually, you can use this:

if length%3 and startswith and endswith or ...

no need to write

if ... startswith == True ...
0
On

Use True, not true. Also, instead of startswith==True, you can just use startswith (eg: if length%3==0 and startswith and endswith ...).

You should also add parentheses to make your logic more readable. Even though precedence is well documented, many people don't know it. And even when they do, they can't tell if you do or not.

if (length%3==0 and (startswith and endswith) or endswith2 or endswith3):
0
On

Much easier:

return (len(DNA) % 3 == 0 and
        DNA.startswith("ATG") and
        DNA.endswith(("TAA", "TAG", "TGA")))

Comparing a boolean value to True or False is almost always redundant, so whenever you find yourself doing that ... do something else ;-)

5
On

First thing: it's True not true.

Second thing: don't say endswith == True, just say endswith.

Third thing: and has higher precedence than or, so what you've written is equivalent to:

(length%3==0 and startswith==true and endswith==true) or ...

which isn't what you meant.

Fourth thing: it's probably better to say:

if len(DNA) % 3 == 0 and DNA.startswith('ATG') and DNA[-3:] in ('TAA', 'TAG', 'TGA'):

As Tim points out, DNA.endswith(('TAA', 'TAG', 'TGA')) beats DNA[-3:] in .... It's simpler and without bothering to test, I'd expect it to be faster too. If you had a lot of permissible endings of equal length, and you were doing many tests, then it would be faster to construct a set once and do an in test of the end-slice. But three possibilities is not "a lot".