2012-10-11 41 views
2

我正在使用Python中的牛顿猜测和检查方法来完成一个近似数字的平方根的数学问题。用户应该输入一个数字,初始猜测数字,以及他们想要在返回之前检查他们的答案的次数。为了让事情变得更容易,并且了解Python(几个月前我才刚刚开始学习这门语言),我将它分解为一些较小的函数;现在的问题是,我无法调用每个函数并传递数字。使用牛顿的方法找到平方根(错误!)

这里是我的代码,与意见,以帮助(每个功能在使用顺序排列):

# This program approximates the square root of a number (entered by the user) 
# using Newton's method (guess-and-check). I started with one long function, 
# but after research, have attempted to apply smaller functions on top of each 
# other. 
# * NEED TO: call functions properly; implement a counting loop so the 
# goodGuess function can only be accessed the certain # of times the user 
# specifies. Even if the - .001 range isn't reached, it should return. 

# sqrtNewt is basically the main, which initiates user input. 

def sqrtNewt(): 
    # c equals a running count initiated at the beginning of the program, to 
    # use variable count. 
    print("This will approximate the square root of a number, using a guess-and-check process.") 
    x = eval(input("Please type in a positive number to find the square root of: ")) 
    guess = eval(input("Please type in a guess for the square root of the number you entered: ")) 
    count = eval(input("Please enter how many times would you like this program to improve your initial guess: ")) 
    avg = average(guess, x) 
    g, avg = improveG(guess, x) 
    final = goodGuess(avg, x) 
    guess = square_root(guess, x, count) 
    compare(guess, x) 


# Average function is called; is the first step that gives an initial average, 
# which implements through smaller layers of simple functions stacked on each 
# other. 
def average(guess, x) : 
    return ((guess + x)/2) 

# An improvement function which builds upon the original average function. 
def improveG(guess, x) : 
    return average(guess, x/guess) 

# A function which determines if the difference between guess X guess minus the 
# original number results in an absolute vale less than 0.001. Not taking 
# absolute values (like if guess times guess was greater than x) might result 
# in errors 
from math import * 
def goodGuess(avg, x) : 
    num = abs(avg * avg - x) 
    return (num < 0.001) 

# A function that, if not satisfied, continues to "tap" other functions for 
# better guess outputs. i.e. as long as the guess is not good enough, keep 
# improving the guess. 
def square_root(guess, x, count) : 
    while(not goodGuess(avg, x)): 
     c = 0 
     c = c + 1 
     if (c < count): 
      guess = improveG(guess, x) 
     elif (c == count): 
      return guess 
     else : 
      pass 

# Function is used to check the difference between guess and the sqrt method 
# applied to the user input. 
import math 
def compare(guess, x): 
    diff = math.sqrt(x) - guess 
    print("The following is the difference between the approximation") 
    print("and the Math.sqrt method, not rounded:", diff) 

sqrtNewt() 

目前,我得到这个错误:g, avg = improveG(guess, x) TypeError: 'float' object is not iterable. 最终的功能使用的猜测最终迭代从数学平方根法减去,并返回整体差异。 我是否做对了?工作代码将不胜感激,并提供建议,如果你可以提供。再次,我是一个新手,所以我对错误观念或盲目的明显错误表示歉意。

+1

有你看着http://radiantbytes.com/books/python-latex/src/chap9.html - 这一切都没有:) – root

回答

7

实现牛顿方法:

它应该很容易在需要时小的调整要添加到它。尝试,并告诉我们什么时候卡住了。

from math import * 
def average(a, b): 
    return (a + b)/2.0 
def improve(guess, x): 
    return average(guess, x/guess) 
def good_enough(guess, x): 
    d = abs(guess*guess - x) 
    return (d < 0.001) 
def square_root(guess, x): 
    while(not good_enough(guess, x)): 
     guess = improve(guess, x) 
    return guess 
def my_sqrt(x): 
    r = square_root(1, x) 
    return r 

>>> my_sqrt(16) 
4.0000006366929393 

