Level 1 · Foundations · Topic 1 of 6

DNA, RNA and the central dogma

Nucleotides, base pairing and the double helix in real 3D structures, how RNA differs, and how a gene becomes a protein. Your first Python runs on a real viral genome.

  • About 90 minutes
  • 3 interactive 3D structures
  • 8 code cells · 4 checked exercises
  • 10-question check
  • Runs in your browser

What you will learn

  • Name the three parts of a nucleotide and explain how nucleotides join into a strand with a 5′ and a 3′ end.
  • Explain base pairing, antiparallel strands and why sequences are always written 5′ to 3′.
  • Describe the double helix from a real crystal structure, including its grooves and dimensions.
  • Compare DNA and RNA in their sugar, bases and shape.
  • Follow information from gene to protein and predict the effect of a single-base change.
  • Use Python to read a genome file, calculate GC content, reverse-complement and translate sequences.

Before you start: None. School biology helps but is not required. The code runs in your browser, so you do not need to install anything; a laptop or desktop is more comfortable than a phone for the code lab.

Why this matters for bioinformatics

Almost every file you will meet as a bioinformatician is a description of DNA, RNA or protein. A FASTA file is a strand written as letters. A FASTQ file is millions of short pieces of strands read by a sequencer. A VCF file lists the places where one genome’s letters differ from another’s.

To use those files correctly you need a working picture of the molecules behind the letters. Many analysis bugs come from forgetting which strand a sequence is on, which direction it is written in, or where a gene really starts. This topic builds that picture, using real structures and real genomes rather than cartoons alone.

Nucleotides: the building blocks

DNA (deoxyribonucleic acid) and RNA (ribonucleic acid) are polymers: long chains built from repeating units called nucleotides. Every nucleotide has three parts:

  1. A phosphate group, which carries a negative charge. It is why DNA moves towards the positive electrode in gel electrophoresis.
  2. A five-carbon sugar: deoxyribose in DNA, ribose in RNA. Its carbons are numbered 1′ to 5′ (“one-prime” to “five-prime”). The primes distinguish sugar carbons from the atoms of the base.
  3. A nitrogenous base, attached to the 1′ carbon. The base is the part that carries information.
Deoxyadenosine monophosphate (dAMP): a phosphate group on the 5′ carbon, a deoxyribose sugar with carbons 1′ to 5′, and the base adenine attached to the 1′ carbon. The 3′ hydroxyl is where the next nucleotide is linked.
Swipe sideways to see the whole figure. Deoxyadenosine monophosphate (dAMP), one DNA nucleotide. The phosphate is on the 5′ carbon; the 3′ hydroxyl is where the next nucleotide attaches. Drawn from its chemical structure with RDKit. Open full size

There are five common bases. Adenine (A) and guanine (G) are purines, with two fused rings. Cytosine (C), thymine (T) and uracil (U) are pyrimidines, with a single ring. DNA uses A, C, G and T; RNA uses A, C, G and U.

Skeletal structures of adenine and guanine (purines, two fused rings) and cytosine, thymine and uracil (pyrimidines, one ring). Thymine, found in DNA, carries a methyl group that uracil, found in RNA, lacks.
Swipe sideways to see the whole figure. The five nucleobases. Thymine and uracil differ only by one methyl group (highlighted); that small difference is how cells tell DNA from RNA. Open full size

Strands have a direction: 5′ and 3′

Nucleotides join through a phosphodiester bond: the phosphate on the 5′ carbon of one nucleotide links to the hydroxyl on the 3′ carbon of the previous one. Repeating this makes a sugar–phosphate backbone with the bases sticking out to one side.

Because every link runs from a 3′ carbon to a 5′ carbon, a strand has two different ends. The 5′ end finishes with a free phosphate; the 3′ end finishes with a free hydroxyl. Enzymes that make DNA and RNA can only add new nucleotides to the 3′ end, so strands always grow in the 5′ → 3′ direction.

