def weighted_score(raw_earned, raw_possible, weight):
    """
    Returns a tuple that represents the weighted (earned, possible) score.
    If weight is None or raw_possible is 0, returns the original values.

    When weight is used, it defines the weighted_possible.  This allows
    course authors to specify the exact maximum value for a problem when
    they provide a weight.
    """
    assert raw_possible is not None
    cannot_compute_with_weight = weight is None or raw_possible == 0
    if cannot_compute_with_weight:
        return raw_earned, raw_possible
    else:
        return float(raw_earned) * weight / raw_possible, float(weight)