Exercise 1 solution from itertools import product, combinations_with_replacement from collections import Counter from fractions import Fraction def flower(genotype): return {0: "white", 1: "pink", 2: "red"}[genotype.count("R")] for p1, p2 in combinations_with_replacement(["RR", "Rr", "rr"], 2): c = Counter(flower(a + b) for a, b in product(p1, p2)) total = sum(c.values()) print(p1, "x", p2, {k: str(Fraction(v, total)) for k, v in sorted(c.items())}) Output: RR x RR {'red': '1'} RR x Rr {'pink': '1/2', 'red': '1/2'} RR x rr {'pink': '1'} Rr x Rr {'pink': '1/2', 'red': '1/4', 'white': '1/4'} Rr x rr {'pink': '1/2', 'white': '1/2'} rr x rr {'white': '1'} Reading it: combinations_with_replacement gives each unordered pair of parent genotypes once (6 pairs). Because each genotype has its own look, the genotype ratio and the look ratio are the same. Only one pair, Rr x Rr, gives all three looks, in the ratio 1/4, 1/2, 1/4.