You are on page 1of 4

DNA_PAIRS = (("A", "T"), ("G", "C"))

DNA_BASES = {"A": "Adenine", "T": "Thymine", "G": "Guanine", "C": "Cytosine"}

def is_valid_dna_sequence(a_dna):
"""
Checks if a given string is a valid DNA sequence,
it means it is not-empty and contains only DNA bases (case-insensitive).

:param a_dna: a DNA sequence to check


:param a_dna: str

:return: result of the check


:rtype: bool

Examples of True-cases:
>>> is_valid_dna_sequence("A")
True
>>> is_valid_dna_sequence("T")
True
>>> is_valid_dna_sequence("G")
True
>>> is_valid_dna_sequence("C")
True
>>> is_valid_dna_sequence("Adenine")
True
>>> is_valid_dna_sequence("Thymine")
True
>>> is_valid_dna_sequence("Guanine")
True
>>> is_valid_dna_sequence("Cytosine")
True
>>> is_valid_dna_sequence("a")
True
>>> is_valid_dna_sequence("t")
True
>>> is_valid_dna_sequence("g")
True
>>> is_valid_dna_sequence("c")
True
>>> is_valid_dna_sequence("adenine")
True
>>> is_valid_dna_sequence("thymine")
True
>>> is_valid_dna_sequence("guanine")
True
>>> is_valid_dna_sequence("cytosine")
True

Examples of False-cases:
>>> is_valid_dna_sequence(0) # more types could be added here
False
>>> is_valid_dna_sequence("")
False
>>> is_valid_dna_sequence("b")
False
>>> is_valid_dna_sequence(0.0)
False
>>> is_valid_dna_sequence(["A"])
False
>>> is_valid_dna_sequence(["C", "Cytosine"])
False
>>> is_valid_dna_sequence([""])
False
>>> is_valid_dna_sequence(("", ))
False
>>> is_valid_dna_sequence(("T", ))
False
>>> is_valid_dna_sequence(("T", "Thymine"))
False
>>> is_valid_dna_sequence({"G": "Guanine"})
False
>>> is_valid_dna_sequence({})
False
>>> is_valid_dna_sequence(None)
False
"""

for bases, bases_names in DNA_BASES.items():


if a_dna == bases or a_dna == bases_names:
return True
if a_dna == bases.lower() or a_dna == bases_names.lower():
return True
return False

def dna_base_content(a_dna):
"""
Counts occurrences of particular DNA bases.

:param a_dna: a correct DNA sequence


:type a_dna: str

:return: a counter of letters


:rtype: dict

Examples:
# if the below tests does not work because of different orders of expected and
got dictionaries
# rewrite it to the form of the remaining tests
>>> dna_base_content("a")
{'A': 1, 'T': 0, 'G': 0, 'C': 0}
>>> dna_base_content("t") == {'A': 0, 'T': 1, 'G': 0, 'C': 0}
True
>>> dna_base_content("g") == {'A': 0, 'T': 0, 'G': 1, 'C': 0}
True
>>> dna_base_content("c") == {'A': 0, 'T': 0, 'G': 0, 'C': 1}
True
>>> dna_base_content("accgggtttt") == {'A': 1, 'T': 4, 'G': 3, 'C': 2}
True

Only one check, the rest is in the is_valid_dna_sequence()


and we assume white box testing and thorough code maintenance
>>> dna_base_content("abc")
Traceback (most recent call last):
...
TypeError: Not correct DNA sequence: abc
"""
is_valid_dna_sequence(a_dna)

dna_bases_dictionary = dict()
for keys in DNA_BASES:
dna_bases_dictionary[keys] = 0

for letters in a_dna:


letters = letters.upper()
if letters in dna_bases_dictionary:
dna_bases_dictionary[letters] += 1
if letters not in DNA_BASES:
raise TypeError('Not correct DNA sequence: ' + a_dna)

return dna_bases_dictionary

def print_dna_base_content(a_content):
"""
Prints a given DNA content and percentages of pairs.

:param a_content: DNA content


:type a_content: dict

Example:
>>> print_dna_base_content(dna_base_content("ACGTAAA"))
Total count, all bases: 7
Adenine (A) count: 4
Thymine (T) count: 1
Guanine (G) count: 1
Cytosine (C) count: 1
%A~T content: 71
%G~C content: 29
"""

print("Total... ")

def is_valid_dna_pair(a_dna_1, a_dna_2):


"""
Checks if two DNA sequences can be paired.

:param a_dna_1: a correct DNA sequence to check


:type a_dna_1: str

:param a_dna_2: a correct DNA sequence to check


:type a_dna_2: str

:return: result of the check


:rtype: bool

Examples of True-cases:
>>> is_valid_dna_pair("a", "t")
True
>>> is_valid_dna_pair("c", "g")
True
>>> is_valid_dna_pair("at", "at")
True
>>> is_valid_dna_pair("cg", "cg")
True
>>> is_valid_dna_pair("at", "cg")
True
>>> is_valid_dna_pair("cg", "at")
True

Examples of False-cases:
>>> is_valid_dna_pair(0, "c")
False
>>> is_valid_dna_pair("c", "b")
False
>>> is_valid_dna_pair("a", "cc")
False
>>> is_valid_dna_pair("a", "c")
False
>>> is_valid_dna_pair("t", "g")
False
>>> is_valid_dna_pair("ga", "ca")
False
"""

if type(a_dna_1) != str or type(a_dna_2) != str:


return False

for a_dna_1, a_dna_2 in DNA_PAIRS:


a_dna_1 = a_dna_1.upper()
a_dna_2 = a_dna_2.upper()
if (a_dna_1, a_dna_2) in DNA_PAIRS:
return True
if (a_dna_1, a_dna_2) in DNA_PAIRS:
return True
for dna_base in a_dna_1:
if dna_base in DNA_PAIRS[0] or dna_base in DNA_PAIRS[1]:
return True
for dna_base in a_dna_2:
if dna_base in DNA_PAIRS[0] or dna_base in DNA_PAIRS[1]:
return True
return False

if __name__ == '__main__':
import doctest
doctest.testmod()

You might also like