def partisan_gini(election_results):
    """
    Computes the partisan Gini score for the given ElectionResults.
    The partisan Gini score is defined as the area between the seats-votes
    curve and its reflection about (.5, .5).
    """
    # For two parties, the Gini score is symmetric--it does not vary by party.
    party = election_results.election.parties[0]

    # To find seats as a function of votes, we assume uniform partisan swing.
    # That is, if the statewide popular vote share for a party swings by some
    # delta, the vote share for that party swings by that delta in each
    # district.
    # We calculate the necessary delta to shift the district with the highest
    # vote share for the party to a vote share of 0.5. This delta, subtracted
    # from the original popular vote share, gives the minimum popular vote
    # share that yields 1 seat to the party.
    # We repeat this process for the district with the second-highest vote
    # share, which gives the minimum popular vote share yielding 2 seats,
    # and so on.
    overall_result = election_results.percent(party)
    race_results = sorted(election_results.percents(party), reverse=True)
    seats_votes = [overall_result - r + 0.5 for r in race_results]

    # Apply reflection of seats-votes curve about (.5, .5)
    reflected_sv = reversed([1 - s for s in seats_votes])
    # Calculate the unscaled, unsigned area between the seats-votes curve
    # and its reflection. For each possible number of seats attained, we find
    # the area of a rectangle of unit height, with a width determined by the
    # horizontal distance between the curves at that number of seats.
    unscaled_area = sum(abs(s - r) for s, r in zip(seats_votes, reflected_sv))
    # We divide by area by the number of seats to obtain a partisan Gini score
    # between 0 and 1.
    return unscaled_area / len(race_results)