Beispiel #1
0
def test_mathify_pythonify():
    math2python = {
        Integer(1): 1,
        Integer(1) / 2: fractions.Fraction(1, 2),
        Integer(3) / (-5): fractions.Fraction(-3, 5),
        Pow(4, 2): fractions.Fraction(4)**2,
        Pow(5, 3): 5**3,
    }

    # keys() and values() are guaranteed to be in the same order, although a
    # different order shouldn't matter
    math_sum = Add(math2python.keys())  # not gentle_simplify()ied
    python_sum = sum(math2python.values())
    math2python[math_sum] = python_sum

    math_product = Mul(math2python.keys())
    python_product = functools.reduce(operator.mul, math2python.values())
    math2python[math_product] = python_product

    for math, python in math2python.items():
        assert mathify(math) == math  # returned as is
        assert mathify(python) == math.gentle_simplify()
        assert pythonify(math) == python
        assert pythonify(python) == python

    # make sure that fractions aren't returned when not needed
    assert type(mathify(fractions.Fraction(2, 1))) is Integer
    assert type(pythonify(Mul([4, half]))) is int

    with pytest.raises(TypeError, match="don't know how to pythonify <Toot>$"):
        pythonify(Toot())
    with pytest.raises(TypeError, match="don't know how to mathify 'lol'$"):
        mathify('lol')
Beispiel #2
0
def test_pow_gentle_simplify():
    # these simplify to 0 and 1
    weird0 = Add([x, -x])
    weird1 = Mul([x, 1 / x])
    assert weird0 != mathify(0)
    assert weird1 != mathify(1)
    assert weird0.gentle_simplify() == mathify(0)
    assert weird1.gentle_simplify() == mathify(1)

    assert Pow(x, Thing()).gentle_simplify() == Pow(x, Thing(True))
    assert Pow(Thing(), y).gentle_simplify() == Pow(Thing(True), y)
    assert Pow(Pow(x, y), z).gentle_simplify() == Pow(x, y * z)
    assert Pow(x * y, z).gentle_simplify() == Mul([Pow(x, z), Pow(y, z)])
    assert Pow(weird0, x).gentle_simplify() == mathify(0)
    assert Pow(weird1, x).gentle_simplify() == mathify(1)
    assert Pow(weird0, weird0).gentle_simplify() == mathify(0**0)
    assert Pow(x, weird0).gentle_simplify() == mathify(1)
    assert Pow(x, weird1).gentle_simplify() == x

    assert Pow(2, 3).gentle_simplify() == mathify(8)
    assert isinstance(Pow(2, -3).gentle_simplify(), Pow)

    for base in range(-10, 10):
        for exponent in range(-10, 10):
            try:
                value = base**exponent
            except ZeroDivisionError:
                continue  # TODO: derivater should also raise an error :(

            simplified = Pow(base, exponent).gentle_simplify()
            if abs(value - int(value)) > 1e-12:
                # not an integer
                assert isinstance(simplified, Pow)
            else:
                assert simplified == mathify(int(value))
Beispiel #3
0
def test_derivatives():
    with pytest.raises(ValueError,
                       match="negative derivative_count is not supported$"):
        f(x, derivative_count=-1)

    assert x.derivative(x) == mathify(1)
    assert x.derivative(y) == mathify(0)
    assert f(x).derivative(x) == f_(x)
    assert f(x).derivative(x).derivative(x) == f__(x)
    assert f(x).derivative(y) == mathify(0)
    assert f(
        g(x)).derivative(x) == f_(g(x)) * g_(x), "u forgot chain rule n00b"
Beispiel #4
0
def test_minus():
    assert isinstance(-x, Mul)
    assert (-x).objects == [mathify(-1), x]
    assert -(-x) == x

    assert isinstance(x - y, Add)
    assert (x - y).objects == [x, -y]
