def render(element_html, data): element = lxml.html.fragment_fromstring(element_html) # Get the number of digits to output digits = pl.get_integer_attrib(element, 'digits', 2) # Get the presentation type presentation_type = pl.get_string_attrib(element, 'presentation-type', 'f') var_name = pl.get_string_attrib(element, 'params-name') # Get value of variable, raising exception if variable does not exist var_data = data['params'].get(var_name, None) if var_data is None: raise Exception('No value in data["params"] for variable %s in pl-matrix-latex element' % var_name) # If the variable is in a format generated by pl.to_json, convert it # back to a standard type (otherwise, do nothing) var_data = pl.from_json(var_data) if not np.isscalar(var_data): var_data = np.array(var_data) # Check if numpy array type is numeric (integer, float or complex) if np.issubdtype(var_data.dtype, np.number): # Check shape of variable if var_data.ndim != 2: raise Exception('Value in data["params"] for variable %s in pl-matrix-latex element must be 2D array or scalar' % var_name) else: raise Exception('Value in data["params"] for variable %s in pl-matrix-latex element must be numeric' % var_name) # Create string for latex matrix format html = pl.latex_from_2darray(var_data, presentation_type=presentation_type, digits=digits) return html
def render(element_html, data): element = lxml.html.fragment_fromstring(element_html) # get the name of the element, in this case, the name of the array name = pl.get_string_attrib(element, 'answers-name') label = pl.get_string_attrib(element, 'label', None) allow_partial_credit = pl.get_boolean_attrib(element, 'allow-partial-credit', False) allow_feedback = pl.get_boolean_attrib(element, 'allow-feedback', allow_partial_credit) if data['panel'] == 'question': editable = data['editable'] # Get true answer a_tru = pl.from_json(data['correct_answers'].get(name, None)) if a_tru is None: raise Exception( 'No value in data["correct_answers"] for variable %s in pl-matrix-component-input element' % name) else: if np.isscalar(a_tru): raise Exception( 'Value in data["correct_answers"] for variable %s in pl-matrix-component-input element cannot be a scalar.' % name) else: a_tru = np.array(a_tru) if a_tru.ndim != 2: raise Exception( 'Value in data["correct_answers"] for variable %s in pl-matrix-component-input element must be a 2D array.' % name) else: m, n = np.shape(a_tru) input_array = createTableForHTMLDisplay(m, n, name, label, data, 'input') # Get comparison parameters and info strings comparison = pl.get_string_attrib(element, 'comparison', 'relabs') if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', 1e-2) atol = pl.get_float_attrib(element, 'atol', 1e-8) if (rtol < 0): raise ValueError( 'Attribute rtol = {:g} must be non-negative'.format(rtol)) if (atol < 0): raise ValueError( 'Attribute atol = {:g} must be non-negative'.format(atol)) info_params = { 'format': True, 'relabs': True, 'rtol': '{:g}'.format(rtol), 'atol': '{:g}'.format(atol) } elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', 2) if (digits < 0): raise ValueError( 'Attribute digits = {:d} must be non-negative'.format( digits)) info_params = { 'format': True, 'sigfig': True, 'digits': '{:d}'.format(digits), 'comparison_eps': 0.51 * (10**-(digits - 1)) } elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', 2) if (digits < 0): raise ValueError( 'Attribute digits = {:d} must be non-negative'.format( digits)) info_params = { 'format': True, 'decdig': True, 'digits': '{:d}'.format(digits), 'comparison_eps': 0.51 * (10**-(digits - 0)) } else: raise ValueError( 'method of comparison "%s" is not valid (must be "relabs", "sigfig", or "decdig")' % comparison) with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: info = chevron.render(f, info_params).strip() with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: info_params.pop('format', None) info_params['shortformat'] = True shortinfo = chevron.render(f, info_params).strip() html_params = { 'question': True, 'name': name, 'label': label, 'editable': editable, 'info': info, 'shortinfo': shortinfo, 'input_array': input_array, 'inline': True, 'uuid': pl.get_uuid() } partial_score = data['partial_scores'].get(name, {'score': None}) score = partial_score.get('score', None) if score is not None: try: score = float(score) if score >= 1: html_params['correct'] = True elif score > 0: html_params['partial'] = math.floor(score * 100) else: html_params['incorrect'] = True except Exception: raise ValueError('invalid score' + score) with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: html = chevron.render(f, html_params).strip() elif data['panel'] == 'submission': parse_error = data['format_errors'].get(name, None) html_params = { 'submission': True, 'label': label, 'parse_error': parse_error, 'uuid': pl.get_uuid() } a_tru = pl.from_json(data['correct_answers'].get(name, None)) m, n = np.shape(a_tru) partial_score = data['partial_scores'].get(name, {'score': None}) score = partial_score.get('score', None) if score is not None: try: score = float(score) if score >= 1: html_params['correct'] = True elif score > 0: html_params['partial'] = math.floor(score * 100) else: html_params['incorrect'] = True except Exception: raise ValueError('invalid score' + score) if parse_error is None: # Get submitted answer, raising an exception if it does not exist a_sub = data['submitted_answers'].get(name, None) if a_sub is None: raise Exception('submitted answer is None') # If 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 answer in an ndarray (if it's already one, this does nothing) a_sub = np.array(a_sub) # Format submitted answer as a latex string sub_latex = '$' + pl.latex_from_2darray( a_sub, presentation_type='g', digits=12) + '$' # When allowing feedback, display submitted answers using html table sub_html_table = createTableForHTMLDisplay(m, n, name, label, data, 'output-feedback') if allow_feedback and score is not None: if score < 1: html_params['a_sub_feedback'] = sub_html_table else: html_params['a_sub'] = sub_latex else: html_params['a_sub'] = sub_latex else: # create html table to show submitted answer when there is an invalid format html_params['raw_submitted_answer'] = createTableForHTMLDisplay( m, n, name, label, data, 'output-invalid') with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: html = chevron.render(f, html_params).strip() elif data['panel'] == 'answer': # Get true answer - do nothing if it does not exist a_tru = pl.from_json(data['correct_answers'].get(name, None)) if a_tru is not None: a_tru = np.array(a_tru) # Get comparison parameters and create the display data comparison = pl.get_string_attrib(element, 'comparison', 'relabs') if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', 1e-2) atol = pl.get_float_attrib(element, 'atol', 1e-8) # FIXME: render correctly with respect to rtol and atol latex_data = '$' + pl.latex_from_2darray( a_tru, presentation_type='g', digits=12) + '$' elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', 2) latex_data = '$' + pl.latex_from_2darray( a_tru, presentation_type='sigfig', digits=digits) + '$' elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', 2) latex_data = '$' + pl.latex_from_2darray( a_tru, presentation_type='f', digits=digits) + '$' else: raise ValueError( 'method of comparison "%s" is not valid (must be "relabs", "sigfig", or "decdig")' % comparison) html_params = { 'answer': True, 'label': label, 'latex_data': latex_data, 'uuid': pl.get_uuid() } with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: html = chevron.render(f, html_params).strip() else: html = '' else: raise Exception('Invalid panel type: %s' % data['panel']) return html
def render(element_html, data): element = lxml.html.fragment_fromstring(element_html) # get the name of the element, in this case, the name of the array name = pl.get_string_attrib(element, 'answers-name') label = pl.get_string_attrib(element, 'label', None) allow_partial_credit = pl.get_boolean_attrib(element, 'allow-partial-credit', False) allow_feedback = pl.get_boolean_attrib(element, 'allow-feedback', allow_partial_credit) if data['panel'] == 'question': editable = data['editable'] # Get true answer a_tru = pl.from_json(data['correct_answers'].get(name, None)) if a_tru is None: raise Exception('No value in data["correct_answers"] for variable %s in pl-matrix-component-input element' % name) else: if np.isscalar(a_tru): raise Exception('Value in data["correct_answers"] for variable %s in pl-matrix-component-input element cannot be a scalar.' % name) else: a_tru = np.array(a_tru) if a_tru.ndim != 2: raise Exception('Value in data["correct_answers"] for variable %s in pl-matrix-component-input element must be a 2D array.' % name) else: m, n = np.shape(a_tru) input_array = createTableForHTMLDisplay(m, n, name, label, data, 'input') # Get comparison parameters and info strings comparison = pl.get_string_attrib(element, 'comparison', 'relabs') if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', 1e-2) atol = pl.get_float_attrib(element, 'atol', 1e-8) if (rtol < 0): raise ValueError('Attribute rtol = {:g} must be non-negative'.format(rtol)) if (atol < 0): raise ValueError('Attribute atol = {:g} must be non-negative'.format(atol)) info_params = {'format': True, 'relabs': True, 'rtol': '{:g}'.format(rtol), 'atol': '{:g}'.format(atol)} elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', 2) if (digits < 0): raise ValueError('Attribute digits = {:d} must be non-negative'.format(digits)) info_params = {'format': True, 'sigfig': True, 'digits': '{:d}'.format(digits), 'comparison_eps': 0.51 * (10**-(digits - 1))} elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', 2) if (digits < 0): raise ValueError('Attribute digits = {:d} must be non-negative'.format(digits)) info_params = {'format': True, 'decdig': True, 'digits': '{:d}'.format(digits), 'comparison_eps': 0.51 * (10**-(digits - 0))} else: raise ValueError('method of comparison "%s" is not valid (must be "relabs", "sigfig", or "decdig")' % comparison) with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: info = chevron.render(f, info_params).strip() with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: info_params.pop('format', None) info_params['shortformat'] = True shortinfo = chevron.render(f, info_params).strip() html_params = { 'question': True, 'name': name, 'label': label, 'editable': editable, 'info': info, 'shortinfo': shortinfo, 'input_array': input_array, 'inline': True, 'uuid': pl.get_uuid() } partial_score = data['partial_scores'].get(name, {'score': None}) score = partial_score.get('score', None) if score is not None: try: score = float(score) if score >= 1: html_params['correct'] = True elif score > 0: html_params['partial'] = math.floor(score * 100) else: html_params['incorrect'] = True except Exception: raise ValueError('invalid score' + score) with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: html = chevron.render(f, html_params).strip() elif data['panel'] == 'submission': parse_error = data['format_errors'].get(name, None) html_params = { 'submission': True, 'label': label, 'parse_error': parse_error, 'uuid': pl.get_uuid() } a_tru = pl.from_json(data['correct_answers'].get(name, None)) m, n = np.shape(a_tru) partial_score = data['partial_scores'].get(name, {'score': None}) score = partial_score.get('score', None) if score is not None: try: score = float(score) if score >= 1: html_params['correct'] = True elif score > 0: html_params['partial'] = math.floor(score * 100) else: html_params['incorrect'] = True except Exception: raise ValueError('invalid score' + score) if parse_error is None: # Get submitted answer, raising an exception if it does not exist a_sub = data['submitted_answers'].get(name, None) if a_sub is None: raise Exception('submitted answer is None') # If 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 answer in an ndarray (if it's already one, this does nothing) a_sub = np.array(a_sub) # Format submitted answer as a latex string sub_latex = '$' + pl.latex_from_2darray(a_sub, presentation_type='g', digits=12) + '$' # When allowing feedback, display submitted answers using html table sub_html_table = createTableForHTMLDisplay(m, n, name, label, data, 'output-feedback') if allow_feedback and score is not None: if score < 1: html_params['a_sub_feedback'] = sub_html_table else: html_params['a_sub'] = sub_latex else: html_params['a_sub'] = sub_latex else: # create html table to show submitted answer when there is an invalid format html_params['raw_submitted_answer'] = createTableForHTMLDisplay(m, n, name, label, data, 'output-invalid') with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: html = chevron.render(f, html_params).strip() elif data['panel'] == 'answer': # Get true answer - do nothing if it does not exist a_tru = pl.from_json(data['correct_answers'].get(name, None)) if a_tru is not None: a_tru = np.array(a_tru) # Get comparison parameters and create the display data comparison = pl.get_string_attrib(element, 'comparison', 'relabs') if comparison == 'relabs': rtol = pl.get_float_attrib(element, 'rtol', 1e-2) atol = pl.get_float_attrib(element, 'atol', 1e-8) # FIXME: render correctly with respect to rtol and atol latex_data = '$' + pl.latex_from_2darray(a_tru, presentation_type='g', digits=12) + '$' elif comparison == 'sigfig': digits = pl.get_integer_attrib(element, 'digits', 2) latex_data = '$' + pl.latex_from_2darray(a_tru, presentation_type='sigfig', digits=digits) + '$' elif comparison == 'decdig': digits = pl.get_integer_attrib(element, 'digits', 2) latex_data = '$' + pl.latex_from_2darray(a_tru, presentation_type='f', digits=digits) + '$' else: raise ValueError('method of comparison "%s" is not valid (must be "relabs", "sigfig", or "decdig")' % comparison) html_params = { 'answer': True, 'label': label, 'latex_data': latex_data, 'uuid': pl.get_uuid() } with open('pl-matrix-component-input.mustache', 'r', encoding='utf-8') as f: html = chevron.render(f, html_params).strip() else: html = '' else: raise Exception('Invalid panel type: %s' % data['panel']) return html