def test_docs(): """Make sure that the documentation examples work""" # Generate random real numbers between 3 and 7 sampler = RealInterval(start=3, stop=7) # This is equivalent to sampler = RealInterval([3, 7]) # The default is [1, 5] sampler = RealInterval() # Generate random integers between 3 and 7 inclusive sampler = IntegerRange(start=3, stop=7) # This is equivalent to sampler = IntegerRange([3, 7]) # The default is [1, 5] sampler = IntegerRange() # Select random numbers from (1, 3, 5, 7, 9) sampler = DiscreteSet((1, 3, 5, 7, 9)) # Always select 3.5 sampler = DiscreteSet(3.5) # Select random complex numbers from 0 to 1 + i sampler = ComplexRectangle(re=[0, 1], im=[0, 1]) # The default is re=[1, 3], im=[1, 3] sampler = ComplexRectangle() # Select random complex numbers from inside the unit circle sampler = ComplexSector(modulus=[0, 1], argument=[-np.pi, np.pi]) # The default is modulus=[1, 3], argument=[0, pi/2] sampler = ComplexSector() # Test dependent sampling sampler = DependentSampler(depends=["x", "y", "z"], formula="sqrt(x^2+y^2+z^2)") # Select either sin or cos randomly functionsampler = SpecificFunctions([np.cos, np.sin]) # Always select a single lambda function functionsampler = SpecificFunctions(lambda x: x * x) # Generate a random function functionsampler = RandomFunction(center=1, amplitude=2) # The default is center=0, amplitude=10 functionsampler = RandomFunction() # Generate a random sinusoid functionsampler = RandomFunction(num_terms=1) # Generate a function that takes in two values and outputs a 3D vector functionsampler = RandomFunction(input_dim=2, output_dim=3)
def test_complex_rect(): """Tests the ComplexRectangle class""" restart = random.random() * 20 - 10 restop = random.random() * 20 - 10 if restart > restop: restart, restop = restop, restart imstart = random.random() * 20 - 10 imstop = random.random() * 20 - 10 if imstart > imstop: imstart, imstop = imstop, imstart cr = ComplexRectangle(re=[restart, restop], im=[imstart, imstop]) for _ in range(20): sample = cr.gen_sample() assert restart <= np.real(sample) <= restop assert imstart <= np.imag(sample) <= imstop
def test_fg_sampling(): """Test various sampling methods in FormulaGrader""" grader = FormulaGrader( answers="x^2+y^2+z^2", variables=['x', 'y', 'z', 'w'], sample_from={ 'x': 2, 'y': (1, 3, 5), 'z': [1, 5] } ) assert grader(None, 'x^2+y^2+z^2')['ok'] assert isinstance(grader.config["sample_from"]['x'], DiscreteSet) assert isinstance(grader.config["sample_from"]['y'], DiscreteSet) assert isinstance(grader.config["sample_from"]['z'], RealInterval) assert isinstance(grader.config["sample_from"]['w'], RealInterval) with raises(MultipleInvalid, match="extra keys not allowed @ data\['w'\]"): grader = FormulaGrader(variables=['x'], sample_from={'w': 2}) grader = FormulaGrader( answers="z^2", variables=['z'], sample_from={'z': ComplexSector()} ) assert grader(None, '(z-1)*(z+1)+1')['ok'] grader = FormulaGrader( answers="z^2", variables=['z'], sample_from={'z': ComplexRectangle()} ) assert grader(None, '(z-1)*(z+1)+1')['ok'] grader = FormulaGrader( answers="z^2", variables=['z'], sample_from={'z': IntegerRange()} ) assert grader(None, '(z-1)*(z+1)+1')['ok'] grader = FormulaGrader( answers="z^2", variables=['z'], sample_from={'z': RealInterval()} ) assert grader(None, '(z-1)*(z+1)+1')['ok'] grader = FormulaGrader( answers="z^2", variables=['z'], sample_from={'z': DiscreteSet((1, 3, 5))} ) assert grader(None, '(z-1)*(z+1)+1')['ok']
def test_identity_multiples(): # Test shape, identity times constant, MathArray shapes = tuple(range(2, 5)) samples = ([-1, 1], RealInterval(), ComplexRectangle()) for shape in shapes: for sample in samples: matrices = IdentityMatrixMultiples(dimension=shape, sampler=sample) m = matrices.gen_sample() assert m.shape == (shape, shape) assert np.array_equal(m, m[0, 0] * np.eye(shape)) assert isinstance(m, MathArray)
def test_overriding_functions(): grader = FormulaGrader(answers='z^2', variables=['z'], user_functions={ 're': RandomFunction(), 'im': RandomFunction() }, sample_from={'z': ComplexRectangle()}) learner_input = 're(z)^2 - im(z)^2 + 2*i*re(z)*im(z)' assert not grader(None, learner_input)['ok'] grader = FormulaGrader(answers='tan(1)', user_functions={'sin': lambda x: x}) assert grader(None, 'tan(1)')['ok'] assert not grader(None, 'sin(1)/cos(1)')['ok']
def test_fg_with_arrays(): grader = MatrixGrader(answers='x*A*B*u + z*C^3*v/(u*C*v)', variables=['A', 'B', 'C', 'u', 'v', 'z', 'x'], sample_from={ 'A': RealMatrices(shape=[2, 3]), 'B': RealMatrices(shape=[3, 2]), 'C': RealMatrices(shape=[2, 2]), 'u': RealVectors(shape=[2]), 'v': RealVectors(shape=[2]), 'z': ComplexRectangle() }, identity_dim=2) correct_0 = 'x*A*B*u + z*C^3*v/(u*C*v)' correct_1 = 'z*C^3*v/(u*C*v) + x*A*B*u' correct_2 = '(1/16)* z*(2*I)*(2*C)^3*v/(u*C*v) + x*A*B*u' correct_3 = '(1/16)* z*(2*I)*(2*C)^3*v/(v*trans(C)*u) + x*A*B*u/2 + 0.5*x*A*B*u' assert grader(None, correct_0)['ok'] assert grader(None, correct_1)['ok'] assert grader(None, correct_2)['ok'] assert grader(None, correct_3)['ok'] match = r"Cannot multiply a matrix of shape \(rows: 3, cols: 2\) with a matrix of shape \(rows: 3, cols: 2\)" with raises(ShapeError, match=match): grader(None, 'B*B') match = "Cannot raise a non-square matrix to powers." with raises(ShapeError, match=match): grader(None, 'B^2') match = "Cannot add/subtract scalars to a matrix." with raises(ShapeError, match=match): grader(None, 'B + 5') match = (r"There was an error evaluating function sin\(...\)<br/>" r"1st input has an error: received a matrix of shape " r"\(rows: 3, cols: 2\), expected a scalar") with raises(DomainError, match=match): grader(None, 'sin(B)')
def test_docs(): """Test that the documentation examples work as expected""" grader = FormulaGrader(answers='1+x^2+y', variables=['x', 'y']) assert grader(None, '1+x^2+y')['ok'] grader = FormulaGrader(answers='1+x^2+y+z/2', variables=['x', 'y', 'z'], sample_from={ 'x': ComplexRectangle(), 'y': [2, 6], 'z': (1, 3, 4, 8) }) assert grader(None, '1+x^2+y+z/2')['ok'] grader = FormulaGrader(answers='a_{0} + a_{1}*x + 1/2*a_{2}*x^2', variables=['x'], numbered_vars=['a'], sample_from={ 'x': [-5, 5], 'a': [-10, 10] }) assert grader(None, 'a_{0} + a_{1}*x + 1/2*a_{2}*x^2')['ok'] grader = FormulaGrader(answers='1+x^2', variables=['x'], samples=10) assert grader(None, '1+x^2')['ok'] grader = FormulaGrader(answers='1+x^2', variables=['x'], samples=10, failable_evals=1) assert grader(None, '1+x^2')['ok'] grader = FormulaGrader(answers='abs(z)^2', variables=['z'], sample_from={'z': ComplexRectangle()}) assert grader(None, 'abs(z)^2')['ok'] grader = FormulaGrader(answers='sqrt(1 - cos(x)^2)', variables=['x'], sample_from={'x': [0, np.pi]}, blacklist=['sin']) assert grader(None, 'sqrt(1 - cos(x)^2)')['ok'] grader = FormulaGrader(answers='sin(x)/cos(x)', variables=['x'], whitelist=['sin', 'cos']) assert grader(None, 'sin(x)/cos(x)')['ok'] grader = FormulaGrader(answers='pi/2-x', variables=['x'], whitelist=[None]) assert grader(None, 'pi/2-x')['ok'] grader = FormulaGrader(answers='2*sin(theta)*cos(theta)', variables=['theta'], required_functions=['sin', 'cos']) assert grader(None, '2*sin(theta)*cos(theta)')['ok'] grader = FormulaGrader(answers='x*x', variables=['x'], user_functions={'f': lambda x: x * x}) assert grader(None, 'x^2')['ok'] grader = FormulaGrader(answers="f''(x)", variables=['x'], user_functions={"f''": lambda x: x * x}) assert grader(None, "f''(x)")['ok'] grader = FormulaGrader(answers="x^2", variables=['x'], user_functions={"sin": lambda x: x * x}, suppress_warnings=True) assert grader(None, 'sin(x)')['ok'] grader = FormulaGrader(answers="f(x)", variables=['x'], user_functions={"f": [np.sin, np.cos]}) assert grader(None, 'f(x)')['ok'] grader = FormulaGrader(answers="f''(x) + omega^2*f(x)", variables=['x', 'omega'], user_functions={ "f": RandomFunction(), "f''": RandomFunction() }) assert grader(None, "f''(x)+omega^2*f(x)")['ok'] grader = FormulaGrader(answers='1/sqrt(1-v^2/c^2)', variables=['v'], user_constants={'c': 3e8}) assert grader(None, '1/sqrt(1-v^2/c^2)')['ok'] grader = FormulaGrader( answers='2*sin(theta)*cos(theta)', variables=['theta'], forbidden_strings=[ '*theta', 'theta*', 'theta/', '+theta', 'theta+', '-theta', 'theta-' ], forbidden_message= "Your answer should only use trigonometric functions acting on theta, not multiples of theta" ) assert grader(None, '2*sin(theta)*cos(theta)')['ok'] grader = FormulaGrader(answers='2*sin(theta)*cos(theta)', variables=['theta'], tolerance=0.00001) assert grader(None, '2*sin(theta)*cos(theta)')['ok'] grader = FormulaGrader(answers='2*m', variables=['m'], metric_suffixes=True) assert grader(None, '2*m')['ok'] assert not grader(None, '2m')['ok'] def is_coterminal(comparer_params_evals, student_eval, utils): answer = comparer_params_evals[0] reduced = student_eval % (360) return utils.within_tolerance(answer, reduced) grader = FormulaGrader(answers={ 'comparer': is_coterminal, 'comparer_params': ['b^2/a'], }, variables=['a', 'b'], tolerance='1%') assert grader(None, 'b^2/a')['ok'] assert grader(None, 'b^2/a + 720')['ok'] assert not grader(None, 'b^2/a + 225')['ok']
def test_fg_debug_log(): set_seed(0) grader = FormulaGrader(answers='x^2 + f(y) + z', variables=['x', 'y', 'z'], sample_from={'z': ComplexRectangle()}, blacklist=['sin', 'cos', 'tan'], user_functions={ 'f': RandomFunction(), 'square': lambda x: x**2 }, samples=2, debug=True) result = grader(None, 'z + x*x + f(y)') message = ( "<pre>MITx Grading Library Version {version}<br/>\n" "Student Response:<br/>\n" "z + x*x + f(y)<br/>\n" "<br/>\n" "==============================================================<br/>\n" "FormulaGrader Debug Info<br/>\n" "==============================================================<br/>\n" "Functions available during evaluation and allowed in answer:<br/>\n" "{{ 'abs': <function absolute at 0x...>,<br/>\n" " 'arccos': <function arccos at 0x...>,<br/>\n" " 'arccosh': <function arccosh at 0x...>,<br/>\n" " 'arccot': <function arccot at 0x...>,<br/>\n" " 'arccoth': <function arccoth at 0x...>,<br/>\n" " 'arccsc': <function arccsc at 0x...>,<br/>\n" " 'arccsch': <function arccsch at 0x...>,<br/>\n" " 'arcsec': <function arcsec at 0x...>,<br/>\n" " 'arcsech': <function arcsech at 0x...>,<br/>\n" " 'arcsin': <function arcsin at 0x...>,<br/>\n" " 'arcsinh': <function arcsinh at 0x...>,<br/>\n" " 'arctan': <function arctan at 0x...>,<br/>\n" " 'arctan2': <function arctan2 at 0x...>,<br/>\n" " 'arctanh': <function arctanh at 0x...>,<br/>\n" " 'conj': <ufunc 'conjugate'>,<br/>\n" " 'cosh': <function cosh at 0x...>,<br/>\n" " 'cot': <function cot at 0x...>,<br/>\n" " 'coth': <function coth at 0x...>,<br/>\n" " 'csc': <function csc at 0x...>,<br/>\n" " 'csch': <function csch at 0x...>,<br/>\n" " 'exp': <function exp at 0x...>,<br/>\n" " 'f': <function f at 0x...>,<br/>\n" " 'fact': <function factorial at 0x...>,<br/>\n" " 'factorial': <function factorial at 0x...>,<br/>\n" " 'im': <function imag at 0x...>,<br/>\n" " 'kronecker': <function kronecker at 0x...>,<br/>\n" " 'ln': <function log at 0x...>,<br/>\n" " 'log10': <function log10 at 0x...>,<br/>\n" " 'log2': <function log2 at 0x...>,<br/>\n" " 're': <function real at 0x...>,<br/>\n" " 'sec': <function sec at 0x...>,<br/>\n" " 'sech': <function sech at 0x...>,<br/>\n" " 'sinh': <function sinh at 0x...>,<br/>\n" " 'sqrt': <function sqrt at 0x...>,<br/>\n" " 'square': <function <lambda> at 0x...>,<br/>\n" " 'tanh': <function tanh at 0x...>}}<br/>\n" "Functions available during evaluation and disallowed in answer:<br/>\n" "{{ 'cos': <function cos at 0x...>,<br/>\n" " 'sin': <function sin at 0x...>,<br/>\n" " 'tan': <function tan at 0x...>}}<br/>\n" "<br/>\n" "<br/>\n" "==========================================<br/>\n" "Evaluation Data for Sample Number 1 of 2<br/>\n" "==========================================<br/>\n" "Variables:<br/>\n" "{{ 'e': 2.718281828459045,<br/>\n" " 'i': 1j,<br/>\n" " 'j': 1j,<br/>\n" " 'pi': 3.141592653589793,<br/>\n" " 'x': 3.195254015709299,<br/>\n" " 'y': 3.860757465489678,<br/>\n" " 'z': (2.205526752143288+2.0897663659937935j)}}<br/>\n" "Student Eval: (14.7111745179+2.08976636599j)<br/>\n" "Compare to: [(14.711174517877566+2.0897663659937935j)]<br/>\n" "Comparer Function: <function equality_comparer at 0x...><br/>\n" "Comparison Result: {{ 'grade_decimal': 1.0, 'msg': '', 'ok': True}}<br/>\n" "<br/>\n" "<br/>\n" "==========================================<br/>\n" "Evaluation Data for Sample Number 2 of 2<br/>\n" "==========================================<br/>\n" "Variables:<br/>\n" "{{ 'e': 2.718281828459045,<br/>\n" " 'i': 1j,<br/>\n" " 'j': 1j,<br/>\n" " 'pi': 3.141592653589793,<br/>\n" " 'x': 2.694619197355619,<br/>\n" " 'y': 3.5835764522666245,<br/>\n" " 'z': (1.875174422525385+2.7835460015641598j)}}<br/>\n" "Student Eval: (11.9397106851+2.78354600156j)<br/>\n" "Compare to: [(11.93971068506166+2.7835460015641598j)]<br/>\n" "Comparer Function: <function equality_comparer at 0x...><br/>\n" "Comparison Result: {{ 'grade_decimal': 1.0, 'msg': '', 'ok': True}}<br/>\n" "</pre>").format(version=VERSION) assert result['msg'] == message
def test_docs(): """Test that the documentation examples work as expected""" grader = FormulaGrader(answers='1+x^2+y', variables=['x', 'y']) assert grader(None, '1+x^2+y')['ok'] grader = FormulaGrader(answers='1+x^2+y+z/2', variables=['x', 'y', 'z'], sample_from={ 'x': ComplexRectangle(), 'y': [2, 6], 'z': (1, 3, 4, 8) }) assert grader(None, '1+x^2+y+z/2')['ok'] grader = FormulaGrader(answers='1+x^2', variables=['x'], samples=10) assert grader(None, '1+x^2')['ok'] grader = FormulaGrader(answers='1+x^2', variables=['x'], samples=10, failable_evals=1) assert grader(None, '1+x^2')['ok'] grader = FormulaGrader(answers='abs(z)^2', variables=['z'], sample_from={'z': ComplexRectangle()}) assert grader(None, 'abs(z)^2')['ok'] grader = FormulaGrader(answers='sqrt(1 - cos(x)^2)', variables=['x'], sample_from={'x': [0, np.pi]}, blacklist=['sin']) assert grader(None, 'sqrt(1 - cos(x)^2)')['ok'] grader = FormulaGrader(answers='sin(x)/cos(x)', variables=['x'], whitelist=['sin', 'cos']) assert grader(None, 'sin(x)/cos(x)')['ok'] grader = FormulaGrader(answers='pi/2-x', variables=['x'], whitelist=[None]) assert grader(None, 'pi/2-x')['ok'] grader = FormulaGrader(answers='2*sin(theta)*cos(theta)', variables=['theta'], required_functions=['sin', 'cos']) assert grader(None, '2*sin(theta)*cos(theta)')['ok'] grader = FormulaGrader(answers='x*x', variables=['x'], user_functions={'f': lambda x: x * x}) assert grader(None, 'x^2')['ok'] grader = FormulaGrader(answers="f''(x)", variables=['x'], user_functions={"f''": lambda x: x * x}) assert grader(None, "f''(x)")['ok'] grader = FormulaGrader(answers="x^2", variables=['x'], user_functions={"sin": lambda x: x * x}) assert grader(None, 'sin(x)')['ok'] grader = FormulaGrader(answers="f(x)", variables=['x'], user_functions={"f": [np.sin, np.cos]}) assert grader(None, 'f(x)')['ok'] grader = FormulaGrader(answers="f''(x) + omega^2*f(x)", variables=['x', 'omega'], user_functions={ "f": RandomFunction(), "f''": RandomFunction() }) assert grader(None, "f''(x)+omega^2*f(x)")['ok'] grader = FormulaGrader(answers='1/sqrt(1-v^2/c^2)', variables=['v'], user_constants={'c': 3e8}) assert grader(None, '1/sqrt(1-v^2/c^2)')['ok'] grader = FormulaGrader( answers='2*sin(theta)*cos(theta)', variables=['theta'], forbidden_strings=[ '*theta', 'theta*', 'theta/', '+theta', 'theta+', '-theta', 'theta-' ], forbidden_message= "Your answer should only use trigonometric functions acting on theta, not multiples of theta" ) assert grader(None, '2*sin(theta)*cos(theta)')['ok'] grader = FormulaGrader(answers='2*sin(theta)*cos(theta)', variables=['theta'], tolerance=0.00001) assert grader(None, '2*sin(theta)*cos(theta)')['ok'] grader = FormulaGrader(answers='2*sin(theta)*cos(theta)', variables=['theta'], case_sensitive=False) assert grader(None, '2*Sin(theta)*Cos(theta)')['ok'] grader = FormulaGrader(answers='2*m', variables=['m'], metric_suffixes=True) assert grader(None, '2*m')['ok'] assert not grader(None, '2m')['ok']
def test_fg_debug_log(): set_seed(0) grader = FormulaGrader(answers='x^2 + f(y) + z', variables=['x', 'y', 'z'], sample_from={'z': ComplexRectangle()}, blacklist=['sin', 'cos', 'tan'], user_functions={ 'f': RandomFunction(), 'square': squareit }, samples=2, debug=True) result = grader(None, 'z + x*x + f(y)') message = ( "<pre>MITx Grading Library Version {version}<br/>\n" "Running on edX using python {python_version}<br/>\n" "Student Response:<br/>\n" "z + x*x + f(y)<br/>\n" "<br/>\n" "==============================================================<br/>\n" "FormulaGrader Debug Info<br/>\n" "==============================================================<br/>\n" "Functions available during evaluation and allowed in answer:<br/>\n" "{{{u}'abs': <function absolute at 0x...>,<br/>\n" " {u}'arccos': <function arccos at 0x...>,<br/>\n" " {u}'arccosh': <function arccosh at 0x...>,<br/>\n" " {u}'arccot': <function arccot at 0x...>,<br/>\n" " {u}'arccoth': <function arccoth at 0x...>,<br/>\n" " {u}'arccsc': <function arccsc at 0x...>,<br/>\n" " {u}'arccsch': <function arccsch at 0x...>,<br/>\n" " {u}'arcsec': <function arcsec at 0x...>,<br/>\n" " {u}'arcsech': <function arcsech at 0x...>,<br/>\n" " {u}'arcsin': <function arcsin at 0x...>,<br/>\n" " {u}'arcsinh': <function arcsinh at 0x...>,<br/>\n" " {u}'arctan': <function arctan at 0x...>,<br/>\n" " {u}'arctan2': <function arctan2 at 0x...>,<br/>\n" " {u}'arctanh': <function arctanh at 0x...>,<br/>\n" " {u}'ceil': <function ceil at 0x...>,<br/>\n" " {u}'conj': <ufunc 'conjugate'>,<br/>\n" " {u}'cosh': <function cosh at 0x...>,<br/>\n" " {u}'cot': <function cot at 0x...>,<br/>\n" " {u}'coth': <function coth at 0x...>,<br/>\n" " {u}'csc': <function csc at 0x...>,<br/>\n" " {u}'csch': <function csch at 0x...>,<br/>\n" " {u}'exp': <function exp at 0x...>,<br/>\n" " {u}'f': <function random_function at 0x...>,<br/>\n" " {u}'fact': <function factorial at 0x...>,<br/>\n" " {u}'factorial': <function factorial at 0x...>,<br/>\n" " {u}'floor': <function floor at 0x...>,<br/>\n" " {u}'im': <function imag at 0x...>,<br/>\n" " {u}'kronecker': <function kronecker at 0x...>,<br/>\n" " {u}'ln': <function log at 0x...>,<br/>\n" " {u}'log10': <function log10 at 0x...>,<br/>\n" " {u}'log2': <function log2 at 0x...>,<br/>\n" " {u}'max': <function max at 0x...>,<br/>\n" " {u}'min': <function min at 0x...>,<br/>\n" " {u}'re': <function real at 0x...>,<br/>\n" " {u}'sec': <function sec at 0x...>,<br/>\n" " {u}'sech': <function sech at 0x...>,<br/>\n" " {u}'sinh': <function sinh at 0x...>,<br/>\n" " {u}'sqrt': <function sqrt at 0x...>,<br/>\n" " {u}'square': <function squareit at 0x...>,<br/>\n" " {u}'tanh': <function tanh at 0x...>}}<br/>\n" "Functions available during evaluation and disallowed in answer:<br/>\n" "{{{u}'cos': <function cos at 0x...>,<br/>\n" " {u}'sin': <function sin at 0x...>,<br/>\n" " {u}'tan': <function tan at 0x...>}}<br/>\n" "<br/>\n" "<br/>\n" "==========================================<br/>\n" "Evaluation Data for Sample Number 1 of 2<br/>\n" "==========================================<br/>\n" "Variables:<br/>\n" "{{{u}'e': 2.718281828459045,<br/>\n" " {u}'i': 1j,<br/>\n" " {u}'j': 1j,<br/>\n" " {u}'pi': 3.141592653589793,<br/>\n" " {u}'x': 3.195254015709299,<br/>\n" " {u}'y': 3.860757465489678,<br/>\n" " {u}'z': (2.205526752143288+2.0897663659937935j)}}<br/>\n" "Student Eval: (14.7111745179+2.08976636599j)<br/>\n" "Compare to: [(14.711174517877566+2.0897663659937935j)]<br/>\n" "<br/>\n" "<br/>\n" "==========================================<br/>\n" "Evaluation Data for Sample Number 2 of 2<br/>\n" "==========================================<br/>\n" "Variables:<br/>\n" "{{{u}'e': 2.718281828459045,<br/>\n" " {u}'i': 1j,<br/>\n" " {u}'j': 1j,<br/>\n" " {u}'pi': 3.141592653589793,<br/>\n" " {u}'x': 2.694619197355619,<br/>\n" " {u}'y': 3.5835764522666245,<br/>\n" " {u}'z': (1.875174422525385+2.7835460015641598j)}}<br/>\n" "Student Eval: (11.9397106851+2.78354600156j)<br/>\n" "Compare to: [(11.93971068506166+2.7835460015641598j)]<br/>\n" "<br/>\n" "<br/>\n" "==========================================<br/>\n" "Comparison Data for All 2 Samples<br/>\n" "==========================================<br/>\n" "Comparer Function: EqualityComparer({{{u}'transform': <function identity_transform at 0x...>}})<br/>\n" "Comparison Results:<br/>\n" "[{{{u}'grade_decimal': 1.0, {u}'msg': {u}'', {u}'ok': True}},<br/>\n" " {{{u}'grade_decimal': 1.0, {u}'msg': {u}'', {u}'ok': True}}]<br/>\n" "</pre>").format(version=VERSION, python_version=platform.python_version(), u=UNICODE_PREFIX) message = message.replace("<func", "<func").replace("...>", "...>") expected = round_decimals_in_string(message) result_msg = round_decimals_in_string(result['msg']).replace( 'test_fg_debug_log.<locals>.', '') assert expected == result_msg