Each strand is a chain of sugars (pentagons) linked by phosphates (P), joined from the 3′ carbon of one sugar to the 5′ carbon of the next. The upper strand reads ATGC from 5′ to 3′; the lower strand runs the opposite way and, read 5′ to 3′, is GCAT, the reverse complement. A pairs with T through two hydrogen bonds and G with C through three.
Swipe sideways to see the whole figure. Two strands pair in opposite directions. The top strand reads ATGC from 5′ to 3′; its partner, read 5′ to 3′, is GCAT. Open full size

In a double helix the two strands run in opposite directions: they are antiparallel. Convention says we always write a sequence from 5′ to 3′. So the partner of 5′-ATGC-3′ is written 5′-GCAT-3′: complement each base, then reverse the order. This is the reverse complement, and you will compute it constantly.

Base pairing and the double helix

The two strands are held together by hydrogen bonds between bases. The pairing is specific: A pairs with T through two hydrogen bonds, and G pairs with C through three. These are called Watson–Crick base pairs.

Adenine pairs with thymine through two hydrogen bonds, and guanine pairs with cytosine through three, shown as dashed lines. Each base is attached to a sugar on the same side of the pair, the minor groove edge.
Swipe sideways to see the whole figure. The two Watson–Crick base pairs. Every pair joins a two-ring purine to a one-ring pyrimidine, so all pairs are about the same width and the helix stays smooth. Open full size

Base pairing explains a pattern Erwin Chargaff measured around 1950, before the structure was known. In double-stranded DNA the amount of A equals the amount of T, and G equals C. If a DNA sample is 30% A, it must also be 30% T, which leaves 40% for G and C together: 20% each.

Try it below. Type a sequence and watch the partner strand, the hydrogen bonds and the GC content change.

Interactive

Build the complementary strand

The shape: a right-handed double helix

In 1953 James Watson and Francis Crick proposed that the two antiparallel strands wind around a common axis, with the bases paired inside and the backbones outside. Their model relied on X-ray diffraction images taken by Rosalind Franklin and Raymond Gosling, published alongside it in the same issue of Nature. The common form in cells, B-DNA, is about 2 nm wide, rises 0.34 nm per base pair and makes one full turn about every 10.5 base pairs.

Two sugar-phosphate backbones wind around a common axis in opposite directions, 5′ to 3′ and 3′ to 5′, with base pairs as rungs. The helix is about 2 nm wide, each base pair adds 0.34 nm and one full turn holds about 10.5 base pairs. Because the backbones are not opposite each other, the grooves alternate between a wide major groove and a narrow minor groove.
Swipe sideways to see the whole figure. B-DNA drawn to scale. The backbones are not opposite each other, so the gaps between them alternate between a wide major groove and a narrow minor groove. Proteins that read DNA, such as transcription factors, usually recognise bases through the major groove. Open full size
Interactive 3D structureA real double helix: the Drew–Dickerson dodecamer (PDB 1BNA)
A real double helix: the Drew–Dickerson dodecamer (PDB 1BNA). Atomic coordinates of a 12-base-pair B-DNA, 5′-CGCGAATTCGCG-3′, determined by X-ray crystallography in 1981. Every atom is shown where the experiment placed it. 1BNA at RCSB PDB · Download coordinates (75 KB)

Try this

  1. Switch to Spacefill and spin the molecule. You can see the major and minor grooves as two spiralling channels of different width.
  2. Return to Ladder with H-bonds on. Count the dashed lines in an A·T pair (blue–red) and a G·C pair (green–amber). You should find two and three.
  3. Measure a hydrogen bond: in Sticks style, click an atom at each end of a dashed line. Watson–Crick hydrogen bonds in this structure are about 2.7 to 3.1 Å (0.27 to 0.31 nm) long.
  4. Measure the width of the helix: colour By element and click phosphorus atoms (orange) on opposite sides of the helix. The farthest-apart pairs are about 19 Å apart; add the size of the atoms themselves and you reach the 2 nm diameter.
Going further: DNA is not always B-form

Under some conditions DNA adopts other shapes. A-DNA is wider and more compact; RNA double helices take this form. Z-DNA is left-handed, with a zig-zag backbone, and forms most easily in alternating C and G sequences. The structure below, solved in 1979 at 0.9 Å resolution, was the first crystal structure of DNA at atomic resolution, and it surprised everyone by twisting the “wrong” way. Compare it with B-DNA above.

