diff --git a/common/lib/symmath/symmath/formula.py b/common/lib/symmath/symmath/formula.py index e82d361d7c..edc4ad580a 100644 --- a/common/lib/symmath/symmath/formula.py +++ b/common/lib/symmath/symmath/formula.py @@ -32,6 +32,8 @@ from sympy.physics.quantum.state import Ket from sympy.printing.latex import LatexPrinter from sympy.printing.str import StrPrinter +from openedx.core.djangolib.markup import HTML + log = logging.getLogger(__name__) log.warning("Dark code. Needs review before enabling in prod.") @@ -90,8 +92,8 @@ def to_latex(expr): #return '%s{}{}' % (xs[1:-1]) if expr_s[0] == '$': - return '[mathjax]%s[/mathjax]
' % (expr_s[1:-1]) # for sympy v6 # xss-lint: disable=python-interpolate-html - return '[mathjax]%s[/mathjax]
' % (expr_s) # for sympy v7 # xss-lint: disable=python-interpolate-html + return HTML('[mathjax]{expression}[/mathjax]
').format(expression=expr_s[1:-1]) # for sympy v6 + return HTML('[mathjax]{expression}[/mathjax]
').format(expression=expr_s) # for sympy v7 def my_evalf(expr, chop=False): diff --git a/common/lib/symmath/symmath/symmath_check.py b/common/lib/symmath/symmath/symmath_check.py index cc43c32a2f..5a1a2171a7 100644 --- a/common/lib/symmath/symmath/symmath_check.py +++ b/common/lib/symmath/symmath/symmath_check.py @@ -12,6 +12,10 @@ import logging import traceback +from markupsafe import escape + +from openedx.core.djangolib.markup import HTML + from .formula import * log = logging.getLogger(__name__) @@ -49,8 +53,9 @@ def symmath_check_simple(expect, ans, adict={}, symtab=None, extra_options=None) ) except Exception as err: return {'ok': False, - 'msg': 'Error %s
Failed in evaluating check(%s,%s)' % (err, expect, ans) - } + 'msg': HTML('Error {err}
Failed in evaluating check({expect},{ans})').format( + err=err, expect=expect, ans=ans + )} return ret #----------------------------------------------------------------------------- @@ -94,22 +99,28 @@ def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym= try: xgiven = my_sympify(given, normphase, matrix, do_qubit=do_qubit, abcsym=abcsym, symtab=symtab) except Exception as err: - return {'ok': False, 'msg': 'Error %s
in evaluating your expression "%s"' % (err, given)} + return {'ok': False, 'msg': HTML('Error {err}
in evaluating your expression "{given}"').format( + err=err, given=given + )} try: xexpect = my_sympify(expect, normphase, matrix, do_qubit=do_qubit, abcsym=abcsym, symtab=symtab) except Exception as err: - return {'ok': False, 'msg': 'Error %s
in evaluating OUR expression "%s"' % (err, expect)} + return {'ok': False, 'msg': HTML('Error {err}
in evaluating OUR expression "{expect}"').format( + err=err, expect=expect + )} if 'autonorm' in flags: # normalize trace of matrices try: xgiven /= xgiven.trace() except Exception as err: - return {'ok': False, 'msg': 'Error %s
in normalizing trace of your expression %s' % (err, to_latex(xgiven))} + return {'ok': False, 'msg': HTML('Error {err}
in normalizing trace of your expression {xgiven}'). + format(err=err, xgiven=to_latex(xgiven))} try: xexpect /= xexpect.trace() except Exception as err: - return {'ok': False, 'msg': 'Error %s
in normalizing trace of OUR expression %s' % (err, to_latex(xexpect))} + return {'ok': False, 'msg': HTML('Error {err}
in normalizing trace of OUR expression {xexpect}'). + format(err=err, xexpect=to_latex(xexpect))} msg = 'Your expression was evaluated as ' + to_latex(xgiven) # msg += '
Expected ' + to_latex(xexpect) @@ -145,7 +156,7 @@ def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym= def make_error_message(msg): # msg = msg.replace('

','

').replace('

','

') - msg = '
%s
' % msg + msg = HTML('
{msg}
').format(msg=msg) return msg @@ -210,7 +221,7 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None try: fexpect = my_sympify(str(expect), matrix=do_matrix, do_qubit=do_qubit) except Exception as err: - msg += '

Error %s in parsing OUR expected answer "%s"

' % (err, expect) + msg += HTML('

Error {err} in parsing OUR expected answer "{expect}"

').format(err=err, expect=expect) return {'ok': False, 'msg': make_error_message(msg)} ###### Sympy input ####### @@ -226,18 +237,19 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None if is_within_tolerance(fexpect, fans, threshold): return {'ok': True, 'msg': msg} else: - msg += '

You entered: %s

