Ticket #3484: trac3484-sage_eval.patch
| File trac3484-sage_eval.patch, 6.1 kB (added by cwitty, 7 months ago) |
|---|
-
a/sage/misc/sage_eval.py
old new 10 10 # http://www.gnu.org/licenses/ 11 11 #***************************************************************************** 12 12 13 from preparser import preparse 13 from copy import copy 14 import preparser 14 15 15 def sage_eval(source, locals= {}):16 def sage_eval(source, locals=None, cmds='', preparse=True): 16 17 r""" 17 Obtain a \SAGE object from the input string by evaluat eit using18 S AGE. This means calling eval after preparsing and with18 Obtain a \SAGE object from the input string by evaluating it using 19 Sage. This means calling eval after preparsing and with 19 20 globals equal to everything included in the scope of 20 21 \code{from sage.all import *}.). 21 22 If the object has an _sage_ method it is called and the value is23 returned. Otherwise str is called on the object, and all24 preparsing is applied and the resulting expression is evaluated in the25 context of \code{from sage.all import *}. To evaluate the26 expression with certain variables set, use the locals argument,27 which should be a dictionary.28 22 29 23 EXAMPLES: 30 24 This example illustrates that preparsing is applied. … … 33 27 sage: sage_eval('2^3') 34 28 8 35 29 36 Note that you have explicitly define variables and pass 30 However, preparsing can be turned off. 31 32 sage: sage_eval('2^3', preparse=False) 33 1 34 35 Note that you can explicitly define variables and pass 37 36 them as the second option: 38 37 39 38 sage: x = PolynomialRing(RationalField(),"x").gen() 40 39 sage: sage_eval('x^2+1', locals={'x':x}) 41 40 x^2 + 1 42 43 This illustrates interfaces:44 sage: f = gp('2/3')45 sage: type(f)46 <class 'sage.interfaces.gp.GpElement'>47 sage: f._sage_()48 2/349 sage: type(f._sage_())50 <type 'sage.rings.rational.Rational'>51 sage: a = gap(939393/2433)52 sage: a._sage_()53 313131/81154 sage: type(a._sage_())55 <type 'sage.rings.rational.Rational'>56 41 57 42 This example illustrates that evaluation occurs in the context of 58 43 \code{from sage.all import *}. Even though bernoulli has been … … 83 68 sage: sage_eval('4/3 + x', locals={'x':25}) 84 69 79/3 85 70 71 You can also specify a sequence of commands to be run before the 72 expression is evaluated: 73 sage: sage_eval('p', cmds='K.<x> = QQ[]\np = x^2 + 1') 74 x^2 + 1 75 76 If you give commands to execute and a dictionary of variables, then 77 the dictionary will be modified by assignments in the commands: 78 sage: vars = {} 79 sage: sage_eval('None', cmds='y = 3', locals=vars) 80 sage: vars['y'], parent(vars['y']) 81 (3, Integer Ring) 82 83 You can also specify the object to evaluate as a tuple. A 2-tuple 84 is assumed to be a pair of a command sequence and an expression; 85 a 3-tuple is assumed to be a triple of a command sequence, an expression, 86 and a dictionary holding local variables. (In this case, the given 87 dictionary will not be modified by assignments in the commands.) 88 sage: sage_eval(('f(x) = x^2', 'f(3)')) 89 9 90 sage: vars = {'rt2': sqrt(2.0)} 91 sage: sage_eval(('rt2 += 1', 'rt2', vars)) 92 2.41421356237309 93 sage: vars['rt2'] 94 1.41421356237310 95 86 96 This example illustrates how \code{sage_eval} can be useful 87 97 when evaluating the output of other computer algebra systems. 88 98 … … 101 111 102 112 Here you can see eval simply will not work but \code{sage_eval} will. 103 113 """ 114 if isinstance(source, (list, tuple)): 115 cmds = source[0] 116 if len(source) > 2: 117 locals = copy(source[2]) 118 source = source[1] 119 104 120 if not isinstance(source, basestring): 105 121 raise TypeError, "source must be a string." 106 122 123 if locals is None: 124 locals = {} 125 107 126 import sage.all 108 p = preparse(source) 127 if len(cmds): 128 cmd_seq = cmds + '\n_sage_eval_returnval_ = ' + source 129 if preparse: 130 cmd_seq = preparser.preparse_file(cmd_seq) 131 else: 132 if preparse: 133 source = preparser.preparse(source) 109 134 try: 110 return eval(p, sage.all.__dict__, locals) 135 if len(cmds): 136 exec cmd_seq in sage.all.__dict__, locals 137 return locals['_sage_eval_returnval_'] 138 else: 139 return eval(source, sage.all.__dict__, locals) 111 140 except SyntaxError, msg: 112 raise SyntaxError, "%s\nError using SAGE to evaluate '%s'"%(msg, p)141 raise SyntaxError, "%s\nError using SAGE to evaluate '%s'"%(msg, cmd_seq if len(cmds) else source) 113 142 114 143 115 144 … … 118 147 Return a native SAGE object associated to x, if possible 119 148 and implemented. 120 149 121 If x is a string it is evaluated with SAGE preparsing. 150 If the object has an _sage_ method it is called and the value is 151 returned. Otherwise str is called on the object, and all 152 preparsing is applied and the resulting expression is evaluated in the 153 context of \code{from sage.all import *}. To evaluate the 154 expression with certain variables set, use the vars argument, 155 which should be a dictionary. 122 156 123 157 EXAMPLES: 124 158 sage: type(sageobj(gp('34/56'))) … … 130 164 512 131 165 sage: type(k) 132 166 <type 'sage.rings.integer.Integer'> 167 168 This illustrates interfaces: 169 sage: f = gp('2/3') 170 sage: type(f) 171 <class 'sage.interfaces.gp.GpElement'> 172 sage: f._sage_() 173 2/3 174 sage: type(f._sage_()) 175 <type 'sage.rings.rational.Rational'> 176 sage: a = gap(939393/2433) 177 sage: a._sage_() 178 313131/811 179 sage: type(a._sage_()) 180 <type 'sage.rings.rational.Rational'> 133 181 """ 134 182 try: 135 183 return x._sage_()