Exercise 1 solution Code: from itertools import product from collections import Counter def cross(p1, p2): kids = Counter() for a, b in product(p1, p2): kids["".join(sorted(a + b))] += 1 return kids def dom_count(counts, allele="A"): return sum(n for g, n in counts.items() if allele in g) for p1, p2 in (("Aa", "aa"), ("AA", "aa"), ("AA", "Aa")): c = cross(p1, p2) d = dom_count(c) print(p1, "x", p2, dict(c), "dominant:", d, "recessive:", sum(c.values()) - d) Output: Aa x aa {'Aa': 2, 'aa': 2} dominant: 2 recessive: 2 AA x aa {'Aa': 4} dominant: 4 recessive: 0 AA x Aa {'AA': 2, 'Aa': 2} dominant: 4 recessive: 0 Reading it: - Aa x aa gives half Aa and half aa, so a 1 : 1 ratio of dominant to recessive appearance. This is the classic "test cross" pattern. - AA x aa gives only Aa, so every offspring shows the dominant trait. - AA x Aa gives half AA and half Aa; all four squares contain A, so all show the dominant trait even though the genotypes differ.