我正在编程一个导数计算器,因此,我必须能够创建函数表示,然后能够用数字替换变量,然后进行数学运算。我正在尝试使用lambdas为我执行此操作,但我不断收到错误TypeError: unsupported operand type(s) for -: 'function' and 'int'
def doit(p):
a = p.get_base()
b = p.get_deg()
return lambda x: a ** b.get_val()
if __name__ == '__main__':
fext = make_pwr('x', 5)
f = lambda x: doit(fext) + x.get_val()
print(f(make_const(5)))
这是const类的样子:
#!/usr/bin/python
class const(object):
def __init__(self, val=0.0):
self.__val__ = val
def get_val(self):
return self.__val__
def __str__(self):
return str(self.__val__)
@staticmethod
def add(c1, c2):
assert isinstance(c1, const)
assert isinstance(c2, const)
v1, v2 = c1.get_val(), c2.get_val()
return const(val=(v1 + v2))
@staticmethod
def mult(c1, c2):
assert isinstance(c1, const)
assert isinstance(c2, const)
v1, v2 = c1.get_val(), c2.get_val()
return const(val=(v1 * v2))
@staticmethod
def divide(c1, c2):
assert isinstance(c1, const)
assert isinstance(c2, const)
v1, v2 = c1.get_val(), c2.get_val()
return const(val=(v1 / v2))
和功率等级:
#!/usr/bin/python
from const import const
class pwr(object):
def __init__(self, base=None, deg=None):
self.__base__ = base
self.__deg__ = deg
def get_base(self):
return self.__base__
def get_deg(self):
return self.__deg__
def __str__(self):
return '(' + str(self.__base__) + '^' + str(self.__deg__) + ')'
这是回溯:
Traceback (most recent call last):
File "D:/Shared/OneDrive/skewl/Spring 2019/CS 3430/hw01/maker.py", line 39, in <module>
print(f(make_const(5)))
File "D:/Shared/OneDrive/skewl/Spring 2019/CS 3430/hw01/maker.py", line 37, in <lambda>
f = lambda x: doit(fext) + x.get_val()
TypeError: unsupported operand type(s) for +: 'function' and 'int'
答案 0 :(得分:2)
doit
函数返回另一个函数。当您编写doit(fext) + x.get_val()
时,您试图将该功能添加到其他功能(实际上是一个整数)上。
我不清楚doit
的含义是什么。它似乎正在尝试评估一个指数表达式,但是它实际上没有任何意义,因此我无法为您真正解决它。
我认为想要的是能够评估任何给定的表达式,并能够将表达式转换为其派生。我认为弄乱lambda和类似的东西是错误的方式。相反,您需要一个更通用的Expression
类型层次结构。像这样:
from abc import ABCMeta, abstractmethod
class Expression(metaclass=ABCMeta):
@abstractmethod
def eval(self, **kwargs):
pass
@abstractmethod
def derivative(self, var):
pass
def __add__(self, other):
return Sum(self, other)
def __mul__(self, other):
return Product(self, other)
class Constant(Expression):
def __init__(self, value):
self.value = value
def eval(self, **kwargs):
return self.value
def derivative(self, var):
return Constant(0)
class Variable(Expression):
def __init__(self, name):
self.name = name
def eval(self, **kwargs):
return kwargs[self.name] # TODO: raise a better exception if the name is not found
def derivative(self, var):
if self.name == var:
return Constant(1)
return Constant(0)
def __pow__(self, exponent):
return SimplePower(self, exponent)
class Sum(Expression):
def __init__(self, lhs, rhs):
self.lhs = lhs
self.rhs = rhs
def eval(self, **kwargs):
return self.lhs.eval(**kwargs) + self.rhs.eval(**kwargs)
def derivative(self, var):
return self.lhs.derivative(var) + self.rhs.derivative(var)
class Product(Expression):
def __init__(self, lhs, rhs):
self.lhs = lhs
self.rhs = rhs
def eval(self, **kwargs):
return self.lhs.eval(**kwargs) * self.rhs.eval(**kwargs)
def derivative(self, var):
return self.lhs.derivative(var) * self.rhs + self.rhs.derivative(var) * self.lhs
class SimplePower(Expression):
def __init__(self, var, exponent):
self.var = var
self.exponent = exponent
def eval(self, **kwargs):
return self.var.eval(**kwargs) ** self.exponent
def derivative(self, var):
if var == self.var.name:
return Constant(self.exponent) * SimplePower(self.var, self.exponent-1)
else:
return Constant(0)
这是它的使用演示:
>>> x = Variable('x')
>>> f = x ** 2 + x * Constant(3) + Constant(-2) # f(x) = x^2 + 3x - 2
>>> f.eval(x=1)
2
>>> f.eval(x=2)
8
>>> f.eval(x=3)
16
>>> f_prime = f.derivative('x') # f'(x) = 2x + 3
>>> f_prime.eval(x=0)
3
>>> f_prime.eval(x=1)
5
>>> f_prime.eval(x=2)
7
请注意,因为__pow__
仅在Variable
中定义,而不是在Expression
中定义,所以此代码仅支持x**c
形式的幂(其中x
是Variable
和c
是int
(不是Constant
,因为我们不需要eval
)。它不支持任意表达式对任意表达式(可能具有非常复杂的派生)的功能。减法和除法等其他操作也不太难,我只是省略了它们以缩短代码。您可能还可以使__add__
和__mul__
操作检查int
(或者也许是float
)自变量,并自动将它们捆绑到Constant
中。然后,您可以编写像f = x**3 + x**2 * 4 + x * -1 + 8
这样的非常好的表达式,它就可以工作(给定x = Variable('x')
)。