Нарушение функции без печати собственного сообщения об ошибке

avatar
shaqman
8 апреля 2018 в 10:13
38
1
0

Я создаю функцию, которая многократно тестирует другую функцию, чтобы получить значение в пределах заданного пользователем допуска. Я пытался заставить его печатать сообщение об ошибке в случае, когда требуется больше итераций, чтобы попасть в заданный допуск, но это сообщение никогда не печатается, и я не могу понять, почему.

from math import e

def ctrapezoidal(f,a,b,n):
    h=((b-a)/n)
    y = (h/2)*(f(a)+f(b))
    for x in range(n-1):
        p = a + ((x+1)/n)*(b-a)
        y = y + h*(f(p))
    return y

def ctrap(f,a,b,n,tol):
    for x in range(n):
        if x is 0:
            continue
        elif x is 1:
            continue
        elif x is (n-1):
            if abs((ctrapezoidal(f,a,b,x)) - (ctrapezoidal(f,a,b,(x-1)))) < tol:
                print("The integral of the function between",a,"and",b,"approximates to",ctrapezoidal(f,a,b,x),"with a tolerance of",tol)
                break
            else:
                print("The approximation needs more iterations to calculate the integral to the given tolerance.")
                   #This error never shows, even when given too few iterations to compute.
                   #The if-statement works, though, since I've tried with values
                   #of n one integer higher than the needed number of iterations.
        else:
            if abs((ctrapezoidal(f,a,b,x)) - (ctrapezoidal(f,a,b,(x-1)))) < tol:
                print("The integral of the function between",a,"and",b,"approximates to",ctrapezoidal(f,a,b,x),"with a tolerance of",tol,". This calculation took",x,"iterations.")
                break
            else:
                continue

def g(x):
    y = 2*e**(2*x) + 2*x
    return y

ctrap(g,1,5,1331,1.e-4)

Вот что я написал. Заданное значение n в последней строке является наименьшим значением, для которого ctrap работает должным образом. Есть идеи?

Источник
Aran-Fey
8 апреля 2018 в 10:14
3

Не сравнивайте числа с is. Используйте ==.

shaqman
8 апреля 2018 в 10:18
0

@ Аран-Фей, спасибо!

Ответы (1)

avatar
David Z
8 апреля 2018 в 10:57
1

Проблема исходит из линии

        elif x is (n-1):

Когда вы используете is для сравнения, Python проверяет левую и правую стороны, чтобы увидеть, представляют ли они буквально один и тот же объект. Например, он может сравнить их адреса памяти. Но два целых числа, имеющих одинаковое числовое значение, в общем случае не будут одним и тем же объектом. Вы можете увидеть это, запустив интерпретатор и выполнив команду

.
>>> 1331 is (1330 + 1)
False

Это показывает, что целочисленный объект, который вы получаете, когда пишете 1331 в коде, не является тем же целочисленным объектом, который вы получаете, когда вы пишете 1330 + 1, даже если они имеют одинаковое числовое значение. Вот почему ваше сравнение не работает; у вас есть разные объекты, представляющие одно и то же целое число, и вы проверяете равенство объектов вместо числового равенства.

Используйте == вместо проверки числового равенства.

>>> 1331 == (1330 + 1)
True

Обратите внимание, что стандартная реализация Python кэширует целочисленные объекты до 256 включительно, поэтому для каждого значения существует только один экземпляр. Таким образом, целые числа до 256 также будут сравнивать объектно-равные:

>>> 256 is (255 + 1)
True
>>> 257 is (256 + 1)
False

Однако на это полагаться не стоит.