Beispiel #5
0
def test_mul_gentle_simplify():
    assert Mul([x, y, Thing()]).gentle_simplify() == Mul([x, y, Thing(True)])
    assert (Mul([x, y, Mul([z, Thing()])
                 ]).gentle_simplify() == Mul([x, y, z, Thing(True)]))
    assert Mul([1, x, 2, y, 3]).gentle_simplify() == Mul([6, x, y])
    assert Mul([1, x, 2, y, 3]).gentle_simplify().objects[0] == mathify(6)
    assert Mul([1, x, y]).gentle_simplify() == Mul([x, y])
    assert (Mul([x, y, x**a, y,
                 x**b]).gentle_simplify() == Mul([x**(a + b + 1), y**2]))
    assert Mul([x]).gentle_simplify() == x
    assert Mul([x, x]).gentle_simplify() == x**2
    assert Mul([]).gentle_simplify() == mathify(1)
    assert Mul([x, 1 / x]).gentle_simplify() == mathify(1)

    # these were broken in old derivater versions
    assert Mul([x, y, 1 / x]).gentle_simplify() == y
    assert Mul([x, 1 / x]).gentle_simplify() == mathify(1)
Beispiel #6
0
def test_add_gentle_simplify():
    assert Add([x, y, Thing()]).gentle_simplify() == Add([x, y, Thing(True)])
    assert (Add([x, y, Add([z, Thing()])
                 ]).gentle_simplify() == Add([x, y, z, Thing(True)]))
    assert Add([1, x, 2, y, 3]).gentle_simplify() == Add([x, y, 6])
    assert Add([1, x, 2, y, 3]).gentle_simplify().objects[-1] == mathify(6)
    assert Add([x, x, y]).gentle_simplify() == Add([2 * x, y])
    assert Add([2 * x, 3 * y, 4 * x]).gentle_simplify() == Add([6 * x, 3 * y])
    assert Add([x, x]).gentle_simplify() == 2 * x
    assert Add([y]).gentle_simplify() == y
    assert Add([2 * x, -2 * x]).gentle_simplify() == mathify(0)
    assert Add([]).gentle_simplify() == mathify(0)

    assert Add([2, x, half]).gentle_simplify().objects == [x, half * 5]
    assert Add([3 * x, half * x]).gentle_simplify() == half * 7 * x

    # these were broken in old derivater versions
    assert Add([x, y, -x]).gentle_simplify() == y
    assert Add([x, -x]).gentle_simplify() == mathify(0)
Beispiel #7
0
def test_default_may_depend_on_and_derivative():
    assert not MathObject().may_depend_on(x)  # must be overrided if depdends

    assert not Toot().may_depend_on(x)
    assert Toot().may_depend_on(y)
    assert Toot().derivative(x) == mathify(0)
    with pytest.raises(TypeError,
                       match=(r"cannot take derivative of <Toot> "
                              r"with respect to y$")):
        Toot().derivative(y)
Beispiel #8
0
def test_with_fraction_coeff():
    assert Pow(3, 4).with_fraction_coeff() == (Pow(3, 4), mathify(1))
    assert Pow(3, -4).with_fraction_coeff() == (Pow(3, -4), mathify(1))
    assert Mul([2, Pow(3, -4)]).with_fraction_coeff() == (mathify(2) / 81,
                                                          mathify(1))
    assert Mul([half, x, 3]).with_fraction_coeff() == (half * 3, x)
    assert Add([2 * x / 3, 4 * y / 5
                ]).with_fraction_coeff() == (mathify(2) / 15, 5 * x + 6 * y)
    assert Add([]).with_fraction_coeff() == (mathify(1), Add([]))
Beispiel #9
0
def test_automagic_mathify():
    assert f(2).arg == mathify(2)
Beispiel #10
0
 def __init__(self, content):
     self.content = mathify(content)
Beispiel #11
0
def test_integers():
    for n in [-10, -1, 0, 1, 10]:
        assert mathify(n) == Integer(n)
        assert mathify(n).python_int == n
        assert not mathify(n).may_depend_on(x)
        assert mathify(n).with_fraction_coeff() == (mathify(n), mathify(1))

        assert not repr(mathify(n)).startswith('(')
        assert not repr(mathify(n)).endswith(')')
        if n < 0:
            assert mathify(n).add_parenthesize().startswith('(-')
            assert mathify(n).add_parenthesize().endswith(')')
        else:
            assert mathify(n).add_parenthesize() == repr(mathify(n)) == repr(n)

    with pytest.raises(TypeError, match=r"cannot create Integer of 'lol'$"):
        Integer('lol')

    # "cannot create Integer of 2" would be a very confusing error message
    with pytest.raises(TypeError,
                       match=r"cannot create a new Integer of an Integer$"):
        Integer(Integer(2))