' % to_latex(fans) + msg += HTML('

You entered: {fans}

').format(fans=to_latex(fans)) return {'ok': False, 'msg': msg} if do_numerical: # numerical answer expected - force numerical comparison if is_within_tolerance(fexpect, fans, threshold): return {'ok': True, 'msg': msg} else: - msg += '

You entered: %s (note that a numerical answer is expected)

' % to_latex(fans) + msg += HTML('

You entered: {fans} (note that a numerical answer is expected)

').\ + format(fans=to_latex(fans)) return {'ok': False, 'msg': msg} if fexpect == fans: - msg += '

You entered: %s

' % to_latex(fans) + msg += HTML('

You entered: {fans}

').format(fans=to_latex(fans)) return {'ok': True, 'msg': msg} ###### PMathML input ###### @@ -255,20 +267,18 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None # if DEBUG: msg += '

mmlans=%s' % repr(mmlans).replace('<','<') try: fsym = f.sympy - msg += '

You entered: %s

' % to_latex(f.sympy) + msg += HTML('

You entered: {sympy}

').format(sympy=to_latex(f.sympy)) except Exception as err: log.exception("Error evaluating expression '%s' as a valid equation", ans) - msg += "

Error in evaluating your expression '%s' as a valid equation

" % (ans) + msg += HTML("

Error in evaluating your expression '{ans}' as a valid equation

").format(ans=ans) if "Illegal math" in str(err): - msg += "

Illegal math expression

" + msg += HTML("

Illegal math expression

") if DEBUG: - msg += 'Error: %s' % str(err).replace('<', '<') - msg += '
' - msg += '

DEBUG messages:

' - msg += "

%s

" % traceback.format_exc() - msg += '

cmathml=

%s

' % f.cmathml.replace('<', '<') - msg += '

pmathml=

%s

' % mmlans.replace('<', '<') - msg += '
' + msg += HTML('Error: {err}

DEBUG messages:

{format_exc}

' + '

cmathml=

{cmathml}

pmathml=

{pmathml}


').format( + err=escape(str(err)), format_exc=traceback.format_exc(), cmathml=escape(f.cmathml), + pmathml=escape(mmlans) + ) return {'ok': False, 'msg': make_error_message(msg)} # do numerical comparison with expected @@ -277,9 +287,9 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None if abs(abs(fsym - fexpect) / fexpect) < threshold: return {'ok': True, 'msg': msg} return {'ok': False, 'msg': msg} - msg += "

Expecting a numerical answer!

" - msg += "

given = %s

" % repr(ans) - msg += "

fsym = %s

" % repr(fsym) + msg += HTML("

Expecting a numerical answer!

given = {ans}

fsym = {fsym}

").format( + ans=repr(ans), fsym=repr(fsym) + ) # msg += "

cmathml =

%s

" % str(f.cmathml).replace('<','<') return {'ok': False, 'msg': make_error_message(msg)} @@ -297,12 +307,12 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None if abs(dm.vec().norm().evalf()) < threshold: return {'ok': True, 'msg': msg} except sympy.ShapeError: - msg += "

Error - your input vector or matrix has the wrong dimensions" + msg += HTML("

Error - your input vector or matrix has the wrong dimensions") return {'ok': False, 'msg': make_error_message(msg)} except Exception as err: - msg += "

Error %s in comparing expected (a list) and your answer

" % str(err).replace('<', '<') + msg += HTML("

Error %s in comparing expected (a list) and your answer

").format(escape(str(err))) if DEBUG: - msg += "

%s
" % traceback.format_exc() + msg += HTML("

{format_exc}
").format(format_exc=traceback.format_exc()) return {'ok': False, 'msg': make_error_message(msg)} #diff = (fexpect-fsym).simplify() @@ -314,15 +324,13 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None, xml=None diff = None if DEBUG: - msg += '
' - msg += '

DEBUG messages:

' - msg += "

Got: %s

" % repr(fsym) + msg += HTML('

DEBUG messages:

Got: {fsym}

Expecting: {fexpect}

')\ + .format(fsym=repr(fsym), fexpect=repr(fexpect).replace('**', '^').replace('hat(I)', 'hat(i)')) # msg += "

Got: %s" % str([type(x) for x in fsym.atoms()]).replace('<','<') - msg += "

Expecting: %s

" % repr(fexpect).replace('**', '^').replace('hat(I)', 'hat(i)') # msg += "

Expecting: %s" % str([type(x) for x in fexpect.atoms()]).replace('<','<') if diff: - msg += "

Difference: %s

" % to_latex(diff) - msg += '
' + msg += HTML("

Difference: {diff}

").format(diff=to_latex(diff)) + msg += HTML('
') # Used to return more keys: 'ex': fexpect, 'got': fsym return {'ok': False, 'msg': msg}