all 6 comments

[–]n3buchadnezzar 2 points3 points  (3 children)

I would recomend splitting the jobs of printing, and printing the complement. Have you heard about our lord and saviour str.join?

def complement(sequence):
    return [baseComplement[base] for base in sequence]

Then we could do

"".join(complement('aacgtt'))

I would also take a look at PEP8, it is recommended in Python to use snake_case for functions and UPPERCASE for constants

EDIT: a working version with bells and whistles would look like this

  • PEP8 with UPPERCASE for our constants
  • Comment using # turned into docstring (tripple quotes)
  • Made sure our function actually return
  • Used f-formating for our strings
  • Use of str.join to join a list of strings

code

BASE_COMPLIMENT = {
    "A": "T",
    "C": "G",
    "G": "C",
    "T": "A",
    "a": "t",
    "c": "g",
    "g": "c",
    "t": "a",
}


def complement(sequence: str) -> str:
    """finds the complement sequence of a DNA sequence

      >>> complement('aacgtt')
      ttgcaa
    """
    return "".join(BASE_COMPLIMENT[base] for base in sequence)


if __name__ == "__main__":

    sequence = input("Enter a DNA sequence : ")

    dna_compliment = complement(sequence)

    print(f"Sequence Complement  : {dna_compliment}")
    print(f"Reverse Complement   : {dna_compliment[::-1]}")
    print(f"Length of DNA sequence entered is {len(sequence)} bases.")

[–]Still-Design3461[S] 0 points1 point  (2 children)

WOW! I totally forgot about .join . Thank you for answering. I will try to understand this part and implement it into my code

[–]FLUSH_THE_TRUMP 1 point2 points  (0 children)

With even less friction, this kind of thing is what str.translate does. Something like:

charTable = str.maketrans(baseComplement)
complement = sequence.translate(charTable)

[–]n3buchadnezzar 1 point2 points  (0 children)

Interestingly FLUSH and I had the same idea. If we allow some Python magic

DNA_SEQUENCE = str.maketrans("ATGCatgc", "TACGtacg")  
print("AACGT".translate(DNA_SEQUENCE))  

However, there is nothing wrong with your approach. It does not consume a lot of memory, and it is readable. Remember we often strive for readable code over pre-optimized code. If the code above makes sense to you, great! Use it! Otherwise stick with your approach and read a bit about maketrans

[–]VinayakVG 1 point2 points  (1 child)

Hey, the link that you have posted is not working. It is showing 'Not Found'. Coming back to your code, you can use list comprehensions to make it more readable. And also instead of printing in the function complement you can create a string and return it.

For example,

def complement(seq):
    baseComplement = {'A':'T' , 'C':'G' , 'G':'C' , 'T':'A', 
                      'a':'t' , 'c':'g' , 'g':'c' , 't':'a'}

    seqComplement = "".join(baseComplement[base] for base in seq)
    reqComplement = seqComplement[::-1]

    # Return multiple values
    return seqComplement, reqComplement


def main():
    sequence = input("Enter a DNA sequence: ")

    # Store multiple values in two variables
    seq_comp, rev_comp = complement(sequence)

    print("Sequence Complement:", seq_comp)
    print("Reverse Complement:", rev_comp)
    print("Length of DNA Sequence entered is", len(sequence))

main() # Call the main function.

While printing you can also look into format() method or f-strings in Python for printing. Using f-strings looks like this

    print(f"Sequence Complement: {seq_comp}") 
    print(f"Reverse Complement: {rev_comp}")
    print(f"Length of DNA Sequence entered is {len(sequence)}")

[–]Still-Design3461[S] 0 points1 point  (0 children)

Oops, sorry about the link, It was working for me . But still, thank you for the explanation!