Exercise 3 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" def report(orig, mut): a, b = translate(orig), translate(mut) first = "none" for i in range(max(len(a), len(b))): if a[i:i + 1] != b[i:i + 1]: first = i + 1 break print(a, "->", b, classify(orig, mut), "first difference:", first) orig = "GTGCACCTGACTCCTGAGGAGAAG" report(orig, orig[:15] + "GTG" + orig[18:]) report(orig, orig[:17] + "A" + orig[18:]) report(orig, orig[:15] + orig[16:]) report(orig, orig[:15] + "TAG" + orig[18:]) Output: VHLTPEEK -> VHLTPVEK missense first difference: 6 VHLTPEEK -> VHLTPEEK silent first difference: none VHLTPEEK -> VHLTPRR frameshift first difference: 6 VHLTPEEK -> VHLTP nonsense first difference: 6 Reading it: The frameshift variant is compared position by position, and a protein that is shorter simply has no letter there, so the first difference is found where it ends or changes.