我有一个小型网络应用程序,需要 3 个点并计算抛物线函数或指数函数。这是抛物线的代码:
@app.route("/calculate/parabola", methods=["POST"])
def calculate_parabola():
content = request.get_json()
p1_X = content["p1_X"]
p1_Y = content["p1_Y"]
p2_X = content["p2_X"]
p2_Y = content["p2_Y"]
p3_X = content["p3_X"]
p3_Y = content["p3_Y"]
a, b, c = symbols("a,b,c")
eq1 = Eq((a*(p1_X**2)+b*p1_X+c),p1_Y)
eq2 = Eq((a*(p2_X**2)+b*p2_X+c), p2_Y)
eq3 = Eq((a*(p3_X**2)+b*p3_X+c), p3_Y)
eq_result = solve((eq1, eq2, eq3), (a,b,c))
print(eq_result)
returnJSON = {
"function": f"{eq_result[a]}*x^2+{eq_result[b]}*x+{eq_result[c]}",
"success": 1
}
return returnJSON
这个效果很好。 但是问题来了:
@app.route("/calculate/exponential-function", methods=["POST"])
def calculate_exponential_function():
print("calculating...")
content = request.get_json()
p1_X = content["p1_X"]
p1_Y = content["p1_Y"]
p2_X = content["p2_X"]
p2_Y = content["p2_Y"]
p3_X = content["p3_X"]
p3_Y = content["p3_Y"]
a, b, c = symbols("a,b,c", real=True)
# eq1 = Eq((a*(b**p1_X)+c), p1_Y)
# eq2 = Eq((a*(b**p2_X)+c), p2_Y)
# eq3 = Eq((a*(b**p3_X)+c), p3_Y)
eq1 = Eq((a*(b**p1_X)+c), p1_Y)
eq2 = Eq((a*(b**p2_X)+c), p2_Y)
eq3 = Eq((a*(b**p3_X)+c), p3_Y)
# eq_result = solve((eq1, eq2, eq3), (a,b,c))
eq_result = solve((eq1, eq2, eq3), (a,b,c))
print(eq_result)
returnJSON = {}
if(eq_result == []):
returnJSON = {
"success": 0
}
else:
returnJSON = {
"function": f"{eq_result[a]}*({eq_result[b]}**x)+{eq_result[c]}",
#"function": f"{eq_result[a]}*x+{eq_result[c]}",
"success": 1
}
return returnJSON
如果一切正常,“eq_result”应该是这样的:
{a: 5/6, b: -1/6, c: 1}
但是当执行 calculate_exponential_function()
时,“eq_result”输出(例如):
[(-27/5, -2/3, 32/5), (1, 2, 0)]
我做错了什么吗?如果您需要更多信息,请告诉我。
solve()
在它返回的内容上特别奇怪,但对于这种奇怪的东西相当友好(如果有的话,返回除None
之外的不同的、不兼容的对象是完全不Pythonic和令人惊讶的,尽管它很大程度上返回了list
的结果。 .)
来自文档https://docs.sympy.org/latest/explanation/solve_output.html
函数的输出看起来非常笨拙,因为它可能会任意返回六种不同类型的输出之一(除了引发错误之外)。其原因是历史性的,并且偏向于人际交互而不是程序化使用。输出的类型将取决于方程的类型(以及它们的输入方式)和提供的符号数量(以及它们的提供方式)。solve()
您可以通过设置
dict=True
使其表现得更好(尽管输出仍然是一个包含零个或一个条目的列表(或者可能是多个条目,但我不确定这种情况是否可行))
solve()
如果您传递寻求解决方案的符号,则输出将根据您传递的符号数量、是否传递表达式列表以及是否求解线性系统而有所不同。使用
或dict=True
可以获得均匀的输出。set=True
更令人困惑的是,
solve()
与dict=True
不会费心返回本身的值,因为它们并不“有趣”,所以在我简短的实验中,它们需要放回
>>> x, y = symbols("x y")
>>> solve(x + y, {x, y}, dict=True) # doesn't bother with y=y or y=-x
[{x: -y}]
>>> solve(x + y, {y}, dict=True) # force solving for y
[{y: -x}]
def calculate_exponential_function():
content = request.get_json()
p1_X = content["p1_X"]
p1_Y = content["p1_Y"]
p2_X = content["p2_X"]
p2_Y = content["p2_Y"]
p3_X = content["p3_X"]
p3_Y = content["p3_Y"]
a, b, c = symbols("a b c", real=True)
eq1 = Eq((a*(b**p1_X)+c), p1_Y)
eq2 = Eq((a*(b**p2_X)+c), p2_Y)
eq3 = Eq((a*(b**p3_X)+c), p3_Y)
eq_result = solve((eq1, eq2, eq3), {a,b,c}, dict=True)
if not eq_result: # empty list
return { # failed to solve
"success": 0,
}
eq_result = eq_result[0] # TODO consider case of multiple results
# add missing keys
for key in (a, b, c):
if key not in eq_result:
eq_result[key] = key
return {
"function": f"{eq_result[a]}*({eq_result[b]}**x)+{eq_result[c]}",
"success": 1,
}