-2

I need to write a function that takes a string only containing 'A' or 'C' or 'G' or 'T' and change these string according to my codes, otherwise it will return ''. I wrote these codes and my codes seems works fine, but whenever my function receives unsupported character it returns nothing when it is supposed to return ''.

def dna2rna(s):
    rna = []
    # if s.isupper() == False: #or [charr for charr in s if s != 'A' or 'C' or 'G' or 'T']:
        #return ''
    #else
    if [char for char in s]:
        for char in s:
            if char == 'A' or 'C' or 'G' or 'T' or ' ':
                if char == 'A':
                    rna.append('U')
                elif char == 'C':
                    rna.append('G')
                elif char == 'G':
                    rna.append('C')
                elif char == 'T':
                    rna.append('A')
        print ''.join(rna)
    else:
        return ''


print dna2rna('cs5')
  • 4
    `if char == 'A' or 'C' or 'G' or 'T' or ' ':` simply won't work the way you want. – ZdaR Jul 06 '15 at 14:04
  • Seems like the code can be condensed quite a bit. What is the expected input and output example? – taesu Jul 06 '15 at 14:07
  • 2
    Why do you even have the `if char == …`? If you really what to use this outer check, then use `if char in "ACGT":`. That's the beauty of Python. :-) Also look up the built-in function `filter`. – Kijewski Jul 06 '15 at 14:07
  • 1
    Your code won't work fine; see [How do I test one variable against multiple values?](https://stackoverflow.com/questions/15112125/how-do-i-test-one-variable-against-multiple-values). – Martijn Pieters Jul 06 '15 at 14:09
  • 1
    I don't know why you'd think for a moment that your code would work at all. For one thing, the `if` block `print`s but the `else` block `return`s, and `if [char for char in s]:` is just `if s:`. Get a [rubber duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging), and explain the function to it line by line. – jonrsharpe Jul 06 '15 at 14:09
  • 2
    Somewhat off topic, but "I didn't know RNA had thymine!" (I suspect you want uracil) – NightShadeQueen Jul 06 '15 at 14:09
  • Do you want an empty string if there's any invalid characters, invalid characters ignored or spaces in the place of invalid characters? – SuperBiasedMan Jul 06 '15 at 14:16
  • @SuperBiasedMan,Yes. If characters other than 'A','C','G' and 'T' are found then function will return an empty string but if spaces are found with valid characters then it is okay, spaces will be ignored. –  Jul 06 '15 at 14:19
  • it is the way i am instructed to solve problems. @NightShadeQueen –  Jul 06 '15 at 14:23
  • Your workflow involves making an incorrect DNA->RNA function. Let me hope that I never run into your institution. – NightShadeQueen Jul 06 '15 at 14:43
  • edited the question. Now it seems fine. Stupid me. –  Jul 06 '15 at 14:48

4 Answers4

2

A mapping (aka a dictionary) is probably what you want?

def dna2rna(s):
    mapping = {'A': 'U', #RNA has uracil. Not thymine.
               'T': 'A',
               'C': 'G',
               'G': 'C',
              }
    out = []
    for i in s.replace(' ',''): #get rid of spaces
    #if you have tabs and newlines, you may have to regex this instead
    #if you want to just ignore spaces, add them to the mapping and get
    #rid of the .replace(' ','')
         if i in mapping: 
              out.append(mapping[i])
         else: # invalid input
              return ''
    return ''.join(out)
NightShadeQueen
  • 3,284
  • 3
  • 24
  • 37
  • There's no real need to make out a list. It can be a string that you concatenate each character onto. – SuperBiasedMan Jul 06 '15 at 14:27
  • And create a new string object each time? Ew. If I'm mutating, I'm going with a mutable type. – NightShadeQueen Jul 06 '15 at 14:29
  • 2
    But more seriously, list => O(n). string => O(n^2) (because you have to create a new list object each time.) See: https://wiki.python.org/moin/TimeComplexity – NightShadeQueen Jul 06 '15 at 14:31
  • True! I was assuming that sequences would be short, but I know nothing of bioinformatics so I shouldn't be assuming. – SuperBiasedMan Jul 06 '15 at 14:32
  • @NightShadeQueen, seems your function still can not return when invalid characters are found. Thank you for let me know the new approach to handle this problem. –  Jul 06 '15 at 14:52
0

Like so?

def dna2ran(s):
    rna = []
    dictRNA = {
        'A' : 'T',
        'C' : 'G',
        'G' : 'C',
        'T' : 'A'
    }

    for x in s:
        if x in dictRNA:
            rna.append(dictRNA[x])
        else:
            return ''

    return ''.join(rna)

    print(dna2ran("AHUFBNUWBTT"))
Pobe
  • 364
  • 3
  • 13
0

rna is never returned, there is only print ''.join(rna) the only return is return ''

In python, strings can be iterated like: char for char in string

  • The first if statementif [char for char in s]: is not needed.

If you are worried a string is not a dna sequence you could create an exception when a not supported character is found.

I'd recommend changing:

  • if char == 'A' or 'C' or 'G' or 'T' or ' ':
  • to if char in ['A', 'C', 'G', 'T', ' ']:

If you want it to be case insensitive use char.upper()

Seth
  • 446
  • 5
  • 10
-1

Have a look at my changes, The code checks if char is in dna list. if so continue. if not put " " in rna list.

Hope this helps.

def dna2rna(s):
    dna = ['A','C','G','T']
    rna = []
    # if s.isupper() == False: #or [charr for charr in s if s != 'A' or 'C' or 'G' or 'T']:
        #return ''
    #else
    if [char for char in s]:
        for char in s:
            if char in dna:
                if char == 'A':
                    rna.append('T')
                elif char == 'C':
                    rna.append('G')
                elif char == 'G':
                    rna.append('C')
                elif char == 'T':
                    rna.append('A')
            else :
                rna.append(" ")
        print ''.join(rna)
    else:
        return ' '

dna2rna('ACKG')