Beyond Dominant and Recessive

Genetics and Heredity Fundamentals

Course 1 ยท Chapter 6 ยท Beyond Dominant and Recessive

Genetics and Heredity Fundamentals 1 used the simplest rule: one allele hides the other. That rule is real, but it is only one of several. In this chapter we look at three other patterns: alleles that blend, alleles that both show, and traits built from many genes at once. The genotype counting from earlier chapters still works; what changes is how a genotype is turned into a look. All the programs here are Python 3.

What was run, and what was not
Every program in this chapter was run and the output shown is what it printed. The biology is written from general knowledge; items marked (check) are the ones to verify first. Where a program uses random numbers it fixes the seed, so the same output appears each time.

Incomplete Dominance

In incomplete dominance, the heterozygote looks like a mixture of the two homozygotes rather than like one of them (check). The textbook example is a flower with a red allele R and a white allele r: RR is red, rr is white, and Rr is pink (check). Neither allele is hiding the other. The pink flower has half the red-making product of the red one.

In code the change is small. The look now depends on how many copies of R the genotype has, not only on whether there is one.

from itertools import product from collections import Counter def flower(genotype): return {0: "white", 1: "pink", 2: "red"}[genotype.count("R")] kids = Counter(flower(a + b) for a, b in product("Rr", "Rr")) print(kids)
Counter({'pink': 2, 'red': 1, 'white': 1})

Crossing two pink flowers gives 1 red, 2 pink and 1 white out of 4. That is a 1:2:1 ratio. Compare it with the 3:1 ratio from Genetics and Heredity Fundamentals 1: the genotype counts are the same (1 RR, 2 Rr, 1 rr), but now each genotype has its own look, so the look ratio equals the genotype ratio. This is also a useful clue in practice: a 1:2:1 look ratio in a cross suggests incomplete dominance (check).

PatternRr looks likeLook ratio, Rr x Rr
complete dominancethe same as RR3 : 1
incomplete dominancein between RR and rr1 : 2 : 1
codominanceboth at once1 : 2 : 1

Codominance

In codominance, the heterozygote shows both alleles fully and separately, not a blend (check). The look is not "in between"; it is "both". A frequently quoted example is an animal with a red coat allele and a white coat allele whose heterozygote has patches of red and patches of white (check). Because the two patterns have the same 1:2:1 count, the table above lists them together; what differs is the biology, not the arithmetic.

The words are used loosely
Whether a trait is called incomplete dominance or codominance often depends on which level you look at. The same heterozygote can show a blended outward look (incomplete) while the cells make both gene products fully (codominant) (check). Textbooks differ, so treat the names as labels for the observed pattern.

Blood Groups: Three Alleles and Both Patterns

The ABO blood groups show several ideas together (check). The gene has three common alleles, usually called A, B and O. Up to now every gene had two alleles. A person still carries only two copies, one from each parent, but the population has three to choose from, so there are six genotypes.

  • A and B are codominant with each other: a person with both is group AB, showing both markers (check).
  • O is recessive to both: it only shows in a person with two copies, OO, who is group O (check).
  • So AA and AO are both group A, and BB and BO are both group B (check).
def blood_group(genotype): alleles = set(genotype) if alleles == {"A", "B"}: return "AB" if "A" in alleles: return "A" if "B" in alleles: return "B" return "O" for g in ["AA", "AO", "BB", "BO", "AB", "OO"]: print(g, blood_group(g))
AA A AO A BB B BO B AB AB OO O

Six genotypes, but only four looks. That is the key difference from Genetics and Heredity Fundamentals 1: here you cannot always read the genotype from the look. A person in group A might be AA or AO. Now ask what a pair of parents can have as children. Each parent gives one of their two alleles, so we try every pairing, as in the Punnett squares of earlier chapters, and collect the groups.

def child_groups(p1, p2): groups = set() for a in p1: for b in p2: groups.add(blood_group(a + b)) return sorted(groups) print(child_groups("AB", "OO")) print(child_groups("AO", "BO")) print(child_groups("AA", "BB")) print(child_groups("OO", "OO"))
['A', 'B'] ['A', 'AB', 'B', 'O'] ['AB'] ['O']

Read the lines in turn. An AB parent and an O parent cannot have an AB child or an O child, only A or B. Two parents who show A and B (here both heterozygous, AO and BO) can have all four groups. Two O parents can only have O children. Facts like these are why blood groups were once used as one piece of evidence in family questions, with the strong caution that they can only rule things out, never prove a relationship (check).

