【问题标题】:How to fix TypeError: 'Add' object is not callable?如何修复 TypeError:“添加”对象不可调用?
【发布时间】:2020-08-30 11:50:16
【问题描述】:
def f(x):
    f='exp(x)-x-2'
    y=eval(f)
    print(y)
    return y
def bissection(f,f_line,f_2lines,a,b,epsilon1,epsilon2):
    x=a
    result_a=f(a)
    x=b
    result_b=f(b)
    if (f.evalf(a)*f.evalf(b)>=0):
        print("Interval [a,b] does not contain a zero ")
        exit()
    zeta=min(epsilon1,epsilon2)/10
    x=a
    while(f_line(x)>0):
        if(x<b or x>-b):
            x=x+zeta
        else:
            stop  
    ak=a
    bk=b
    xk=(ak+bk)/2
    k=0
    if (f(xk)*f(ak)<0):
        ak=ak
        bk=xk
    if (f(xk)*f(bk)<0):
        ak=xk
        bk=bk
    k=k+1
from sympy import *
import math
x=Symbol('x')
f=exp(x)-x-2
f_line=f.diff(x)                   
f_2lines=f_line.diff(x)           
print("Derivative of f:", f_line)    
print("2nd Derivative of f:", f_2lines) 
a=int(input('Beginning of interval: '))
b=int(input('End of interval: '))
epsilon1=input('1st tolerance: ')
epsilon2=input('2nd tolerance: ')
bissection(f,f_line,f_2lines,a,b,epsilon1,epsilon2)

这个程序是实现二分法的尝试。我试过写两个函数:

第一个 f 应该接收可能包含或不包含根(a 和 b)的区间的极值,并返回在这一点上评估的函数的值。

第二个,二等分,应该接收函数、函数的一阶和二阶导数、区间的极值 (a,b) 和两个容差 (epsilon1,epsilon2)。

我想要做的是将每个值 a 和 b,一次一个,作为函数 f 的参数,它应该返回 f(a) 和 f(b);即函数在点 a 和 b 中的值。

然后,它应该测试两个条件: 1) 如果区间极值的函数值符号相反。如果他们不这样做,该方法将不会在此时间间隔内收敛,那么程序应该终止。

if(f.evalf(a)*f.evalf(b)>=0)
    exit()

2)

while(f_line(x)>0): #while the first derivative of the function evaluated in x is positive
    if(x<b or x>-b):     #This should test whether x belongs to the interval [a,b]
        x=x+zeta                                #If it does, x should receive x plus zeta
    else:
        stop

在这个循环结束时,我的目标是确定一阶导数是否为严格正数(我还没有做负数)。

问题:我遇到了错误

Traceback (most recent call last):
   File "bissec.py", line 96, in <module>
       bissection(f,f_line,f_2lines,a,b,epsilon1,epsilon2)
   File "bissec.py", line 41, in bissection
       result_a=f(a)
TypeError: 'Add' object is not callable

如何正确调用该函数,以便它为每个需要的 x 返回函数的值(在本例中为 f(x)=exp(x)-x-2)?也就是如何评估 f(a) 和 f(b)?

【问题讨论】:

  • 首先使代码更具可读性。将导入放在开头,在字符周围添加空行和空格,例如=。查看更多PEP 8 -- Style Guide for Python Code
  • 您对def f(x)f = exp(x)-x-2 使用相同的名称f,这可能会导致问题 - Python 可能使用与您预期不同的f
  • 我没有看到使用表达式f = 'exp(x)-x-2' 有任何实际问题。我已经测试过了,它可以工作。我建议您不要为变量和函数使用相同的名称,因为这些多个定义可能会发生冲突。
  • 你在result_a=f(a) 行有问题,但后来你不使用result_a - 所以也许干脆删除这行。
  • @DanielLavedoniodeLima 我能够使用这些输入重现问题: 间隔开始:0 间隔结束:1 第一个容差:0.001 第二个容差:0.001

标签: python function typeerror sympy


【解决方案1】:

好的,所以我已经找出了您的程序失败的地方,我有 4 个原因。

首先,您的问题的主题是,如果您想评估函数f 以确定x 值,比如说a,您需要使用f.subs(x, a).evalf(),因为它是在SymPy documentation 中描述。您以两种不同的方式使用:f.evalf(2)f_line(a);两者都是错误的,需要用正确的语法代替。

其次,如果您想停止 while 循环,您应该使用关键字break,而不是代码中所写的“停止”。

第三,避免对变量和函数使用相同的名称。在您的 f 函数中,您还使用了 f 作为变量的名称。在bissection 函数中,您将f 作为参数传递并尝试调用f 函数。那也会失败。相反,我将f 函数更改为f_calc,并在其中应用了我第一点的正确语法。

第四,您的epsilon1epsilon2 输入缺少float() 转换。我已经添加了。

现在,我还编辑了您的代码以使用良好做法并应用 PEP8

此代码应该可以修复您遇到的这个错误以及其他一些错误:

from sympy import *


def func_calc(func, x, val):
    """Evaluate a given function func, whose varible is x, with value val"""
    return func.subs(x, val).evalf()


def bissection(x, f, f_line, f_2lines, a, b, epsilon1, epsilon2):
    """Applies the Bissection Method"""

    result_a = func_calc(f, x, a)
    result_b = func_calc(f, x, b)

    if (result_a * result_b >= 0):
        print("Interval [a,b] does not contain a zero")
        exit()

    zeta = min(epsilon1, epsilon2) / 10
    x_val = a
    while(func_calc(f_line, x, a) > 0):
        if(-b < x_val or x_val < b):
            x_val = x_val + zeta
        else:
            break  # the keyword you're looking for is break, instead of "stop"

    print(x_val)
    ak = a
    bk = b
    xk = (ak + bk) / 2
    k = 0
    if (func_calc(f, x, xk) * func_calc(f, x, ak) < 0):
        ak = ak
        bk = xk
    if (func_calc(f, x, xk) * func_calc(f, x, bk) < 0):
        ak = xk
        bk = bk
    k = k + 1


def main():
    x = Symbol('x')
    f = exp(x) - x - 2
    f_line = f.diff(x)
    f_2lines = f_line.diff(x)
    print("Derivative of f:", f_line)
    print("2nd Derivative of f:", f_2lines)
    a = int(input('Beginning of interval: '))
    b = int(input('End of interval: '))
    epsilon1 = float(input('1st tolerance: '))
    epsilon2 = float(input('2nd tolerance: '))
    bissection(x, f, f_line, f_2lines, a, b, epsilon1, epsilon2)


if __name__ == '__main__':
    main()

【讨论】:

  • 非常感谢大家,我已经设法让程序运行了!
  • 我很高兴它有帮助,@MarceloCarvalho。如果这个答案解决了问题,请不要忘记接受它。
猜你喜欢
  • 2015-02-15
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 2016-08-20
  • 2020-01-30
  • 2021-11-29
相关资源
最近更新 更多