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