Two things this code leaves out
Real blood typing also has the separate Rh positive and negative factor, which is controlled by a different gene (check). And rare exceptions to the usual rules exist, so a program like this describes the standard textbook model, not every real family (check).

Many Genes, One Trait

So far a trait has been the work of one gene. Many familiar traits, such as height, are instead shaped by a great many genes, each adding a small push, together with the environment (check). These are polygenic traits. They do not fall into neat groups like "red, pink, white" but form a smooth range.

A simple model shows why. Suppose there are n genes, and each has two alleles, one "tall" (worth 1) and one "short" (worth 0). An individual has two copies of each gene, so the total score runs from 0 to 2n. Take a parent that is heterozygous for every gene, so every allele is equally likely to be passed on. How many of the 2n allele slots carry a tall allele? This is the same as counting the heads in 2n fair coin tosses, and we can count the ways exactly with math.comb. With n = 4 genes there are 8 slots.

from math import comb from fractions import Fraction n = 4 for k in range(2 * n + 1): ways = comb(2 * n, k) print(k, ways, Fraction(ways, 2 ** (2 * n)), "#" * ways)
0 1 1/256 # 1 8 1/32 ######## 2 28 7/64 ############################ 3 56 7/32 ######################################################## 4 70 35/128 ###################################################################### 5 56 7/32 ######################################################## 6 28 7/64 ############################ 7 8 1/32 ######## 8 1 1/256 #

The bars form a bell shape: the middle score (4) is the most common, with 70 of the 256 equally likely combinations, and the extremes 0 and 8 each have just 1. A person at an extreme needs luck on every single gene. More genes make the shape smoother and the extremes rarer. Now simulate individuals with 1, 2, 5 and 10 genes (so 2, 4, 10 and 20 slots).

import random from collections import Counter def height_score(rng, genes): return sum(rng.choice((0, 1)) + rng.choice((0, 1)) for _ in range(genes)) rng = random.Random(3) n = 20000 for genes in (1, 2, 5, 10): scores = [height_score(rng, genes) for _ in range(n)] mean = sum(scores) / n c = Counter(scores) print(genes, round(mean, 2), len(c), max(c.values()))
1 1.0 3 10065 2 2.0 5 7498 5 5.01 11 4860 10 10.01 18 3534

The columns are the number of genes, the average score, how many different scores appeared, and how many individuals shared the most common score. The average is always about the number of genes (half of the 2n slots), whatever n is. The number of different scores grows with n (3, 5, 11 and 18, of a possible 3, 5, 11 and 21; with 10 genes the three most extreme scores never turned up in 20,000 individuals). And the most common score holds a smaller and smaller share: about half of individuals with 1 gene, about a sixth with 10. The more genes, the finer the steps, and the closer the picture gets to a smooth curve.

A model, not a measurement
Real polygenic traits do not have equal genes or exactly two alleles each, and the environment (diet, health and so on) adds its own spread on top of the genes (check). Our model only explains the shape: many small independent contributions add up to a bell-like distribution. A related idea, heritability, describes how much of the variation in a group comes from genes; it says nothing about how much of one person's trait is "caused by" genes (check).

Challenges

Exercise 1

For incomplete dominance with R and r, take every unordered pair of parent genotypes from RR, Rr, rr (use itertools.combinations_with_replacement). For each pair, print the chance of each flower colour as a fractions.Fraction. Which pair gives all three colours?

๐Ÿ“„ View solution
Exercise 2

Using blood_group and child_groups, list the unordered pairs of the six genotypes (21 pairs). Print how many pairs can have a group O child, which pairs can have children in all four groups, and which pairs can have both an AB child and an O child.

๐Ÿ“„ View solution
Exercise 3

Simulate 50,000 individuals with 10 genes using random.Random(7) and the height_score idea. Print the mean score, the fraction scoring between 8 and 12 inclusive, how many scored exactly 0 or 20, and the lowest and highest scores seen.

๐Ÿ“„ View solution

Quick Reference

  • Complete dominance: heterozygote looks like one homozygote; cross of heterozygotes gives 3 : 1
  • Incomplete dominance: heterozygote is in between; cross gives 1 : 2 : 1
  • Codominance: heterozygote shows both alleles; also 1 : 2 : 1
  • ABO blood groups: three alleles; A and B codominant, O recessive; six genotypes, four looks
  • Polygenic traits: many genes add small effects; the result is a smooth, bell-shaped range
  • Check: the names of the patterns, the blood group details, and what heritability means
Coming next
Genetics and Heredity Fundamentals 7 looks at the chromosomes that decide sex, and at traits carried on them.