因为我的财务课变得有点沉闷,我一直在玩弄同情并决定做一个任意的方程求解器 . 我写了一个基本框架,并开始玩一些例子,但有些工作,有些不是出于某种原因 .
from sympy import *
import sympy.mpmath as const
OUT_OF_BOUNDS = "Integer out of bounds."
INVALID_INTEGER = "Invalid Integer."
INVALID_FLOAT = "Invalid Float."
CANT_SOLVE_VARIABLES = "Unable to Solve for More than One Variable."
CANT_SOLVE_DONE = "Already Solved. Nothing to do."
# time value of money equation: FV = PV(1 + i)**n
# FV = future value
# PV = present value
# i = growth rate per perioid
# n = number of periods
FV, PV, i, n = symbols('FV PV i n')
time_value_money_discrete = Eq(FV, PV*(1+i)**n)
time_value_money_continuous = Eq(FV, PV*const.e**(i*n))
def get_sym_num(prompt, fail_prompt):
while(True):
try:
s = input(prompt)
if s == "":
return None
f = sympify(s)
return f
except:
print(fail_prompt)
continue
equations_supported = [['Time Value of Money (discrete)', [FV, PV, i, n], time_value_money_discrete],
['Time Value of Money (continuous)',[FV, PV, i, n], time_value_money_continuous]]
EQUATION_NAME = 0
EQUATION_PARAMS = 1
EQUATION_EXPR = 2
if __name__ == "__main__":
while(True):
print()
for i, v in enumerate(equations_supported):
print("{}: {}".format(i, v[EQUATION_NAME]))
try:
process = input("What equation do you want to solve? ")
if process == "" or process == "exit":
break
process = int(process)
except:
print(INVALID_INTEGER)
continue
if process < 0 or process >= len(equations_supported):
print(OUT_OF_BOUNDS)
continue
params = [None]*len(equations_supported[process][EQUATION_PARAMS])
for i, p in enumerate(equations_supported[process][EQUATION_PARAMS]):
params[i] = get_sym_num("What is {}? ".format(p), INVALID_FLOAT)
if params.count(None) > 1:
print(CANT_SOLVE_VARIABLES)
continue
if params.count(None) == 0:
print(CANT_SOLVE_DONE)
continue
curr_expr = equations_supported[process][EQUATION_EXPR]
for i, p in enumerate(params):
if p != None:
curr_expr = curr_expr.subs(equations_supported[process][EQUATION_PARAMS][i], params[i])
print(solve(curr_expr, equations_supported[process][EQUATION_PARAMS][params.index(None)]))
这是我到目前为止的代码 . 我想如果需要的话我可以把它剥离成一个基本的例子,但我也想知道是否有更好的方法来实现这种系统 . 在我完成此操作后,我希望能够添加任意方程并在输入除一个参数之外的所有方程后解决它们 .
例如,如果我输入(对于等式0),FV = 1000,PV = 500,i = .02,n为空,我得到35.0027887811465,这是正确的答案 . 如果我重做它并将FV更改为4000,它将返回一个空列表作为答案 .
另一个例子,当我输入FV,PV和n时,程序似乎挂了 . 当我输入小数字时,我得到RootOf()答案而不是简单的小数 .
谁能帮我?
旁注:我正在使用SymPy 0.7.6和Python 3.5.1,我很确定它是最新的
2 回答
这是一个浮点精度问题 .
solve
默认情况下将解决方案插入到原始等式中并对其进行评估(使用浮点算法)以便对错误解决方案进行排序 . 您可以通过设置check=False
来禁用此功能 . 例如,对于Hugh Bothwell的代码这使
我没有答案,但我确实有一个更简单的演示案例;-)
哪个产生
猜测这是准确度下降到足以找不到
n
的可验证解决方案的地方?此外,虽然我在这里做了一个相当广泛的重写,你可能会觉得有用 . 它与您的代码几乎完全相同,但是以更加松散耦合的方式 .