Interactive 3D structureLeft-handed Z-DNA (PDB 2DCG)
Left-handed Z-DNA (PDB 2DCG). The hexamer 5′-CGCGCG-3′. The small extra molecules are two spermine molecules and a magnesium ion from the crystal. 2DCG at RCSB PDB · Download coordinates (59 KB)

RNA: same alphabet, different chemistry

RNA differs from DNA in three ways that matter:

  • Sugar. Ribose has a hydroxyl (–OH) on its 2′ carbon; deoxyribose (“de-oxy”) has only a hydrogen there. The 2′-OH makes RNA more chemically reactive and much less stable, which suits a short-lived working copy.
  • Base. RNA uses uracil (U) where DNA uses thymine (T). U pairs with A just as T does.
  • Shape. RNA is usually made as a single strand. It folds back on itself, pairing short complementary stretches into stems and loops, and these folds give many RNAs their function.
The five-carbon sugars of DNA and RNA, with carbons numbered 1′ to 5′. The base attaches at 1′. Ribose has a hydroxyl group at the 2′ carbon; 2′-deoxyribose has only a hydrogen there.
Swipe sideways to see the whole figure. The sugars of DNA and RNA side by side. The only difference is at the 2′ carbon (highlighted). Open full size

Cells make several kinds of RNA. Messenger RNA (mRNA) carries the instructions for a protein. Transfer RNA (tRNA) brings amino acids to the ribosome. Ribosomal RNA (rRNA) forms the core of the ribosome and catalyses the joining of amino acids. Many other RNAs, such as microRNAs and long non-coding RNAs, regulate genes without ever being translated.

Below is a real tRNA. Its 76 nucleotides fold into an L shape held together by base pairs between distant parts of the chain, including G·U “wobble” pairs and unusual pairs that DNA never makes. Notice how much of the molecule is double-stranded even though it is one chain.

Interactive 3D structureYeast phenylalanine tRNA (PDB 1EHZ)
Yeast phenylalanine tRNA (PDB 1EHZ). One RNA chain of 76 nucleotides, solved at 1.93 Å. Modified bases, such as pseudouridine and wybutosine, are coloured as the base they derive from; hover over them to see their names. 1EHZ at RCSB PDB · Download coordinates (223 KB)

Try this

  1. Colour By base and look for purple (U) paired with green (G): these are G·U wobble pairs.
  2. Find the anticodon, residues 34 to 36 (G, A, A; the G is 2′-O-methylated), at the tip of the arm farthest from the 3′ end. Read 5′ to 3′ it is GAA, which pairs with the mRNA codon UUC for phenylalanine.
  3. Turn on Spin to see the L shape. The amino acid attaches to the 3′ end, CCA, about 7 nm from the anticodon: measure it by clicking an atom of A76 and one of A35.

How does a single strand decide which parts to pair? The simplest model looks for the arrangement with the most base pairs. Try it with the sequences below: complementary stretches separated by a loop fold into a hairpin.

Interactive

Fold an RNA (teaching model)

The central dogma: DNA → RNA → protein

In 1958 Francis Crick summarised how genetic information flows, and restated it in 1970 as the central dogma of molecular biology. Information is copied from DNA to DNA (replication), from DNA to RNA (transcription) and from RNA to protein (translation). Some viruses add special routes, but information never flows back out of a protein into nucleic acid.

DNA is copied by replication, transcribed into RNA by RNA polymerase, and RNA is translated into protein by the ribosome. Special transfers also occur: reverse transcription from RNA to DNA in retroviruses such as HIV, and RNA replication in many RNA viruses. Information does not flow back from protein to nucleic acid.
Swipe sideways to see the whole figure. The central dogma. Solid arrows happen in all cells; dashed arrows are special cases found in viruses such as HIV (reverse transcription) and many RNA viruses (RNA replication). Open full size

Transcription

