Feature Creep 2026, 05 - A Mental Math Trainer - Not Sure What I Did Last Week, Happy Testing

On the equation-generator front, I thought I might get away with just calling some sympy evaluation call. As it is, the equations will come out as strings, that are basically latex code. From what I know, sympy can interface between python and latex code, but I've never really used it before. Upon cursory reading, I should be able to do something like this:

import sympy
from sympy.parsing.latex import parse_latex

def equation_eval(latex_string):
  as_symbol = parse_latex(latex_string)
  result = eval(as_symbol)

I've been told in the past that eval() is evil, and while I'm inclined to agree, considering the script will have generated what goes into eval() itself, I don't mind it being there as much. Perhaps there's a better way of doing that within the sympy framework, but until I find that version of doing things, I'll stick to eval() and move on.

Beyond that, I had to still set up the mongodb database, and I personally wanted to include testing as I go on with development. The easiest thing to test is the eval function, so I wrote some simple tests.

import python                                                                                                                                                                                 
import generator

gen = generator.equation_generator()

def is_legit(val):
    success = False

    try:
        if float(val) != None:
            success = True
    except:
        pass
    return success

def test_operators():
    teststr = "(\\frac{4}{2} - 3) * (5 + 4/2)"
    value = "7" 

    assert gen.evaluate(value) == gen.evaluate(teststr)

def test_gen_operators():
    expr = gen.simple_linked()
    val = gen.evaluate(expr)

    assert is_legit(val) == True

def test_integral_solve_for_x():
    teststr = "5 + 6 - x = 4"
    value = "7" 

    assert gen.evaluate(value) == gen.evaluate(teststr)

def test_gen_function():
    expr = gen.get_simple_function('x')
    assert 'x' in expr

    val = gen.evaluate(expr)
    assert is_legit(val) == True

def test_derivative():
    teststr = "\\frac{d}{dx} x^2 + x^3"
    value = "2x + 3x^2"

    assert gen.evaluate(value) == gen.evaluate(teststr)

def test_integral_indefinite():
    teststr = "\\int{dx} x^2 + x"
    value = "\\frac{1}{3}x^3 + \\frac{1}{2}x^2"

    assert gen.evaluate(value) == gen.evaluate(teststr)

Beyond this, there's a lot of other tests of this style which mainly serve as a way to check whether the evaluator can deal with the latex symbol correctly. The actual module is meant to test the generator functions and evaluate whether the output is good.

I also implemented a function generator, which basically recycles last week's expression generator and inserts the variable name somewhere appropriate. The "appropriate" part was a point of contention, and I'm starting to think that I'll have to build a tokenizer later, because my solution won't be able to deal with sin or cos in the expression. However, as it is, I would be able to easily implement the solution once I've thought through the tokenizer.

def get_simple_function(self, varname):
        expr = self.simple_linked()
        idxarray = []

        while len(idxarray) == 0:
            for char_idx in range(0, len(expr)):
                if random.randrange(1, 100) > 80 and
                        expr[char_idx] != len(expr) - 1:
                    if (varname != [expr[char_idx], expr[char_idx + 1]]):
                        idxarray.append(char_idx)

        for k in range(0, idxarray - 1):
            expr.push(varname, idxarray[len(idxarray) - 1 - k])

        return expr
Previous
Previous

Feature Creep 2026, 06 - A Mental Math Trainer - Tokenizer and Debugging the Tests

Next
Next

Feature Creep 2026, 04 - A Mental Math Trainer - Code-Generating Some LaTeX