Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
逐步执行Python递归函数_Python_Debugging_Recursion_Turtle Graphics - Fatal编程技术网

逐步执行Python递归函数

逐步执行Python递归函数,python,debugging,recursion,turtle-graphics,Python,Debugging,Recursion,Turtle Graphics,我正在努力提高我对递归的理解,可视化表示对我很有帮助。我有一个递归树绘制函数,我希望能够逐步完成它,并思考每个阶段会发生什么。我找到了IDLE的调试器,但似乎无法在调用递归函数后使其停止。此外,当我逐步阅读代码时,turtle模块打开了几个窗口,这一切都变得一团糟 这是否可能使用IDLE,或者我是否应该手动编码了解此功能所需的暂停和日志信息?作为第二个问题,有人能解释一下这段代码是如何工作的吗?它似乎先画出了所有的右手分支,我可以跟着画,但它所做的事情开始看起来像是伏都教 代码如下: impor

我正在努力提高我对递归的理解,可视化表示对我很有帮助。我有一个递归树绘制函数,我希望能够逐步完成它,并思考每个阶段会发生什么。我找到了IDLE的调试器,但似乎无法在调用递归函数后使其停止。此外,当我逐步阅读代码时,turtle模块打开了几个窗口,这一切都变得一团糟

这是否可能使用IDLE,或者我是否应该手动编码了解此功能所需的暂停和日志信息?作为第二个问题,有人能解释一下这段代码是如何工作的吗?它似乎先画出了所有的右手分支,我可以跟着画,但它所做的事情开始看起来像是伏都教

代码如下:

import turtle

def tree(branchLen,t):
    if branchLen > 5:
        t.forward(branchLen)
        t.right(20)
        tree(branchLen-15,t)
        t.left(40)
        tree(branchLen-15,t)
        t.right(20)
        t.backward(branchLen)

def main():
    t = turtle.Turtle()
    t.speed(1)
    myWin = turtle.Screen()
    t.left(90)
    t.up()
    t.backward(100)
    t.down()
    t.color("green")
    tree(75,t)
    myWin.exitonclick()

main()

我可以想出两种方法来帮助你形象化这些步骤

第一个是在
函数的开头添加
t.stamp()
。这将在每次调用
函数时提供另一个可视指示器

def tree(branchLen, t):
if branchLen > 5:
    t.stamp()
    t.forward(branchLen)
    ...
你已经有了乌龟的速度。另一种减慢操作速度的方法是导入
时间
模块并使用
睡眠
功能。如果使用此解决方案,我建议在递归调用
树之前使用
sleep
调用

import turtle
import time

def tree(branchLen,t):
    if branchLen > 5:
        t.forward(branchLen)
        t.right(20)
        time.sleep(0.5)
        tree(branchLen-15,t)
        t.left(40)
        tree(branchLen-15,t)
        time.sleep(0.5)
        t.right(20)
        t.backward(branchLen)

您甚至可以结合使用这两种方法来区分何时为右分支和左分支(第一次和第二次递归调用)调用树。

下面是一种在不修改原始递归子例程的情况下可视化正在发生的事情的方法。首先,我们通过反转符号将
backward()
更改为
forward()
。然后,我们粉碎了一个新的
foward()
实现,它改变了笔的颜色,画了线,在控制台等待回车,撤销了它刚刚做的事情,最后做了原来的
forward()
应该做的事情:

from turtle import Screen, Turtle

def visible_forward(self, distance):
    if self.isdown():
        color = self.pencolor()
        self.pencolor('red')

        forward_original(self, distance)

        input("step> ")

        self.pencolor(color)
        forward_original(self, -distance)

    forward_original(self, distance)

def tree(branchLen, t):
    if branchLen > 5:
        t.forward(branchLen)
        t.right(20)
        tree(branchLen-15, t)
        t.left(40)
        tree(branchLen-15, t)
        t.right(20)
        t.forward(-branchLen)

myWin = Screen()

turtle = Turtle()

forward_original, Turtle.forward = Turtle.forward, visible_forward

turtle.speed('slowest')

turtle.left(90)
turtle.penup()
turtle.backward(100)
turtle.pendown()

turtle.color("green")
tree(75, turtle)

myWin.mainloop()


我只建议将此作为一种学习或调试技巧,而不是用于完成的代码。

我不使用IDLE,因此我无法在这方面帮助您。理解
的关键是,在完成绘制(子)树时,海龟已被放回其原始位置和方向。因此,每次递归调用都不会干扰当前位置和航向。