def grade(element_html, element_index, data): element = lxml.html.fragment_fromstring(element_html) name = pl.get_string_attrib(element, 'answers_name') # Get weight weight = pl.get_integer_attrib(element, 'weight', 1) # Get true answer (if it does not exist, create no grade - leave it # up to the question code) a_tru = data['correct_answers'].get(name, None) if a_tru is None: return data # Convert true answer to numpy a_tru = np.array(a_tru) # Throw an error if true answer is not a 2D numpy array if a_tru.ndim != 2: raise ValueError('true answer must be a 2D array') # Get submitted answer (if it does not exist, score is zero) a_sub = data['submitted_answers'].get(name, None) if a_sub is None: data['partial_scores'][name] = {'score': 0, 'weight': weight} return data # Convert submitted answer to numpy a_sub = np.array(a_sub) # If true and submitted answers have different shapes, score is zero if not (a_sub.shape == a_tru.shape): data['partial_scores'][name] = {'score': 0, 'weight': weight} return data # Get method of comparison, with relabs as default comparison = pl.get_string_attrib(element, 'comparison', 'relabs') # Compare submitted answer with true answer if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', 1e-5) atol = pl.get_float_attrib(element, 'atol', 1e-8) correct = pl.is_correct_ndarray2D_ra(a_sub, a_tru, rtol, atol) elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', 2) eps_digits = pl.get_integer_attrib(element, 'eps_digits', 3) correct = pl.is_correct_ndarray2D_sf(a_sub, a_tru, digits, eps_digits) elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', 2) eps_digits = pl.get_integer_attrib(element, 'eps_digits', 3) correct = pl.is_correct_ndarray2D_dd(a_sub, a_tru, digits, eps_digits) else: raise ValueError('method of comparison "%s" is not valid' % comparison) if correct: data['partial_scores'][name] = {'score': 1, 'weight': weight} else: data['partial_scores'][name] = {'score': 0, 'weight': weight} return data
def grade(element_html, data): element = lxml.html.fragment_fromstring(element_html) name = pl.get_string_attrib(element, 'answers-name') # Get weight weight = pl.get_integer_attrib(element, 'weight', WEIGHT_DEFAULT) # Get true answer (if it does not exist, create no grade - leave it # up to the question code) a_tru = pl.from_json(data['correct_answers'].get(name, None)) if a_tru is None: return # Wrap true answer in ndarray (if it already is one, this does nothing) a_tru = np.array(a_tru) # Throw an error if true answer is not a 2D numpy array if a_tru.ndim != 2: raise ValueError('true answer must be a 2D array') # Get submitted answer (if it does not exist, score is zero) a_sub = data['submitted_answers'].get(name, None) if a_sub is None: data['partial_scores'][name] = {'score': 0, 'weight': weight} return # If submitted answer is in a format generated by pl.to_json, convert it # back to a standard type (otherwise, do nothing) a_sub = pl.from_json(a_sub) # Wrap submitted answer in an ndarray (if it's already one, this does nothing) a_sub = np.array(a_sub) # If true and submitted answers have different shapes, score is zero if not (a_sub.shape == a_tru.shape): data['partial_scores'][name] = {'score': 0, 'weight': weight} return # Get method of comparison, with relabs as default comparison = pl.get_string_attrib(element, 'comparison', COMPARISON_DEFAULT) # Compare submitted answer with true answer if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', RTOL_DEFAULT) atol = pl.get_float_attrib(element, 'atol', ATOL_DEFAULT) correct = pl.is_correct_ndarray2D_ra(a_sub, a_tru, rtol, atol) elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', DIGITS_DEFAULT) correct = pl.is_correct_ndarray2D_sf(a_sub, a_tru, digits) elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', DIGITS_DEFAULT) correct = pl.is_correct_ndarray2D_dd(a_sub, a_tru, digits) else: raise ValueError('method of comparison "%s" is not valid' % comparison) if correct: data['partial_scores'][name] = {'score': 1, 'weight': weight} else: data['partial_scores'][name] = {'score': 0, 'weight': weight}
def grade(element_html, data): element = lxml.html.fragment_fromstring(element_html) name = pl.get_string_attrib(element, 'answers-name') # Get weight weight = pl.get_integer_attrib(element, 'weight', 1) # Get true answer (if it does not exist, create no grade - leave it # up to the question code) a_tru = pl.from_json(data['correct_answers'].get(name, None)) if a_tru is None: return # Wrap true answer in ndarray (if it already is one, this does nothing) a_tru = np.array(a_tru) # Throw an error if true answer is not a 2D numpy array if a_tru.ndim != 2: raise ValueError('true answer must be a 2D array') # Get submitted answer (if it does not exist, score is zero) a_sub = data['submitted_answers'].get(name, None) if a_sub is None: data['partial_scores'][name] = {'score': 0, 'weight': weight} return # If submitted answer is in a format generated by pl.to_json, convert it # back to a standard type (otherwise, do nothing) a_sub = pl.from_json(a_sub) # Wrap submitted answer in an ndarray (if it's already one, this does nothing) a_sub = np.array(a_sub) # If true and submitted answers have different shapes, score is zero if not (a_sub.shape == a_tru.shape): data['partial_scores'][name] = {'score': 0, 'weight': weight} return # Get method of comparison, with relabs as default comparison = pl.get_string_attrib(element, 'comparison', 'relabs') # Compare submitted answer with true answer if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', 1e-2) atol = pl.get_float_attrib(element, 'atol', 1e-8) correct = pl.is_correct_ndarray2D_ra(a_sub, a_tru, rtol, atol) elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', 2) correct = pl.is_correct_ndarray2D_sf(a_sub, a_tru, digits) elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', 2) correct = pl.is_correct_ndarray2D_dd(a_sub, a_tru, digits) else: raise ValueError('method of comparison "%s" is not valid' % comparison) if correct: data['partial_scores'][name] = {'score': 1, 'weight': weight} else: data['partial_scores'][name] = {'score': 0, 'weight': weight}