diff --git a/lms/djangoapps/courseware/tabs.py b/lms/djangoapps/courseware/tabs.py index 8ec856e5b3..e97622a5ef 100644 --- a/lms/djangoapps/courseware/tabs.py +++ b/lms/djangoapps/courseware/tabs.py @@ -173,7 +173,7 @@ def get_course_tabs(user, course, active_page): """ Return the tabs to show a particular user, as a list of CourseTab items. """ - if not course.tabs: + if not hasattr(course,'tabs') or not course.tabs: return get_default_tabs(user, course, active_page) # TODO (vshnayder): There needs to be a place to call this right after course diff --git a/lms/lib/symmath/formula.py b/lms/lib/symmath/formula.py index 4aa9f60d30..1698b004d9 100644 --- a/lms/lib/symmath/formula.py +++ b/lms/lib/symmath/formula.py @@ -105,6 +105,7 @@ def my_sympify(expr, normphase=False, matrix=False, abcsym=False, do_qubit=False 'e': sympy.E, # for exp 'i': sympy.I, # lowercase i is also sqrt(-1) 'Q': sympy.Symbol('Q'), # otherwise it is a sympy "ask key" + 'I': sympy.Symbol('I'), # otherwise it is sqrt(-1) #'X':sympy.sympify('Matrix([[0,1],[1,0]])'), #'Y':sympy.sympify('Matrix([[0,-I],[I,0]])'), #'Z':sympy.sympify('Matrix([[1,0],[0,-1]])'), @@ -273,11 +274,16 @@ class formula(object): if not self.is_mathml(): return my_sympify(self.expr) if self.is_presentation_mathml(): + cmml = None try: cmml = self.cmathml xml = etree.fromstring(str(cmml)) except Exception, err: - raise Exception, 'Err %s while converting cmathml to xml; cmml=%s' % (err, cmml) + if 'conversion from Presentation MathML to Content MathML was not successful' in cmml: + msg = "Illegal math expression" + else: + msg = 'Err %s while converting cmathml to xml; cmml=%s' % (err, cmml) + raise Exception, msg xml = self.fix_greek_in_mathml(xml) self.the_sympy = self.make_sympy(xml[0]) else: @@ -320,6 +326,24 @@ class formula(object): 'power': sympy.Pow, 'sin': sympy.sin, 'cos': sympy.cos, + 'tan': sympy.tan, + 'cot': sympy.cot, + 'sinh': sympy.sinh, + 'cosh': sympy.cosh, + 'coth': sympy.coth, + 'tanh': sympy.tanh, + 'asin': sympy.asin, + 'acos': sympy.acos, + 'atan': sympy.atan, + 'atan2': sympy.atan2, + 'acot': sympy.acot, + 'asinh': sympy.asinh, + 'acosh': sympy.acosh, + 'atanh': sympy.atanh, + 'acoth': sympy.acoth, + 'exp': sympy.exp, + 'log': sympy.log, + 'ln': sympy.ln, } # simple sumbols @@ -385,8 +409,7 @@ class formula(object): if 'hat' in usym: sym = my_sympify(usym) else: - if usym == 'i': print "options=", self.options - if usym == 'i' and 'imaginary' in self.options: # i = sqrt(-1) + if usym == 'i' and self.options is not None and 'imaginary' in self.options: # i = sqrt(-1) sym = sympy.I else: sym = sympy.Symbol(str(usym)) diff --git a/lms/lib/symmath/symmath_check.py b/lms/lib/symmath/symmath_check.py index 4af012d2cb..bcb4a0d490 100644 --- a/lms/lib/symmath/symmath_check.py +++ b/lms/lib/symmath/symmath_check.py @@ -140,13 +140,20 @@ def check(expect, given, numerical=False, matrix=False, normphase=False, abcsym= # msg += "
dot test " + to_latex(dot(sympy.Symbol('x'),sympy.Symbol('y'))) return {'ok': False, 'msg': msg} +#----------------------------------------------------------------------------- +# helper function to convert all to
+
+def make_error_message(msg):
+ # msg = msg.replace(' ',' ').replace('
Error %s in parsing OUR expected answer "%s"
' % (err, expect) - return {'ok': False, 'msg': msg} + return {'ok': False, 'msg': make_error_message(msg)} # if expected answer is a number, try parsing provided answer as a number also try: @@ -184,6 +197,13 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None): msg += 'You entered: %s
' % to_latex(fans) return {'ok': False, 'msg': msg} + if do_numerical: # numerical answer expected - force numerical comparison + if abs(abs(fans - fexpect) / fexpect) < threshold: + return {'ok': True, 'msg': msg} + else: + msg += 'You entered: %s (note that a numerical answer is expected)
' % to_latex(fans) + return {'ok': False, 'msg': msg} + if fexpect == fans: msg += 'You entered: %s
' % to_latex(fans) return {'ok': True, 'msg': msg} @@ -205,16 +225,18 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None): msg += 'You entered: %s
' % to_latex(f.sympy) except Exception, err: log.exception("Error evaluating expression '%s' as a valid equation" % ans) - msg += "Error %s in evaluating your expression '%s' as a valid equation
" % (str(err).replace('<', '<'), - ans) + msg += "Error in evaluating your expression '%s' as a valid equation
" % (ans) + if "Illegal math" in str(err): + msg += "Illegal math expression
" if DEBUG: + msg += 'Error: %s' % str(err).replace('<', '<') msg += 'DEBUG messages:
' msg += "%s" % traceback.format_exc() msg += '
cmathml=
%s' % f.cmathml.replace('<', '<') msg += '
pmathml=
%s' % mmlans.replace('<', '<') msg += '
given = %s
" % repr(ans) msg += "fsym = %s
" % repr(fsym) # msg += "cmathml =
%s" % str(f.cmathml).replace('<','<') - return {'ok': False, 'msg': msg} + return {'ok': False, 'msg': make_error_message(msg)} if fexpect == fsym: return {'ok': True, 'msg': msg} @@ -239,11 +261,11 @@ def symmath_check(expect, ans, dynamath=None, options=None, debug=None): return {'ok': True, 'msg': msg} except sympy.ShapeError: msg += "
Error - your input vector or matrix has the wrong dimensions" - return {'ok': False, 'msg': msg} + return {'ok': False, 'msg': make_error_message(msg)} except Exception, err: msg += "
Error %s in comparing expected (a list) and your answer
" % str(err).replace('<', '<') if DEBUG: msg += "%s" % traceback.format_exc() - return {'ok': False, 'msg': msg} + return {'ok': False, 'msg': make_error_message(msg)} #diff = (fexpect-fsym).simplify() #fsym = fsym.simplify()