Python中的交替计数器(斐波那契图)

Python中的交替计数器(斐波那契图),python,fibonacci,Python,Fibonacci,在我的计算课上,我被分配了一个项目,使用Python 2.7代码,用LaTeX做一个关于数学某个领域的报告——我选择了斐波那契序列 作为我项目的一部分,我想包括一个斐波那契“螺旋”图,它实际上由一系列半径不断增大的四分之一圆组成。因此,我试图定义一个函数,给出一个返回这些四分之一圆中心的循环,以便创建一个绘图。我用笔和纸找到了每个四分之一圆的中心,并注意到每个新的四分之一圆都有坐标交换——即,如果n是偶数,则前一个中心的x坐标仍然是第n个中心的x坐标;类似地,当n为奇数时,y坐标保持不变 我的问

在我的计算课上,我被分配了一个项目,使用Python 2.7代码,用LaTeX做一个关于数学某个领域的报告——我选择了斐波那契序列

作为我项目的一部分,我想包括一个斐波那契“螺旋”图,它实际上由一系列半径不断增大的四分之一圆组成。因此,我试图定义一个函数,给出一个返回这些四分之一圆中心的循环,以便创建一个绘图。我用笔和纸找到了每个四分之一圆的中心,并注意到每个新的四分之一圆都有坐标交换——即,如果n是偶数,则前一个中心的x坐标仍然是第n个中心的x坐标;类似地,当n为奇数时,y坐标保持不变

我的问题出现在另一个坐标上。他们在n-2斐波那契数的+或-到y坐标(对于偶数n)或x坐标(对于前一个中心的奇数)的交替模式下工作

我在SageMathCloud中创建了以下循环,但我想我已经推断出我的计数器在我希望它们增加时没有增加:

def centrecoords(n):
    k = 0
    l = 1
    if fib(n) == 1:
        return tuple((0,-1))
    elif n % 2 == 0 and k % 2 == 0:
        return tuple((centrecoords(n-1)[0], centrecoords(n-1)[1] + ((-1) ** k) * fib(n - 2)))
        k += 1
    elif n % 2 == 0:
        return tuple((centrecoords(n-1)[0], centrecoords(n-1)[1] + ((-1) ** k) * fib(n - 2)))
    elif n % 2 != 0 and l % 2 == 0:
        return tuple((centrecoords(n-1)[0] + ((-1) ** l) * fib(n - 2), centrecoords(n-1)[1]))
        l += 1
    else:
        return tuple((centrecoords(n-1)[0] + ((-1) ** l) * fib(n - 2), centrecoords(n-1)[1]))


cen_coords = []

for i in range(0, 21):
    cen_coords.append(centrecoords(i))

cen_coords

非常感谢您在使用if语句使k计数器和l计数器递增时提供的任何帮助。

请继续我的评论。您的代码可能与下面的代码类似。但请注意,您可能不需要相应地将k和l的起始值调整为-1和0,因为k和l在与代码相反的递归调用之前递增,这意味着首先调用递归,然后才增加k和l。 我还删除了元组,这在python中是不必要的,而且很难阅读,创建元组时使用逗号语法,例如:1,2。 另外,n==0 fibn==0应被视为特例,否则当使用n=0调用centrecoords时,程序将进入无限递归并崩溃

我在SageMathCloud上没有帐户来测试它,但它至少应该修复计数器增量

def centrecoords(n, k=0, l=1):
    if n == 0:
        return 0, 0  # this is pure guess and most likely incorrect, but n == 0 (or fib(n) == 0 should be handled separatly)
    if fib(n) == 1:
        return 0, -1
    elif n % 2 == 0 and k % 2 == 0:
        k += 1
        return centrecoords(n-1, k, l)[0], centrecoords(n-1, k, l)[1] + ((-1) ** k) * fib(n - 2)
    elif n % 2 == 0:
        return centrecoords(n-1, k, l)[0], centrecoords(n-1, k, l)[1] + ((-1) ** k) * fib(n - 2)
    elif n % 2 != 0 and l % 2 == 0:
        l += 1
        return centrecoords(n-1, k, l)[0] + ((-1) ** l) * fib(n - 2), centrecoords(n-1, k, l)[1]
    else:
        return centrecoords(n-1, k, l)[0] + ((-1) ** l) * fib(n - 2), centrecoords(n-1, k, l)[1]


cen_coords = []

for i in range(0, 21):
    cen_coords.append(centrecoords(i))

cen_coords
你的问题是k和l是局部变量。因此,每次函数退出时,它们都会丢失,当再次调用时,它们会分别在0和1处重新启动。是,即使从函数本身调用时也是如此

Nick的代码旨在将k和l的每个实例存储在顶级函数中,并与递归调用共享它们

另一种合理的方法可能是将递归重写为循环,并生成序列。这使得保持k和l的状态变得很简单,因为您的局部变量被保留

或者,您可以将函数作为类方法重新编写,并生成k和l实例变量。其行为类似,实例存储对centrecoords调用之间的中间状态

除此之外,您的代码似乎还需要每次调用centrecoords来接收下一个值n。因此,即使您解决了状态问题,这也是一个糟糕的设计

我建议按照生成器的路线,取一个参数,最大值n。然后您可以迭代rangen,依次生成每个结果。还要注意,您唯一的递归调用是针对n-1的,这只是您的上一次迭代,所以您可以简单地记住它

快速演示:我没有测试过这个,也没有检查过角落的箱子

def fib(n):
    if n < 2:
        return 1
    return fib(n-1) + fib(n-2)

def centrecoords(max_n):
    # initial values
    k = 0
    l = 1
    result=(0,-1)
    # note fib(0) == fib(1) == 1
    for n in range(2,max_n):
        if n % 2 == 0:
            result = (result[0], result[1] + ((-1) ** k) * fib(n - 2))
            yield result
            if k % 2 == 0:
                k += 1
        else:
            result = (result[0] + ((-1) ** l) * fib(n - 2), result[1])
            yield result
            if l % 2 == 0:
                l += 1


cen_coords = list(centrecoords(21))

不能在return语句后增加计数器,因为程序在调用return时离开函数,很可能应该将k和l作为参数引入函数。