Exercise 1 solution from itertools import product from fractions import Fraction mothers = {"HH": ("H", "H"), "Hh": ("H", "h"), "hh": ("h", "h")} for mname, mom in mothers.items(): for dad in ("H", "h"): sons = daughters = 0 for m, f in product(mom, ("X", "Y")): if f == "Y": sons += (m == "h") else: daughters += ((m, dad).count("h") == 2) print(mname, "x", dad, "| affected son", Fraction(sons, 2), "| affected daughter", Fraction(daughters, 2)) Output: HH x H | affected son 0 | affected daughter 0 HH x h | affected son 0 | affected daughter 0 Hh x H | affected son 1/2 | affected daughter 0 Hh x h | affected son 1/2 | affected daughter 1/2 hh x H | affected son 1 | affected daughter 0 hh x h | affected son 1 | affected daughter 1 Reading it: each line is one pairing of mother and father. A son gets his only X from his mother, so his chance of being affected is the share of her X chromosomes that carry h: 0, 1/2 or 1. A daughter is affected only when both her X chromosomes carry h, so she needs an h from her father as well, which only an affected father can give. A carrier mother with an affected father is the one pairing that gives affected daughters (1/2).