【问题标题】:Stepping Through Python Turtle Recursive Function单步执行 Python Turtle 递归函数
【发布时间】:2017-02-02 21:15:12
【问题描述】:

我正在努力提高对递归的理解,视觉表示对我非常有帮助。我有一个递归的树图函数,我希望能够逐步完成它并考虑每个阶段会发生什么。我找到了 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()

【问题讨论】:

  • 我不使用 IDLE,所以我无法帮助你。理解tree 的关键在于,在(子)树的绘制完成时,海龟已被放回其原始位置和航向。所以每次递归调用都不会干扰当前位置和航向。

标签: python debugging recursion turtle-graphics


【解决方案1】:

我可以想到两种方法可以帮助您形象化这些步骤。

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

def tree(branchLen, t):
if branchLen > 5:
    t.stamp()
    t.forward(branchLen)
    ...

你已经拥有了乌龟的速度。另一种减慢动作的方法是导入time 模块并使用sleep 函数。如果使用此解决方案,我建议您在递归调用 tree 之前使用 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)

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

【讨论】:

    【解决方案2】:

    这是一种在不修改原始递归子例程的情况下可视化正在发生的事情的方法。首先,我们通过反转符号将backward() 更改为forward()。然后我们破坏了forward() 的一个新实现,它改变了笔的颜色、画线、在控制台等待回车、撤消它刚刚做的事情,最后做原来的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()
    

    我只推荐这个作为学习或调试技巧,而不是用于完成的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 2017-11-26
      • 2020-04-17
      • 1970-01-01
      相关资源
      最近更新 更多