# Evaluate from string an equation that has integer division

I have the following Python list that contains strings of equations.

L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']


You can see that all of the equations have integer division. Because this is obtained by some program, I can not edit the strings.

When I evaluate for t=1.0 with the following code in SageMath (for example), it does not evaluate as an Euclidean division.

F = function('F')(t)
for k in L:
F(t) = eval(k)
Fc = fast_callable(F, vars=[t])
val2eval = 1.0
print(Fc(val2eval).n(13))


It gives

1.00000000000000
1.00000000000000
2.00000000000000


And should be give

1.86587997307599
1.00029510077345
2.86617507384944


Of course I can solve this by modifying MANUALLY the strings of the equations by indicating that the denominator is a real number and not an integer (I put a decimal point at the end of the integer in the denominator) as following.

L = ['651/349.*t + 5382747/9778631000.', 't + 57879/196133000.', '1000/349.*t + 57879/68450417.']


But this is not the idea, the strings of the equations are generated automatically and one can not modify by editing manually, because it will be implemented in a process where it should be create at least 2000 equations.

Is there some elegant solution for this? --Many thanks!

edit retag close merge delete

Sort by ยป oldest newest most voted

One solution is to use Python3-style division, where the quotient of two integers is a floating-point number.

The simplest way is to import division from __future__:

Use .n(digits=13) to get 13 decimal digits; using .n(13) gives 13 bits of precision, so only 3 decimal digits.

sage: from __future__ import division
sage: L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
sage: t = SR.var('t')
sage: F = function('F')(t)
sage: for k in L:
....:     F(t) = eval(k)
....:     Fc = fast_callable(F, vars=[t])
....:     val2eval = 1.0
....:     print(Fc(val2eval).n(digits=13))
....:
1.865879973076
1.000295100773
2.866175073849

more

I put the sentence from __future__ import division at the beginning of my file 'twophasevolumeweightunsat.sage' and I become the following Error Message:

sage: load('twophasevolumeweightunsat.sage')
File "<string>", line 2
SyntaxError: from __future__ imports must occur at the beginning of the file

( 2018-11-20 17:45:13 +0200 )edit

I'm using 'SageMath version 7.5.1, Release Date: 2017-01-15' because I could not install the new SageMath 8.X., this is another problem I would afford next.

( 2018-11-20 17:47:28 +0200 )edit

You could try putting the import statement at the start of the init.sage file in the .sage folder in your home directory. Create the init.sage file if it does not exist yet.

( 2018-11-20 18:22:39 +0200 )edit

Or you could convert your file twophasevolumeweightunsat.sage into twophasevolumeweightunsat.py; this might involve modifying your code to turn it into pure Python syntax, and adding imports for all the Sage functions that are used in this file.

( 2018-11-20 18:24:59 +0200 )edit

If you want to parse strings in the way that the sage prompt does it, you could use

eval(preparse(k))


It's also a little wasteful to call

F(t)=eval(preparse(k))


(that's not valid python syntax. The preparser does quite a bit with that as well). In fact, if you know you want to parse the strings into symbolic expressions, you might want to call

F=symbolic_expression(k).function(t)


if you want F to be a function in t rather than just an expression.

more