I am still relatively new to Python but I have been actively doing sample examples to try and get used to problem solving aspect of programming.
With that said, I stumbled upon a question that asks you to write a code to convert DNA strand to its complementary form.
What I have written works, but I don't believe that my approach is efficient enough. Could you please review my code and guide me as to how I might improve on it? I feel like there will be a faster way than writing multiple if, elif statements.
import sys
def check_input(user_input):
if len(user_input) == 0:
sys.exit("No strand provided.")
return user_input
def complementary(strand):
complementary_strand = ''
for dna in strand:
if dna == 'A':
complementary_strand += 'T'
elif dna == 'a':
complementary_strand += 't'
elif dna == 'T':
complementary_strand += 'A'
elif dna == 't':
complementary_strand += 'a'
elif dna == 'G':
complementary_strand += 'C'
elif dna == 'g':
complementary_strand += 'c'
elif dna == 'C':
complementary_strand += 'G'
elif dna == 'c':
complementary_strand += 'g'
else:
complementary_strand += 'x'
return complementary_strand
if __name__ == "__main__":
user_input = input("Enter strand: ")
print()
strand = check_input(user_input)
complementary_strand = complementary(strand)
print("Complementary strand is {}".format(complementary_strand))
2 Answers 2
Typically, a character-for-character replacement is best done using str.translate()
:
strand.translate(str.maketrans('AaTtGgCc', 'TtAaCcGg'))
However, your situation is trickier, because you also want to map all invalid characters to 'x'
. To achieve that, you would need to read the str.maketrans()
documentation carefully, and figure out that you can wrap the mapping in a collections.defaultdict
.
from collections import defaultdict
DNA_COMPLEMENTS = defaultdict(lambda: 'x', str.maketrans('AaTtGgCc', 'TtAaCcGg'))
def complementary(strand):
return strand.translate(DNA_COMPLEMENTS)
Note that lambda: 'x'
is a way to make a function that, when called with no parameters, returns the letter 'x'
.
I know this is old, but considering the amount of views it gets (and I also looked it up now) thought I'd also add.
Couldn't you just use a dictionary, and convert all letters to upper (this way you don't have to import anything either)?
DNA_complement_dict={'A':'T',
'T':'A',
'G':'C',
'C':'G'
def check_input(user_input):
if len(user_input) == 0:
sys.exit("No strand provided.")
return user_input.upper()
def complementary(strand):
complementary_strand = ''
for dna in strand:
try:
complementary_strand += DNA_complement_dict[dna]
except:
complementary_strand += 'X'
return complementary strand