注意:你会发现如何在SO或谷歌搜索在这里使用原始输入足够exaples,但是,如果你指望环路,c=0必须是外循环,否则你会被卡在无限循环。

Quiqk和肮脏的,大量的方法来改善:

from math import * 
def average(a, b): 
    return (a + b)/2.0 
def improve(guess, x): 
    return average(guess, x/guess) 
def square_root(guess, x, c): 
    guesscount=0 
    while guesscount < c : 
     guesscount+=1 
     guess = improve(guess, x) 
    return guess 
def my_sqrt(x,c): 
    r = square_root(1, x, c) 
    return r 

number=int(raw_input('Enter a positive number')) 
i_guess=int(raw_input('Enter an initial guess')) 
times=int(raw_input('How many times would you like this program to improve your initial guess:'))  
answer=my_sqrt(number,times) 

print 'sqrt is approximately ' + str(answer) 
print 'difference between your guess and sqrt is ' + str(abs(i_guess-answer)) 
+0

+1 - 很好做。我不认为这个网站会给你这样的问题带来好处。 8) – duffymo

+0

@ duffymo - 就这样,是的:) – root

+0

谢谢!我应该说我正在使用Python ver 3.30,所以我做了相应的更改。我想我也可以从Math.sqrt返回的数字中减去猜测。再次,这是非常有帮助的;真的很感激这个! – user1739537

2

这里是一个完全不同的函数来计算平方根;它假定ñ非负:

def mySqrt(n): 
    if (n == 0): 
     return 0 
    if (n < 1): 
     return mySqrt(n * 4)/2 
    if (4 <= n): 
     return mySqrt(n/4) * 2 
    x = (n + 1.0)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    return x 

这种算法类似于牛顿的,但不完全相同。它是在一世纪(约二千年前),由一位名叫Heron的希腊数学家发明的(他的名字有时拼写英雄)住在埃及亚历山大港。 Heron的递推公式比牛顿简单,苍鹭使用x' = (x + n/x)/2其中牛顿使用x' = x - (x^2 - n)/2x

第一个测试是零的一个特例;没有它,(n < 1)测试会导致无限循环。接下来的两个测试将n标准化为范围1 < n <= 4;使范围小意味着我们可以很容易地计算初始近似值的平方根的Ñ,其在的X第一计算完成,然后“展开循环”和迭代递推方程的固定数量次,因此消除了对两次连续循环之间的差异过大的测试和循环的需要。

顺便说一句,Heron是一个非常有趣的家伙。除了发明了计算平方根的方法,他建立了一个工作的喷气发动机,投币式自动售货机,和许多其他奇妙的东西!

你可以阅读更多关于my blog计算平方根。

+0

谢谢!将我的代码的评论加入;相当有帮助。 – user1739537

7

选择的答案有点复杂...没有不尊重OP​​。

对于谁曾谷歌这在将来任何人,这是我的解决方案:

def check(x, guess): 
    return (abs(guess*guess - x) < 0.001) 

def newton(x, guess): 
    while not check(x, guess): 
     guess = (guess + (x/guess))/2.0 
    return guess 

print newton(16, 1) 
0

它不应该有那么复杂,我写这件事

def squareroot(n,x): 
final = (0.5*(x+(n/x))) 
print (final) 
for i in range(0,10): 
    final = (0.5*(final+(n/final))) 
    print (final) 

,或者你可以将其更改为像这样

n = float(input('What number would you like to squareroot?')) 
x = float(input('Estimate your answer')) 
final = (0.5*(x+(n/x))) 
print (final) 
for i in range(0,10): 
    final = (0.5*(final+(n/final))) 
    print (final) 
0

所有你需要知道的是序列中的第n项。从莱布尼兹系列中,我们知道这是((-1)** n)/((2 * n)+1)。对于所有我来说,只需对这个系列进行总结,初始条件为零,然后设置好。

def myPi(n): 

pi=0 
for i in range(0,n): 
    pi=pi+((-1)**i)/((2*i)+1) 
return 4*pi 
print (myPi(10000))