RNA polymerase opens the double helix and reads one strand, the template strand, from 3′ to 5′. It builds an RNA from 5′ to 3′ that is complementary to the template. That RNA therefore has the same sequence as the other strand, the coding strand, except that it has U where the coding strand has T. Sequence databases show genes as coding strand, 5′ to 3′.

Translation

A ribosome reads the mRNA three bases at a time. Each triplet is a codon. Four bases make 4 × 4 × 4 = 64 codons: 61 specify amino acids and 3 (UAA, UAG, UGA) mean “stop”. Translation usually begins at AUG, which also codes for methionine. Most amino acids have several codons, so the code is redundant (or degenerate): a change in the third base of a codon often leaves the protein unchanged.

Where you start reading matters. A sequence can be read in three reading frames on each strand, and only one of them, usually, gives the real protein.

Interactive

Transcribe and translate a real gene

This is the start of the coding sequence of human HBB, the gene for β-globin, a subunit of haemoglobin. Hover over a codon to follow it through each step, try the other reading frames, then apply the sickle-cell mutation.

One letter changes everything. In sickle-cell disease, base 20 of the HBB coding sequence is T instead of A. Codon 7 changes from GAG to GTG, and the protein gets valine instead of glutamate: a missense change written c.20A>T (p.Glu7Val). Older papers call it Glu6Val, because they count from the second amino acid: the first methionine is removed from the mature protein. Vernon Ingram identified this single amino-acid difference in 1957, the first time an inherited disease was traced to one amino-acid change in a protein.

Genes are more than coding sequence

In plants, animals and fungi, most genes are split. The pieces that remain in the mature mRNA are exons; the pieces in between, which are removed by splicing, are introns. The mRNA also keeps untranslated regions (UTRs) at both ends, and gains a 5′ cap and a poly(A) tail. HBB, for example, has three exons and two introns.

A eukaryotic gene has a promoter, then exons separated by introns. Transcription makes a pre-mRNA copy of the whole gene; splicing removes the introns, which usually begin with GT and end with AG, and a 5′ cap and poly(A) tail are added. The mature mRNA has a 5′ untranslated region, the coding sequence from the start codon to the stop codon, and a 3′ untranslated region.
Swipe sideways to see the whole figure. From gene to mature mRNA. Only the coding sequence, from the start codon to the stop codon, is translated. Open full size

Code lab: your first genome analysis

Time to work with real data. Each box below is a small Python program that runs in your browser. Press Run (or Ctrl + Enter) to run it. The first run downloads Python, about 12 MB, which takes a few seconds; after that, runs are instant. Each box runs on its own, so you can do them in any order, and your edits are saved in this browser until you press Reset.

Boxes marked Exercise are checked automatically when you run them. If you get stuck, there is a hint and a worked solution.

Example

Read a genome from a FASTA file

A FASTA file has a header line starting with > and then the sequence, split over many lines. This reads the SARS-CoV-2 genome and joins the lines into one string.

Data: NC_045512.2.fasta

with open("NC_045512.2.fasta") as handle:
    header = handle.readline().strip()               # the first line
    sequence = "".join(line.strip() for line in handle)  # all the rest, joined

print("Header:", header)
print("Length:", len(sequence), "bases")
print("First 60 bases:", sequence[:60])
print("Last 60 bases: ", sequence[-60:])
What you should see

The genome is 29,903 bases long. It ends in a run of 33 A’s: the poly(A) tail of the viral RNA genome, recorded here as DNA letters.

Example

Count bases and calculate GC content

Counter counts how often each letter appears. GC content is the fraction of bases that are G or C.

Data: NC_045512.2.fasta

from collections import Counter

with open("NC_045512.2.fasta") as handle:
    handle.readline()                                    # skip the header
    sequence = "".join(line.strip() for line in handle)

counts = Counter(sequence)
for base in "ACGT":
    print(f"{base}: {counts[base]:>6,}  ({counts[base] / len(sequence):.1%})")

gc = (counts["G"] + counts["C"]) / len(sequence)
print(f"GC content: {gc:.2%}")
What you should see

SARS-CoV-2 is AT-rich, with a GC content of 37.97%. Genomes vary widely: the E. coli genome is about 51% GC, some bacteria are below 25% and others above 70%.

