【问题标题】:Sympy refuses to calculate valuesSympy 拒绝计算值
【发布时间】:2014-05-02 14:20:10
【问题描述】:

我正在尝试实现一种类似 Markdown 的语言来进行数学运算。基本想法是有一个文件,你可以在其中写下你的数学,然后有一个 python 脚本进行计算并吐出 tex。

但是,我正面临一个问题,即 Sympy 拒绝吐出值,它只会让我回到等式。更奇怪的是,它确实在备用测试脚本中吐出值,这基本上是相同的代码。

这是工作代码:

import sympy as sp
m = sp.symbols('m')
kg = sp.symbols('kg')
s = sp.symbols('s')
g = sp.sympify(9.80665*m/s**2)
mass = sp.sympify(0.2*kg)
acc = sp.sympify(g)
F = sp.sympify(mass*acc)
print F

输出:

1.96133*kg*m/s**2

这是无效的代码:

import re
import sympy as sp
print 'import sympy as sp'

#read units
mymunits = 'units.mymu'
with open(mymunits) as mymu:
    mymuinput = mymu.readlines()
    for lines in mymuinput:
        lines = re.sub('\s+','',lines).split()
        if lines != []:
            if lines[0][0] != '#':
                unit = lines[0].split('#')[0]
                globals()[unit] = sp.symbols(unit)
                print unit+' = sp.symbols(\''+unit+'\')'

#read constants
mymconstants = 'constants.mymc'
with open(mymconstants) as mymc:
    mymcinput = mymc.readlines()
    for lines in mymcinput:
        lines = re.sub('\s+','',lines).split()
        if lines != []:
            if lines[0][0] != '#':
                constant = lines[0].split('#')[0].split(':=')
                globals()[constant[0]] = sp.sympify(constant[1])
                print constant[0]+' = sp.sympify('+constant[1]+')'

#read file
mymfile = 'test.mym'
with open(mymfile) as mym:
    myminput = mym.readlines()
    #create equations by removing spaces and splitting lines
    for line in myminput:
        line = line.replace(' ','').strip().split(';')
        for eqstr in line:
            if eqstr != '':
                eq = re.split(':=',eqstr)
                globals()[eq[0]] = sp.sympify(eq[1])
                print eq[0]+' = sp.sympify('+eq[1]+')'

print 'print F'
print F

它输出这个:

acc*mass

它应该输出一个值,就像测试脚本一样。 相同的脚本还输出测试脚本中使用的代码。唯一的区别是,在不工作的脚本中,我尝试从输入文件生成代码,如下所示:

mass := 0.2*kg ; acc := g

F := mass*acc

以及单位文件:

#SI

m       #length
kg      #mass
s       #time

和常量:

#constants

g:=9.80665*m/s**2       #standard gravity

整个代码也可以在github 上找到。 我不明白为什么一个版本有效,而另一个版本无效。欢迎任何想法。 谢谢。

【问题讨论】:

  • 在脚本底部附近,等式的后半部分 eq[1] 仍然是一个字符串。看起来 sympify 需要一个实际的表达式(在这种情况下,两个变量和一个乘法)。
  • 来自文档:sympy.core.sympify.sympify(a, locals=None, convert_xor=True, strict=False,rational=False, evaluate=None)[来源] 转换一个可以在 SymPy 中使用的类型的任意表达式。 ...它目前接受作为参数:... 字符串(如“0.09”或“2e-19”)...编辑:但是 - 你是正确的!
  • 好的,我将:sp.sympify(eq[1]) 更改为:sp.sympify(eval(eq[1])) 现在它可以工作了。谢谢你的提示,埃弗特!
  • sympify 应该可以很好地处理字符串。我认为您需要传入全局或本地字典,以便它知道您设置的内容。

标签: python numeric sympy


【解决方案1】:

根据 Everts 的评论,我想出了这个解决方案:

改变:

sp.sympify(eq[1])

到:

sp.sympify(eval(eq[1]))

【讨论】:

  • 由于您在此处使用eval,并且您允许通过用户文件(任意)输入,因此您可能需要谨慎。或许ast.literal_eval可以帮到你?
猜你喜欢
  • 2018-08-06
  • 2018-03-03
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
  • 2019-02-26
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多