python 开根号_python自学日记3——迭代

将下面递归函数用循环方式写出来:

def print_n(s,n):
    if n<=0:
        return
    print(s)
    print_n(s,n-1)
print_n(3,4)

我刚开始写的是这样的:

def print_n(s,n):
    while n>0:
        print(s)
        n=n-1
print_n('hello',4)

报错提示:TypeError: print() missing 1 required positional argument: 'n'

主要原因是刚开始print_n写成了print了。

但是以为这段代码有问题,所以百度查了下也没查出原因来,我想按照增量开发的原则,从提示报错的print(s)位置改一下

s='hello'
print(s)

然后还是报同样的错误,我就有点懵了,难道我以前记得的有关print的表达方式有问题

随机写了一个

print('hello')

还是报同样的错误,这个让我想起jupyter notebook有时候会出现缓存现象,修改的代码运行还是报原来的问题,然后我重启了一下服务,就正常了,这样才发现上面代码是没有问题的,也是因为自己不够确定,才导致的,否则一开始就重启服务就好了。

调试建议:

削减调试时间的方法:二分调试,例如,如果你的程序有100行代码,每次检查一行,需要100步

可以尝试把问题分成两半,找到程序的中点,或接近中点的地方,找一个可以检验的中间结果,添加一个print语句并运行。如果报错,证明代码前半部分有问题,没有则在后面,然后再进行二分,这样只需要6步左右即可完成。

实践中常常很难找到中点,我们应该思考程序哪些地方可能出错,哪些地方容易检查。

还要记得增量开发,实时调试。

求解平方根,使用牛顿方法:y=(x+a/x)/2

def square_root(a):
    x=3
    epsilon=0.0000001
    while True:
# print(x)
        y=(x+a/x)/2 #这时一个固定公式
# if abs(y-x)<epsilon: #判断条件,相比于y==x,这样更安全一些,因为很多时候得不到y==x
        if y==x:
            break
        x=y
    return x
square_root(2)

d7a24a7f8bbba868bb0c2b3aa5a61cf0.png

看到这个问题时我先做最小化分解,首先打印第一行,对第一行的四个数进行分解,看看每一列怎么打印出来,最终发现除了最后一列需要新增一个abs绝对值函数外前面都已经练过了

先按最简单的第一行开始时这么打印的

import math
def test_square_root(a):
    print(a,square_root(a),math.sqrt(a),abs(square_root(a)-math.sqrt(a)))
test_square_root(1)

报错了,那应该是一个print不能打印这么多,需要将这些分开打印,但是分开的话就会造成换行,去查了下如何不换行,查到print函数默认end参数后带的是换行符,改成end=" "就可以了

import math
def test_square_root(a):
    while a<10:
        print(a,end="  ") #end后面默认是换行符,改成空则不换行继续打印
        print(square_root(a),end="") 
        print(math.sqrt(a),end="  ")
        print(abs(square_root(a)-math.sqrt(a)))
        a=a+1
test_square_root(1)

这样虽然显示没问题了,但是没有对齐,然后找了python打印对齐的方法后,改成如下:

import math
def test_square_root(a):
    while a<10:
        print(a,end="  ") #end后面默认是换行符,改成空则不换行继续打印
        print('%-20s'%square_root(a),end="") #%-20s 表示左对齐,且占用20个字符位
        print('%-20s'%math.sqrt(a),end="  ")
        print('%-20s'%abs(float(square_root(a))-float(math.sqrt(a))))#求绝对值首先得把两个值都改成统一字符类型,所以都变成float格式
        a=a+1
test_square_root(1)

接下来遇到的这个问题就比较难了

fabc24504f99f8cb65256969ba01bde3.png

看到这个题第一感觉就是很难,还是看别人怎么做的吧,但是又一想还是应该自己先做一下,如果遇到难题就不动脑子就比较难提升了,还是应该先把问题分解一下,看看这些有没有学过,题目里还是给了提示和解决方案的,只要把这个公式用代码表达出来就可以了,拆解下公式,开根号学过了,加和公式可以用循环来做,阶乘前面也学过用递归做,那么问题就不是很难了。

我按照自己的想法写出如下代码:

def estimate_pi():
    def factorial(n):
        if n==0:
            return 1
        else:
            recurse=factorial(n-1)
            result=n*recurse
            return result
    a=0
    k=0
    while (factorial(4k)*(1103+26390*k))/(factorial(k)**4*396**(4*k))>=1e-15:
        a+=(factorial(4k)*(1103+26390*k))/factorial(k)**4*396**(4*k)
        k=k+1
    return a
    daoshu=2*math.sqrt(2)/9801*a
    pi=1/daoshu
    return pi
estimate_pi()

然后发现报错了,提示while (factorial(4k)*(1103+26390*k))/(factorial(k)**4*396**(4*k))>=1e-15:语法错误

那想着先拆分出这段代码看看到底哪里出了问题:

def qiuzhi(k):
    jieguo=(factorial(4k)*(1103+26390*k))/(factorial(k)**4*396**(4*k))
    while jieguo<1e-15:
        break
    jieguo=jieguo+(factorial(4(k+1))*(1103+26390*(k+1)))/(factorial(k+1)**4*396**(4*(k+1)))
    return jieguo
qiuzhi(0)

还是报同样的错误jieguo=(factorial(4k)*(1103+26390*k))/(factorial(k)**4*396**(4*k))语法错误。

再拆成更简单的如下:

def qiuzhi_1(k):
    print((factorial(4k)*(1103+26390*k))/(factorial(k)**4*396**(4*k)))
qiuzhi_1(1)

还是报同样的问题语法错误,但是当我直接把数字1代入(factorial(4k)*(1103+26390*k))/(factorial(k)**4*396**(4*k))中,能得出值来啊,难道是数值类型有问题吗,然后用type测了下是float,怎么看都没有问题,找不出问题就只能看答案了


下面是答案代码:

import math


def factorial(n):

    """Computes factorial of n."""
    if n == 0:
        return 1
    else:
        recurse = factorial(n-1)
        result = n * recurse
        return result




def estimate_pi():
    """Computes an estimate of pi.


    Algorithm due to Srinivasa Ramanujan, from 
    http://en.wikipedia.org/wiki/Pi
    """
    total = 0
    k = 0
    factor = 2 * math.sqrt(2) / 9801
    while True:
        num = factorial(4*k) * (1103 + 26390*k)
        den = factorial(k)**4 * 396**(4*k)
        term = factor * num / den
        total += term
 
        if abs(term) < 1e-15: break
        k += 1


    return 1 / total


print estimate_pi()

我发现跟我的思路是一样的,只不过将我那一个长公式分割成了好几部分,也许真的是我的公式代码太长了吧,后面回来再看看能不能找到原因。不过我有个地方是由于对这个公式不够熟悉导致的,就是在判断条件时,我用式子没带加和公式前的部分,正确的是应该带的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值