Exercise

Write a reverse-complement function

Complete reverse_complement so it returns the partner strand, read 5′ to 3′.

def reverse_complement(seq):
    """Return the reverse complement of a DNA sequence written 5'->3'."""
    pairs = {"A": "T", "T": "A", "G": "C", "C": "G"}
    # 1. Complement every base using the dictionary.
    # 2. Reverse the result so it reads 5'->3'.
    return ""   # replace this line


print(reverse_complement("ATGC"))     # should print GCAT
print(reverse_complement("GAATTC"))   # the EcoRI site: should print GAATTC
Exercise

Translate the HBB gene

The HBB mRNA record says its coding sequence is bases 51 to 494. Python counts from 0 and a slice excludes its end, so those bases are mrna[50:494]. Finish translate, then check your protein against UniProt.

Data: NM_000518.5.fasta P68871.fasta

# The standard genetic code, built from the usual T, C, A, G ordering.
bases = "TCAG"
amino_acids = "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"
codon_table = {a + b + c: amino_acids[16 * i + 4 * j + k]
               for i, a in enumerate(bases)
               for j, b in enumerate(bases)
               for k, c in enumerate(bases)}

def read_fasta(path):
    """Return (header, sequence) for a single-record FASTA file."""
    with open(path) as handle:
        header = handle.readline().strip()
        return header, "".join(line.strip() for line in handle)

_, mrna = read_fasta("NM_000518.5.fasta")
cds = mrna[50:494]          # bases 51-494, as given in the GenBank record

def translate(dna):
    """Translate codon by codon, stopping at the first stop codon."""
    protein = ""
    # Step through dna three bases at a time: range(0, len(dna) - 2, 3)
    # Look each codon up in codon_table; stop (break) when you reach "*".
    return protein

protein = translate(cds)
print(len(cds), "bases ->", len(protein), "amino acids")
print(protein)

_, uniprot = read_fasta("P68871.fasta")
print("Matches UniProt P68871:", protein == uniprot)
Exercise

What does the sickle-cell variant do?

Variant names such as c.20A>T count from the A of the start codon, which is base 1. Make the change, translate both versions and find the codon that differs.

Data: NM_000518.5.fasta

# The standard genetic code, built from the usual T, C, A, G ordering.
bases = "TCAG"
amino_acids = "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"
codon_table = {a + b + c: amino_acids[16 * i + 4 * j + k]
               for i, a in enumerate(bases)
               for j, b in enumerate(bases)
               for k, c in enumerate(bases)}

def read_fasta(path):
    """Return (header, sequence) for a single-record FASTA file."""
    with open(path) as handle:
        header = handle.readline().strip()
        return header, "".join(line.strip() for line in handle)

def translate(dna):
    """Translate codon by codon, stopping at the first stop codon."""
    protein = ""
    for i in range(0, len(dna) - 2, 3):
        amino_acid = codon_table[dna[i:i + 3]]
        if amino_acid == "*":
            break
        protein += amino_acid
    return protein

_, mrna = read_fasta("NM_000518.5.fasta")
cds = mrna[50:494]

position = 20                                    # c.20 is base 20 of the CDS
print("Base at c.20:", cds[position - 1])       # should be A

mutant = cds          # TODO: replace base 20 with T (build a new string with slices)

normal_protein = translate(cds)
mutant_protein = translate(mutant)

codon_number = None   # TODO: which codon (counting from 1) contains base 20?
before = None         # TODO: that amino acid in normal_protein
after = None          # TODO: that amino acid in mutant_protein
print(codon_number, before, "->", after)
Example

Test Chargaff’s rule on two real genomes

A FASTA file holds one strand, so Chargaff’s rule (A = T, G = C across both strands) does not have to hold within it. Yet in long double-stranded genomes it nearly does, a pattern known as Chargaff’s second parity rule. Compare E. coli with the single-stranded RNA genome of SARS-CoV-2. The E. coli file is gzip-compressed, which gzip.open handles.

Data: NC_000913.3.fasta.gz NC_045512.2.fasta

