'Grade a numeric response.'

def get_score(self, student_answers):

    if (self.answer_id not in student_answers):
        return CorrectMap(self.answer_id, 'incorrect')
    if self.has_partial_credit:
        graders = ['list', 'close']
        for style in self.credit_type:
            if (style not in graders):
                raise LoncapaProblemError(('partial_credit    attribute    should    be    one    of:    ' + ','.join(graders)))
    student_answer = student_answers[self.answer_id]
    _ = self.capa_system.i18n.ugettext
    general_exception = StudentInputError(_(u"Could    not    interpret    '{student_answer}'    as    a    number.").format(student_answer=cgi.escape(student_answer)))
    try:
        student_float = evaluator({}, {}, student_answer)
    except UndefinedVariable as undef_var:
        raise StudentInputError(_(u'You    may    not    use    variables    ({bad_variables})    in    numerical    problems.').format(bad_variables=undef_var.message))
    except ValueError as val_err:
        if ('factorial' in val_err.message):
            raise StudentInputError(_("Factorial    function    evaluated    outside    its    domain:'{student_answer}'").format(student_answer=cgi.escape(student_answer)))
        else:
            raise general_exception
    except ParseException:
        raise StudentInputError(_(u"Invalid    math    syntax:    '{student_answer}'").format(student_answer=cgi.escape(student_answer)))
    except Exception:
        raise general_exception
    tree = self.xml
    has_partial_range = tree.xpath('responseparam[@partial_range]')
    if has_partial_range:
        partial_range = float(has_partial_range[0].get('partial_range', default='2'))
    else:
        partial_range = 2
    has_partial_answers = tree.xpath('responseparam[@partial_answers]')
    if has_partial_answers:
        partial_answers = has_partial_answers[0].get('partial_answers').split(',')
        for (index, word) in enumerate(partial_answers):
            partial_answers[index] = word.strip()
            partial_answers[index] = self.get_staff_ans(partial_answers[index])
    else:
        partial_answers = False
    partial_score = 0.5
    is_correct = 'incorrect'
    if self.range_tolerance:
        if isinstance(student_float, complex):
            raise StudentInputError(_(u'You    may    not    use    complex    numbers    in    range    tolerance    problems'))
        boundaries = []
        for (inclusion, answer) in zip(self.inclusion, self.answer_range):
            boundary = self.get_staff_ans(answer)
            if (boundary.imag != 0):
                raise StudentInputError(_('There    was    a    problem    with    the    staff    answer    to    this    problem:    complex    boundary.'))
            if isnan(boundary):
                raise StudentInputError(_('There    was    a    problem    with    the    staff    answer    to    this    problem:    empty    boundary.'))
            boundaries.append(boundary.real)
            if compare_with_tolerance(student_float, boundary, tolerance=float_info.epsilon, relative_tolerance=True):
                is_correct = ('correct' if inclusion else 'incorrect')
                break
        else:
            if (boundaries[0] < student_float < boundaries[1]):
                is_correct = 'correct'
            elif (self.has_partial_credit is False):
                pass
            elif ('close' in self.credit_type):
                extended_boundaries = []
                boundary_range = (boundaries[1] - boundaries[0])
                extended_boundaries.append((boundaries[0] - (partial_range * boundary_range)))
                extended_boundaries.append((boundaries[1] + (partial_range * boundary_range)))
                if (extended_boundaries[0] < student_float < extended_boundaries[1]):
                    is_correct = 'partially-correct'
    else:
        correct_float = self.get_staff_ans(self.correct_answer)
        if str(self.tolerance).endswith('%'):
            expanded_tolerance = (str((partial_range * float(str(self.tolerance)[:(-1)]))) + '%')
        else:
            expanded_tolerance = (partial_range * float(self.tolerance))
        if compare_with_tolerance(student_float, correct_float, self.tolerance):
            is_correct = 'correct'
        elif (self.has_partial_credit is False):
            pass
        elif ('list' in self.credit_type):
            for value in partial_answers:
                if compare_with_tolerance(student_float, value, self.tolerance):
                    is_correct = 'partially-correct'
                    break
                elif ('close' in self.credit_type):
                    if compare_with_tolerance(student_float, correct_float, expanded_tolerance):
                        is_correct = 'partially-correct'
                        break
                    elif compare_with_tolerance(student_float, value, expanded_tolerance):
                        is_correct = 'partially-correct'
                        partial_score = (partial_score * partial_score)
                        break
        elif ('close' in self.credit_type):
            if compare_with_tolerance(student_float, correct_float, expanded_tolerance):
                is_correct = 'partially-correct'
    self.additional_answer_index = (-1)
    if (is_correct == 'incorrect'):
        temp_additional_answer_idx = 0
        for additional_answer in self.additional_answers:
            staff_answer = self.get_staff_ans(additional_answer)
            if (complex(student_float) == staff_answer):
                is_correct = 'correct'
                self.additional_answer_index = temp_additional_answer_idx
                break
            temp_additional_answer_idx += 1
    if (is_correct == 'partially-correct'):
        return CorrectMap(self.answer_id, is_correct, npoints=partial_score)
    else:
        return CorrectMap(self.answer_id, is_correct)
