3

Transitions between A <-> G and C <-> T
Transversions between A <-> C and G <-> T

Assignment:

  • Write a function transition that takes two nucleotides. The function must return a Boolean value that indicates whether or not replacing the first nucleotide by the second nucleotide leads to a transition.

Problem: I don't think the function recognizes the statement behind the or. The code doesn't work in some cases for example: transition('A', 'G') is True and with my code he gives False

  • Write a function ratio that takes two DNA sequences s1 and s2
    The function may assume that both sequences have the same length (the function does not need to check this explicitly). The function must return the transition/transversion ratio R(s 1 ,s 2 )∈R of the two given sequences as a floating point number. In case there are no transversions between the two sequences, R(s 1 ,s 2 )=0 by definition.

Problem: the code is not working

def transition(letter1, letter2):        
    """
    >>> transition('G', 'A')
    True
    >>> transition('t', 'g')
    False
    >>> transition('C', 'c')
    False
    """    
    return True if letter1.lower() == 'gt' and letter2.lower() == 'ac' or letter1.lower() == 'ac' and letter2.lower() == 'gt' else False


def transversion(letter1, letter2):
    """
    >>> transversion('G', 'A')
    False
    >>> transversion('t', 'g')
    True
    >>> transversion('C', 'c')
    False
    """
    return True if letter1.lower() == 'ct' and letter2.lower() == 'ag' or  letter1.lower() == 'ag' and letter2.lower() == 'ct' else False


def ratio(seq1, seq2):
    """
    >>> ratio('ATTAGCATTATCATC', 'AAATAGGATATATGG')
    0.2222222222222222
    >>> seq1 = 'GCAACGCACAACGAAAACCCTTAGGGACTGGATTATTTCGTGATCGTTGTAGTTATTGGAAGTACGGGCATCAACCCAGTT'
    >>> seq2 = 'ttatctgacaaagaaagccgtcaacggctggataatttcgcgatcgtgctggttactggcggtacgagtgttcctttgggt'
    >>> ratio(seq1, seq2)   
    1.2142857142857142
    """
    count = 0
    tel = 0

    for i in range(len(seq1)):
        if transition(seq1[i], seq2[i]):
            count += 1

    for i in range(len(seq1)):
        if transversion(seq1[i], seq2[i]):
            tel += 1

    if tel != 0:
        return float(count / tel)
    else:
        return 0 

if __name__ == '__main__':
    import doctest
    doctest.testmod()
4
  • 3
    You already have a boolean result. Just return that rather than using True if expression else False. expression itself is already producing True or False in most cases. If not, use bool(expression), but only if you must have a boolean. if doesn't need a boolean, for example. Commented Oct 30, 2017 at 19:21
  • 'g' != 'gt'. == is "is this thing equal to this other thing", not "is this thing equal to part of this other thing". Commented Oct 30, 2017 at 19:28
  • letter1.lower() == "gt" should be letter1.lower() in "gt" Commented Oct 30, 2017 at 19:51
  • @Lien please upvote and accept answer if it solved your problem. Thanks ;-) Commented Nov 8, 2017 at 10:12

4 Answers 4

2

Change the lines like this

return True if letter1.lower() == 'gt' and letter2.lower() == 'ac' or letter1.lower() == 'ac' and letter2.lower() == 'gt' else False

by :

return (letter1.lower() == 'gt' and letter2.lower() == 'ac' or letter1.lower() == 'ac' and letter2.lower() == 'gt') 
Sign up to request clarification or add additional context in comments.

2 Comments

Ok but it gives still wrong results in some cases. I don't understand why.
He never returns True value only False
2

I think transition or transversion of same nucleobase must return False
( ie transition('A','A')==False )

You can simplify using simple naming predicat : https://repl.it/N4TC/4

def transition(nucleobase1, nucleobase2):        
   """ True if both are different and are purine
   """
   return (not isEqual(nucleobase1, nucleobase2) and
           isPurine(nucleobase1) and 
           isPurine(nucleobase2))

def transversion(nucleobase1, nucleobase2):        
   """ True if both are different and not transition
   """
   return (not isEqual(nucleobase1, nucleobase2) and
           not transition(nucleobase1, nucleobase2))

Other predicat :

### nucleobase Predicat    

def isAdenine(nucleobase):
    """ True if adenine (A)
    """
    return nucleobase.lower()=='a'

def isCytosine(nucleobase):
    """ True if cytosine (C)
    """
    return nucleobase.lower()=='c'

def isGuanine(nucleobase):
    """ True if guanine (G)
    """
    return nucleobase.lower()=='g'

def isThymine(nucleobase):
    """ True if thymine (T)    
    """
    return nucleobase.lower()=='t'

def isPurine(nucleobase):
    """ True if adenine (A) or guanine (G)
    """
    return isAdenine(nucleobase) or isGuanine(nucleobase)

def isPyrimidine(nucleobase):
    """ True if cytosine (C) or thymine (T)
    """
    return isCytosine(nucleobase) or isThymine(nucleobase)

def isEqual(nucleobase1, nucleobase2):
    """ Equal ignore case
    """
    return nucleobase1.lower()==nucleobase2.lower()      

Comments

1

As a general rule of thumb you can if you have multiple conditions assign them to variables first. Might not be the answer you were looking for but possibly can help you write easier-to-read code.

Like this:

letter1 = "GT"
letter2 = "AC"

def transition(letter1, letter2):

    cond1 = (letter1.lower() == 'gt')
    cond2 = (letter2.lower() == 'ac')
    cond3 = (letter1.lower() == 'ac')
    cond4 = (letter2.lower() == 'gt')

    if (cond1 and cond2) or (cond3 and cond4):
        return True
    else:
        return False

transition(letter1,letter2)

Comments

0

Try this:

def transition(letter1, letter2):        
   """
   >>> transition('G', 'A')
   True
   >>> transition('t', 'g')
   False
   >>> transition('C', 'c')
   False
   """
   if letter1.lower() == letter2.lower():
       return False

   return (letter1.lower() in 'ag' and letter2.lower() in 'ag') or (letter1.lower() in 'ct' and letter2.lower() in 'ct')

and

def transversion(letter1, letter2):        
   """
   >>> transversion('G', 'A')
   False
   >>> transition('t', 'g')
   True
   >>> transition('C', 'c')
   False
   """
   if letter1.lower() == letter2.lower():
       return False

   return (letter1.lower() in 'ac' and letter2.lower() in 'ac') or (letter1.lower() in 'gt' and letter2.lower() in 'gt')

It seems with letter1.lower() == 'gt' you are trying to check if the letter is either g or t. You do that with in instead of ==.

1 Comment

@Lien You're welcome! If it solved your problem, please accept it as an answer! From the Help Center: "Please do not add a comment on your question or on an answer to say 'Thank you'. [...] If you want to say 'thank you,' vote on or accept that person's answer [...]."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.