import gzip
from collections import Counter
import matplotlib.pyplot as plt

def read_sequence(path):
    opener = gzip.open if path.endswith(".gz") else open
    with opener(path, "rt") as handle:
        handle.readline()
        return "".join(line.strip() for line in handle)

genomes = {
    "E. coli K-12 (double-stranded DNA)": read_sequence("NC_000913.3.fasta.gz"),
    "SARS-CoV-2 (single-stranded RNA)": read_sequence("NC_045512.2.fasta"),
}

fig, ax = plt.subplots(figsize=(7, 3.2))
for offset, (name, seq) in enumerate(genomes.items()):
    counts = Counter(seq)
    print(f"{name}: {len(seq):,} bases, A/T = {counts['A'] / counts['T']:.3f}, G/C = {counts['G'] / counts['C']:.3f}")
    fractions = [counts[base] / len(seq) for base in "ACGT"]
    ax.bar([i + offset * 0.4 for i in range(4)], fractions, width=0.4, label=name)

ax.set_xticks([i + 0.2 for i in range(4)], list("ACGT"))
ax.set_ylabel("Fraction of genome")
ax.legend(frameon=False, fontsize=8)
plt.show()
What you should see

In E. coli, A/T is 1.001 and G/C is 0.998 on a single strand of 4.6 million bases. SARS-CoV-2 departs clearly from parity (A/T 0.933, G/C 1.068): with no partner strand, nothing forces the balance.

Example

The same work with Biopython

You will rarely parse files by hand in real projects. Biopython reads GenBank records, including their annotated features. Note how it prints locations: [50:494] is Python-style (0-based, end excluded), the same bases GenBank writes as 51..494.

Data: NM_000518.5.gb

from Bio import SeqIO

record = SeqIO.read("NM_000518.5.gb", "genbank")
print(record.id, "-", record.description)
print("Length:", len(record.seq), "bases\n")

for feature in record.features:
    if feature.type == "exon":
        print("exon", feature.location)
    elif feature.type == "CDS":
        cds = feature.extract(record.seq)
        protein = cds.translate(to_stop=True)
        print("CDS ", feature.location, "->", len(cds), "bases")
        print("Protein:", protein)
        print("Matches the annotation:", str(protein) == feature.qualifiers["translation"][0])
What you should see

The record lists three exons, matching the three-exon structure of the HBB gene, and Biopython’s translation matches the one stored in the file.

Check your understanding

Ten questions. Score 70% or more to complete this part of the topic. You can retake it as often as you like.

1What makes an RNA nucleotide different from a DNA nucleotide?
2What is the reverse complement of 5′-ATGCC-3′?
3A double-stranded DNA sample is 30% adenine. What percentage is guanine?
4Why is the double helix the same width along its whole length?
5Which statement about strand direction is correct?
6During transcription, RNA polymerase…
7How many of the 64 codons specify an amino acid?
8The sickle-cell variant changes codon 7 of HBB from GAG to GTG, so glutamate becomes valine. What kind of mutation is this?
9A GFF3 file places a gene at 21563–25384. Which Python slice extracts it from a genome string?
10What does a transfer RNA (tRNA) do?

Mini project: find and translate the spike gene

The spike protein lets SARS-CoV-2 enter human cells, and it is the target of COVID-19 vaccines. Use the genome and its GFF3 annotation to pull out the spike gene, translate it and locate one of its best-known features: the furin cleavage site, the amino acids PRRAR, which is cut by a human enzyme as part of activating the protein.

  1. Find the coordinates of the gene named S in the GFF3 file (given).
  2. Extract its DNA from the genome, converting 1-based, inclusive coordinates to a Python slice.
  3. Translate it, leaving out the stop codon.
  4. Find where PRRAR begins, numbering amino acids from 1.
Exercise

The spike gene

Data: NC_045512.2.fasta NC_045512.2.gff3

# The standard genetic code, built from the usual T, C, A, G ordering.
bases = "TCAG"
amino_acids = "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"
codon_table = {a + b + c: amino_acids[16 * i + 4 * j + k]
               for i, a in enumerate(bases)
               for j, b in enumerate(bases)
               for k, c in enumerate(bases)}

