Exercise 2 solution B = "TCAG" AA = "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG" CODON = {a + b + c: AA[16 * i + 4 * j + k] for i, a in enumerate(B) for j, b in enumerate(B) for k, c in enumerate(B)} def translate(dna): protein = [] for i in range(0, len(dna) - 2, 3): aa = CODON[dna[i:i + 3]] if aa == "*": break protein.append(aa) return "".join(protein) def classify(old, new): if len(old) != len(new): return "frameshift" if (len(new) - len(old)) % 3 else "in-frame indel" a, b = translate(old), translate(new) if a == b: return "silent" return "nonsense" if len(b) < len(a) else "missense" gene = "ATGGCCTTGAAATGGTAA" counts = {"silent": 0, "missense": 0, "nonsense": 0} for pos in range(15): for n in "ACGT": if n != gene[pos]: counts[classify(gene, gene[:pos] + n + gene[pos + 1:])] += 1 print(counts, sum(counts.values())) Output: {'silent': 6, 'missense': 35, 'nonsense': 4} 45 Reading it: Every substitution is classified by translating both versions. The classifier counts changes; it does not judge how serious each one is.