'Return a tuple that is (state, grade, max_grade) to preserve.
THIS SHOULD ONLY BE CALLED FOR CAPA PROBLEMS.
Updates to scores could have gotten crossed with updates to state, so
that the states and scores do not match up to each other (e.g. you might
have correct_course_row with the proper state, but the score
corresponding to that state might live in newline_course_row). So we\'re
going to re-derive the scores from the state for capa problems.'

def capa_state_and_grade(self, correct_course_row, newline_course_row):

    (ccr_grade, ccr_max_grade) = self.grade_for_state(correct_course_row.state)
    if ((ccr_grade, ccr_max_grade) != (correct_course_row.grade, correct_course_row.max_grade)):
        log.info('->    Correct    course    row    %s    has    grade    %s    but    should    have    grade    %s', correct_course_row.id, (correct_course_row.grade, correct_course_row.max_grade), (ccr_grade, ccr_max_grade))
    (ncr_grade, ncr_max_grade) = self.grade_for_state(newline_course_row.state)
    if ((ncr_grade, ncr_max_grade) != (newline_course_row.grade, newline_course_row.max_grade)):
        log.info('->    Newline    course    row    %s    has    grade    %s    but    should    have    grade    %s', newline_course_row.id, (newline_course_row.grade, newline_course_row.max_grade), (ncr_grade, ncr_max_grade))
    if (ncr_grade > ccr_grade):
        log.info('->    Newline    course    row    %s    has    higher    derived    grade    for    state.', newline_course_row.id)
        return (newline_course_row.state, ncr_grade, ncr_max_grade)
    log.info('->    Correct    course    row    %s    has    higher    or    equal    derived    grade    for    state.', correct_course_row.id)
    return (correct_course_row.state, ccr_grade, ccr_max_grade)