def read_fasta(path):
    """Return (header, sequence) for a single-record FASTA file."""
    with open(path) as handle:
        header = handle.readline().strip()
        return header, "".join(line.strip() for line in handle)

def translate(dna):
    """Translate codon by codon, stopping at the first stop codon."""
    protein = ""
    for i in range(0, len(dna) - 2, 3):
        amino_acid = codon_table[dna[i:i + 3]]
        if amino_acid == "*":
            break
        protein += amino_acid
    return protein

_, genome = read_fasta("NC_045512.2.fasta")

# 1. Find the spike (S) gene in the annotation. GFF3 columns are tab-separated:
#    seqid, source, type, start, end, score, strand, phase, attributes
start = end = None
with open("NC_045512.2.gff3") as handle:
    for line in handle:
        fields = line.rstrip("\n").split("\t")
        if len(fields) == 9 and fields[2] == "gene" and "Name=S;" in fields[8] + ";":
            start, end = int(fields[3]), int(fields[4])
print("Spike gene:", start, "to", end)

# 2. Extract the gene's DNA (1-based inclusive -> 0-based slice).
spike_dna = None        # TODO

# 3. Translate it, without the stop codon.
spike_protein = None    # TODO

# 4. Where does the furin site PRRAR start (counting amino acids from 1)?
furin_position = None   # TODO

print(len(spike_protein or ""), "amino acids; PRRAR at", furin_position)

Go further

  • Which amino acid is most common in the spike protein? (Use Counter on spike_protein.)
  • Extract and translate the nucleocapsid gene, named N, the same way. How long is its protein?
  • Open the GenBank file NC_045512.2.gb with Biopython and compare your spike translation with the one stored in the record.

Summary and further reading

Key takeaways

  • A nucleotide is a phosphate, a sugar (deoxyribose in DNA, ribose in RNA) and a base. Bases carry the information.
  • Strands have direction. They grow 5′ → 3′, pair antiparallel, and are always written 5′ → 3′; the partner strand is the reverse complement.
  • A pairs with T (or U) through two hydrogen bonds, G with C through three. B-DNA is a right-handed helix about 2 nm wide with about 10.5 base pairs per turn.
  • RNA is usually single-stranded and folds into functional shapes, such as the L-shaped tRNA.
  • Genes are transcribed into RNA, and mRNA is translated codon by codon into protein. One base change can change the protein, as in sickle-cell disease.
  • Coordinates need care: annotation files are usually 1-based and inclusive, Python slices are 0-based and exclude the end.

Key terms

Data used on this page

References and further reading

  1. Watson JD, Crick FHC. Molecular structure of nucleic acids: a structure for deoxyribose nucleic acid. Nature 171, 737–738 (1953). doi:10.1038/171737a0
  2. Franklin RE, Gosling RG. Molecular configuration in sodium thymonucleate. Nature 171, 740–741 (1953). doi:10.1038/171740a0
  3. Crick F. Central dogma of molecular biology. Nature 227, 561–563 (1970). doi:10.1038/227561a0
  4. Ingram VM. Gene mutations in human haemoglobin: the chemical difference between normal and sickle cell haemoglobin. Nature 180, 326–328 (1957). doi:10.1038/180326a0
  5. Drew HR, et al. Structure of a B-DNA dodecamer: conformation and dynamics. PNAS 78, 2179–2183 (1981). doi:10.1073/pnas.78.4.2179
  6. Wang AH-J, et al. Molecular structure of a left-handed double helical DNA fragment at atomic resolution. Nature 282, 680–686 (1979). doi:10.1038/282680a0
  7. Shi H, Moore PB. The crystal structure of yeast phenylalanine tRNA at 1.93 Å resolution: a classic structure revisited. RNA 6, 1091–1105 (2000). doi:10.1017/S1355838200000364
  8. PDB-101 Molecule of the Month: DNA. A short, illustrated introduction from the RCSB Protein Data Bank. pdb101.rcsb.org

Finished the topic?

Pass the check and the exercises, or mark the topic complete yourself. Progress is saved in this browser.