def expected_hamming(p1, p2=None):
    """
    Return the expected hamming distance between two random vectors X and Y
    where X_i ~ Bernoulli(p1) and Y_i ~ Bernoulli(p2) (defaults to p1 if p2
    isn't specified), under the following assumptions:
    1. P(X_i = Y_i) = P(X_j = Y_j). In words, this means (X_i, Y_i) and
    (X_j, Y_j) are identically jointly distributed. In other words, all data
    points are equally easy (or hard) to learn (this is an empirically false
    assumption).
    2. X_i and Y_i are conditionally independent (conditioned on i). In other
    words, the predictions between any two learned models on the same test
    example are independent (obviously false assumption).
    """
    if p2 is None:
        return 2 * p1 * (1 - p1)
    else:
        return p1 + p2 - 2 * p1 * p2