如果没有直接的例子,这有点难以解释。所以让我们把非常简单的 ideal-gas law作为例子。对于正常情况下的理想气体,下式成立:
PV = RT
这意味着如果我们知道 4 个变量中的 3 个(压力、体积、特定气体常数和温度),我们就可以求解另一个。
我如何将其放入对象中?我想要一个对象,我可以在其中插入 3 个变量,然后计算第 4 个。不知是否可以通过属性来实现?
我目前最好的猜测是像这样插入它:
class gasProperties(object):
__init__(self, P=None, V=None, R=None, T=None)
self.setFlowParams(P, V, R, T)
def setFlowParams(self, P=None, V=None, R=None, T=None)
if P is None:
self._P = R*T/V
self._V = V
self._R = R
self._T = T
elif V is None:
self._V = R*T/P
self._P = P
self._R = R
self._T = T
#etc
虽然这很麻烦,而且容易出错(我必须添加检查以查看是否恰好有一个参数设置为“无”)。
有没有更好、更简洁的方法?
我发现这种“问题”经常以各种方式发生,尤其是一旦变量数量增加(将密度、雷诺数、粘度添加到混合物中),不同 if 语句的数量就会迅速增加。 (即,如果我有 8 个变量并且任何 5 个使系统唯一,我将需要 8 nCr 5 = 56 if 语句)。
最佳答案
使用 sympy
,您可以为每个方程式创建一个类。使用 ω, π = sp.symbols('ω π')
创建方程式的符号等等,方程本身然后使用函数f()
做剩下的:
import sympy as sp
# Create all symbols.
P, V, n, R, T = sp.symbols('P V n R T')
# Create all equations
IDEAL_GAS_EQUATION = P*V - n*R*T
def f(x, values_dct, eq_lst):
"""
Solves equations in eq_lst for x, substitutes values from values_dct,
and returns value of x.
:param x: Sympy symbol
:param values_dct: Dict with sympy symbols as keys, and numbers as values.
"""
lst = []
lst += eq_lst
for i, j in values_dct.items():
lst.append(sp.Eq(i, j))
try:
return sp.solve(lst)[0][x]
except IndexError:
print('This equation has no solutions.')
试试这个……:
vals = {P: 2, n: 3, R: 1, T:4}
r = f(V, values_dct=vals, eq_lst=[IDEAL_GAS_EQUATION, ])
print(r) # Prints 6
如果您没有通过values_dct
提供足够的参数你会得到类似 3*T/2
的结果, 检查其 type()
你得到 <class 'sympy.core.mul.Mul'>
.
如果您确实提供了所有参数,您将获得结果 6
它的类型是 <class 'sympy.core.numbers.Integer'>
,所以你可以提出异常,或者任何你需要的。您也可以使用 int()
将其转换为 int (如果你有 3*T/2
而不是 6 ,它会引发错误,所以你也可以那样测试它)。
或者,您可以简单地检查是否 None
values_dct
中的值大于 1。
合并多个方程,例如PV=nRT
和 P=2m
, 你可以创建额外的符号 m
像前面的符号一样分配 2m
到新方程名称 MY_EQ_2
, 然后将其插入 eq_lst
功能:
m = sp.symbols('m')
MY_EQ_2 = P - 2 * m
vals = {n: 3, R: 1, T:4}
r = f(V, values_dct=vals, eq_lst=[IDEAL_GAS_EQUATION, MY_EQ_2])
print(r) # Prints 6/m
关于管理任意数量变量的 Pythonic 方式,用于方程求解。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29253418/