Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Hello, @moon! I am not 100% sure of what you want, but perhaps the following works for you?

import operator as op  # Python's standard library of operators (+, -, <, >, <=, >=, etc.)
oper = [op.gt, op.ge, op.lt, op.le]  # store the operators themselves instead of strings
# The following is as in your code:
a = randint(-20, 20)
b=randint(-10, 10)
c, d=0, 0
while c*x+d == 0:
    c = randint(-20, 20)
    d = randint(-10, 10)
f = (a*x + b) / (c*x + d)
a = randint(-20, 20)
b = randint(-10, 10)

c, d = 0, 0
while c*x+d == 0:
    c = randint(-20, 20)
    d = randint(-10, 10)
g = (a*x + b) / (c*x + d)

# The following is what does what you want (explained below)
expr = sample(oper,1)[0](f, g)  # (1)
show(expr)  # (2)
print(solve(expr, x))  # (3)
print(latex(expr))  # (4)

Line (1) takes one random element from ´oper´. For example, ´oper[0]´ is ´op.gt´, which is equivalent to ´>´; ´oper[1]´ is ´op.ge´, ehich is equivalent to ´>=´, etc. The part ´sample(oper,1)[0]´ chooses one of them, as you already know. Now, this operators are actually functions (in the programming sense), so you should write ´op.gt(f, g)´ instead of ´f > g´. That is why we have the ´(f, g)´ part in (1). This is an expression, as far as Sage concerns, so we call it, creatively enough, ´expr´.

Line (2) is there just to show the resulting expression. Line (3) is to show that you can use ´solve´ without ´eval´ (remember, because ´expr´ is already an expression). Finally, what you wanted: line (4) shows that this expression can be readily converted to LaTeX without using ´eval´; this should preserve the structure of the expression, as far as I know.

Additionally, please allow me to make a couple of suggestions:

  1. Instead of using ´sample(oper,1)[0]´, it could be better to use Sage's ´choice´ function, which I believe should be more clearly readable and more efficient (given that it is design exactly for the purpose of making a random choice from a list). Then, line (1) should become

    expr = choice(oper)(f, g)
    
  2. The ´while´ loops could be more clearly written as

    while (c == 0 and d == 0):
    

    This is equivalent to the form you wrote, but it's more standard.

  3. Depending on how many times you want to use line (1) or in the alternative form of the previous suggestion, it could be convenient to encapsulate it in a function like

    def ineq(f, g):
        return choice(oper)(f, g)
    

This is possible, given that Sage can work with expressions. The reason why this could be convenient, is because it more clear to write, for example, ´solve(ineq(f,g), x)´ than ´solve(choice(oper)(f,g), x)´. However, there is the possibility to store in a variable, as you do, so perhaps this is not as much a suggestion as it is an alternative approach. Alas, I not 100% sure if it's worth.

I hope this helps!