Net zoals nucleïnezuren polymeren zijn van nucleotiden, zijn eiwitten ketens van kleinere moleculen die aminozuren genoemd worden. In elk levend organisme vinden we de gebruikelijke 20 aminozuren. Net zoals de primaire structuur van een nucleïnezuur bepaald wordt door de volgorde van zijn nucleotiden, wordt de primaire structuur van een eiwit bepaald door de volgorde van zijn aminozuren. Sommige eiwitten bestaan uit verschillende deelketens die polypeptiden genoemd worden, terwijl andere uit slechts één enkele polypeptide bestaan. Eiwitten zijn de motor van elke functie die door de cel wordt uitgevoerd, en dus ligt de sleutel tot het ontsluieren van leven vermoedelijk in het interpreteren van de relatie tussen een keten van aminozuren en de functie van het eiwit dat uiteindelijk gevormd wordt door deze keten van aminozuren. Het onderzoeksdomein dat gewijd is aan de studie van eiwitten wordt proteomics genoemd.
Hoe worden eiwitten gemaakt? De genetische code — ontdekt doorheen een aantal ingenieuze experimenten die in de late jaren '50 uitgevoerd werden — geeft in detail weer hoe de vertaling verloopt van een RNA molecule die boodschapper RNA (messenger RNA, mRNA) genoemd wordt naar de aminozuren die instaan voor eiwitsynthese. De ogenschijnlijke moeilijkheid bij deze vertaling is dat ze op één of andere manier in staat moet zijn om 4 RNA basen te vertalen naar een taal die bestaat uit 20 aminozuren. Om elk van de mogelijke aminozuren te kunnen maken, moeten we 3-nucleobase strings (die in deze context codons genoemd worden) vertalen naar aminozuren. Merk op dat er $$4^3=64$$ mogelijke codons zijn, waardoor verschillende codons kunnen coderen voor hetzelfde aminozuur. Twee speciale soorten codons zijn de startcodons (AUG in de standaard genetische code) die coderen voor het aminozuur methionine en altijd aangeven waar de vertaling begint, en de stopcodons (UAA, UAG, UGA in de standaard genetische code), die niet coderen voor een aminozuur maar aangeven waar de vertaling van het eiwit eindigt.
De idee dat eiwitten altijd gemaakt worden uit RNA, dat op zijn beurt altijd gemaakt wordt uit DNA, vormt het centrale dogma van de moleculaire biologie. Net als alle andere dogma's is het niet altijd waar. Het biedt ons echter een uitstekende benadering van de werkelijkheid. Het ribosoom maakt peptiden aan met behulp van een hulpmolecule die transfer RNA (tRNA) genoemd wordt. Een tRNA molecule heeft een reeks van drie RNA nucleotiden aan één uiteinde (dit wordt een anticodon genoemd) en een aminozuur aan het andere uiteinde. Het ribosoom neemt een mRNA molecule die aangemaakt werd uit DNA en onderzoekt het codon per codon. Bij elke stap bindt een tRNA molecule die beschikt over het complementaire anticodon zich aan het codon op die positie, en wordt het aminozuur aan het andere uiteinde van het tRNA toegevoegd aan de groeiende peptideketen vooraleer het resterende deel van het tRNA wordt uitgestoten in de cel. Daarna gaat het ribosoom op zoek naar de volgende tRNA molecule.
Niet elke RNA base zal uiteindelijk vertaald worden naar een eiwit, waardoor een interval van RNA (of een interval van DNA dat vertaald wordt naar RNA) dat codeert voor een eiwit biologisch gezien een zeer belangrijke waarde heeft. Een dergelijk interval van DNA of RNA wordt een gen genoemd. Omdat eiwitsynthese de drijvende kracht is achter alle cellulaire processen, zorgen genen voor het onderscheid tussen organismen en vormen ze de basis voor erfelijkheid, zijnde het proces waarbij eigenschappen worden overgeërfd.
De 20 gebruikelijke aminozuren worden symbolisch voorgesteld door 20 hoofdletters van ons alfabet (alle letters behalve B, J, O, U, X, en Z). Eiwitstrings worden opgebouwd uit deze 20 letters. Een RNA codontabel bevat alle details omtrent het coderen van specifieke codons naar het alfabet van de aminozuren. De codontabel die hieronder staat, geeft de afbeelding die gebruikt wordt bij de standaard genetische code. Er bestaan echter alternatieve genetische codes die kleine verschillen vertonen met dit afbeeldingsschema. Stopcodons coderen niet voor een aminozuur en worden in de tabel aangegeven met het woord Stop in plaats van een letter die staat voor een aminozuur.
UUU F CUU L AUU I GUU V
UUC F CUC L AUC I GUC V
UUA L CUA L AUA I GUA V
UUG L CUG L AUG M GUG V
UCU S CCU P ACU T GCU A
UCC S CCC P ACC T GCC A
UCA S CCA P ACA T GCA A
UCG S CCG P ACG T GCG A
UAU Y CAU H AAU N GAU D
UAC Y CAC H AAC N GAC D
UAA Stop CAA Q AAA K GAA E
UAG Stop CAG Q AAG K GAG E
UGU C CGU R AGU S GGU G
UGC C CGC R AGC S GGC G
UGA Stop CGA R AGA R GGA G
UGG W CGG R AGG R GGG G
Als onderzoekers een nieuw eiwit ontdekken, dan willen ze graag achterhalen van welke RNA streng dit eiwit kan vertaald zijn, om zo de genen die geassocieerd zijn met dit eiwit te kunnen localiseren op het genoom. Ondanks het feit dat elke RNA string op een unieke manier kan vertaald worden naar een eiwitstring, levert het omgekeerde proces helaas een groot aantal mogelijke RNA strings op voor eenzelfde eiwitstring omdat aminozuren mogelijks corresponderen met meerdere RNA codons. Je opdracht bestaat erin om voor een gegeven eiwitstring te bepalen hoeveel verschillende mRNA strings een vertaling geven naar dit eiwit. Hiervoor ga je als volgt te werk:
Schrijf een functie codontabel waaraan de locatie van een tekstbestand moet doorgegeven worden. Dit tekstbestand moet de afbeelding van codons naar aminozuren bevatten die gebruikt wordt door een bepaalde genetische code, in het formaat zoals dat hierboven wordt weergegeven. De functie moet de afbeeldint uit het bestand lezen, en teruggeven onder de vorm van een dictionary (die dus de 64 mogelijke codons afbeeldt op hun corresponderende aminozuur). Stopcodons moeten hierbij afgebeeld worden op een sterretje (*).
Schrijf een functie omgekeerde_codontabel waaraan een dictionary moet doorgegeven worden die de vorm heeft van de dictionaries die teruggegeven worden door de functie codontabel. De functie moet een nieuwe dictionary teruggeven, die elk van de 20 aminozuren + het stopcodon (voorgesteld door een sterretje: *) afbeeldt op de verzameling van codons die vertalen naar dit aminozuur/stopcodon.
Schrijf een functie mRNA waaraan twee argumenten moeten doorgegeven worden: een eiwitstring en een codontabel. De codontabel moet doorgegeven worden als een dictionary die de vorm heeft van de dictionaries die teruggegeven worden door de functie codontabel. De functie moet teruggeven hoeveel verschillende mRNA strings volgens de gegeven codontabel vertaald worden naar het gegeven eiwit. Dit aantal kan bepaald worden als het product van het aantal codons dat afgebeeld wordt op elk van de aminozuren in de eiwitstring. Vergeet ook niet dat eiwitsynthese eindigt bij een stopcodon (dat niet expliciet is aangegeven op het einde van de eiwitstring die aan de functie wordt doorgegeven). Er moet dus ook vermenigvuldigd worden met het aantal mogelijke stopcodons. Een voorbeeld: volgens de codontabel van de standaard genetische code worden bijvoorbeeld 12 mRNA strings vertaald naar het eiwit MA, want er is één codon dat vertaald wordt naar M, vier naar A en er zijn ook drie stopcodons: $$1 \times 4 \times 3 = 12$$. Op analoge manier vertalen er $$1 \times 6 \times 2 \times 4 \times 3 = 144$$ mRNA strings naar de eiwitstring MRNA.
Bij onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand standard_code.txt1 zich in de huidige directory bevindt.
>>> tabel = codontabel('standard_code.txt')
>>> tabel
{'GUC': 'V', 'ACC': 'T', 'GUA': 'V', 'GUG': 'V', 'GUU': 'V', 'AAC': 'N', 'CCU': 'P', 'UGG': 'W', 'AGC': 'S', 'AUC': 'I', 'CAU': 'H', 'AAU': 'N', 'AGU': 'S', 'ACU': 'T', 'CAC': 'H', 'ACG': 'T', 'CCG': 'P', 'CCA': 'P', 'ACA': 'T', 'CCC': 'P', 'UGU': 'C', 'GGU': 'G', 'UCU': 'S', 'GCG': 'A', 'UGC': 'C', 'CAG': 'Q', 'GAU': 'D', 'UAU': 'Y', 'CGG': 'R', 'UCG': 'S', 'AGG': 'R', 'GGG': 'G', 'UCC': 'S', 'UCA': 'S', 'UAA': '*', 'GGA': 'G', 'UAC': 'Y', 'GAC': 'D', 'GAA': 'E', 'AUA': 'I', 'GCA': 'A', 'CUU': 'L', 'GGC': 'G', 'AUG': 'M', 'UGA': '*', 'CUG': 'L', 'GAG': 'E', 'CUC': 'L', 'AGA': 'R', 'CUA': 'L', 'GCC': 'A', 'AAA': 'K', 'AAG': 'K', 'CAA': 'Q', 'UUU': 'F', 'CGU': 'R', 'CGA': 'R', 'GCU': 'A', 'UAG': '*', 'AUU': 'I', 'UUG': 'L', 'UUA': 'L', 'CGC': 'R', 'UUC': 'F'}
>>> omgekeerde_codontabel(tabel)
{'A': {'GCA', 'GCC', 'GCU', 'GCG'}, 'C': {'UGC', 'UGU'}, 'E': {'GAG', 'GAA'}, 'D': {'GAU', 'GAC'}, 'G': {'GGU', 'GGG', 'GGA', 'GGC'}, 'F': {'UUU', 'UUC'}, 'I': {'AUA', 'AUC', 'AUU'}, 'H': {'CAC', 'CAU'}, 'K': {'AAG', 'AAA'}, '*': {'UAA', 'UGA', 'UAG'}, 'M': {'AUG'}, 'L': {'CUU', 'CUG', 'CUC', 'CUA', 'UUG', 'UUA'}, 'N': {'AAU', 'AAC'}, 'Q': {'CAA', 'CAG'}, 'P': {'CCU', 'CCG', 'CCA', 'CCC'}, 'S': {'UCU', 'AGC', 'UCG', 'UCC', 'UCA', 'AGU'}, 'R': {'AGG', 'CGC', 'AGA', 'CGA', 'CGG', 'CGU'}, 'T': {'ACC', 'ACA', 'ACG', 'ACU'}, 'W': {'UGG'}, 'V': {'GUC', 'GUA', 'GUG', 'GUU'}, 'Y': {'UAC', 'UAU'}}
>>> mRNA('MA', tabel)
12
>>> mRNA('MWQWQWY', tabel)
24
>>> mRNA('MRNA', tabel)
144