파이썬

(파이썬) 이분 검색을 일반화 하는 함수 findRoot, 검사함수 testFindRoot

조이키트 블로그 2023. 7. 30. 16:28
728x90
반응형

findRoot 함수는 제곱근을 찾는데 사용했던 이분 검색을 일반화하는 함수이고, testFindRoot는 findRoot가 제대로 작동하는지 검사할 때 사용하는 함수이다.

프로그램이 제대로 작동하지 않을 때 문제가 어디서 발생하는지 찾고 그것을 고치는 작업을 할 때 만약 미리 테스트 코드를 짜놓는다면 매번 쉘에 시험사례를 입력하여 검사를 하는것 보다 훨씬 수월하게 오류를 찾아낼 수 있다.

#근의 근사값 찾기
def findRoot(x, power, epsilon):
    """Assumes x and epsilon int or float, power an int, 
    epsilon > 0,& power >=1
    Returns float y such that y**power is within epsilon of x.
    If such a float does not exist, it returns None"""
    if x < 0 and power%2 == 0:
        return None
    low = min(-1.0, x)
    high = max(1.0, x)
    ans = (high + low)/2.0
    while abs(ans**power - x) >= epsilon:
        if ans**power < x:
            low = ans
        else:
            high = ans
        ans = (high + low)/2.0
    return ans

def testFindRoot():
    epsilon = 0.0001
    for x in (0.25, -0.25, 2, -2, 8, -8):
        for power in range(1, 4):
            print('Testing x = ' + str(x) + 'and power = ' + str(power))
            result = findRoot(x, power, epsilon)
            if result == None:
                print('No root')
            else:
                print(' ', result**power, '~=', x)

print('testFindRoot :', testFindRoot())
print('findRoot : ', findRoot(4, 2, 0.1))

findRoot의 사양은 그 사양을 만족시키는 모든 구현 가능한 것들을 추상화한 것이다. 

findRoot의 고객은 구현된것이 사양대로 작동한다고 가정할 수 있지만 고객은 그 이상 어떤 것도 추정해서는 안된다.

예를 들어 고객이 findRoot(4.0, 2, 0.1)을 호출하면 제곱으로 3.99에서 4.01 사이의 값을 가진 어떤 값을 변환한다는 것을 추정할 수 있다. 그 값은 양수일 수도 있고 음수일수 있으며 4.0이 완전 제곱이라 할지라고 반환된 완전 제곱 값은 2.0이나 -2.0이 아닐 수도 있다.

 

출력결과

Testing x = 0.25and power = 1
  0.25 ~= 0.25
Testing x = 0.25and power = 2
  0.25 ~= 0.25
Testing x = 0.25and power = 3
  0.24990749079734087 ~= 0.25
Testing x = -0.25and power = 1
  -0.25 ~= -0.25
Testing x = -0.25and power = 2
No root
Testing x = -0.25and power = 3
  -0.24990749079734087 ~= -0.25
Testing x = 2and power = 1
  1.999908447265625 ~= 2
Testing x = 2and power = 2
  2.0000906325876713 ~= 2
Testing x = 2and power = 3
  2.000059155646067 ~= 2
Testing x = -2and power = 1
  -1.999908447265625 ~= -2
Testing x = -2and power = 2
No root
Testing x = -2and power = 3
  -2.000059155646067 ~= -2
Testing x = 8and power = 1
  7.999931335449219 ~= 8
Testing x = 8and power = 2
  7.99999568007479 ~= 8
Testing x = 8and power = 3
  8.000068664747232 ~= 8
Testing x = -8and power = 1
  -7.999931335449219 ~= -8
Testing x = -8and power = 2
No root
Testing x = -8and power = 3
  -8.000068664747232 ~= -8
testFindRoot : None
findRoot :  2.0078125
728x90
반응형