在给定深度改变递归函数
Varying recursive function at given depth
我有一个使用 python turtle
模块绘制分形的递归函数:
def fract(t, order, size):
if order == 0:
t.forward(size)
else:
for angle in (60, -120, 60, 0):
fract(t, order - 1, size / 3)
t.left(angle)
我有另一个函数调用第一个函数并修改最后一个角度,以便分形构建一个圆
def circle(t, order, size):
for i in range(order):
fract(t, 2, size)
t.right(360 / order)
circle(t, 4, 300)
虽然这按预期工作,但真正的目标是在单个递归函数中获得相同的结果。
显然这不是一个真正的编程案例,而是 python 初学者书中的一个任务,我完全坚持了下来。我想这个问题的尴尬标题反映了我对这个问题缺乏理解。
假设您的 fract()
函数应该调用自身,那么我已经能够 运行 您的代码成功。
您所做的是定义一个递归函数 fract()
,您的 circle()
函数会多次调用该函数。这称为组合函数。这是好事。
您的每个函数都有严格定义的行为,即它们是内聚的。这意味着其他程序员可以使用您的函数(尤其是 fract()
)并在他们自己的程序中重用它们。
我的意见是,最好有许多小的内聚函数(以及 类 和模块),它们可以以比最初预期更多的方式组合。
我同意@quamrana 对此事的看法,但让我们解决可能是一个难题。有点诡计。
首先,您的合并函数必须采用四个参数,因为 circle()
的 order
参数与 fract()
的 order
参数无关。我们将把其中的第一个重命名为 sides()
,因为这就是它所代表的。
其次,您的fract()
函数并不完全递归,它在内部使用迭代。我将在我的解决方案中遵循相同的模式。
最后,我们需要一些隐藏信息来处理——您可以使用内部更改的默认第五个参数,但我将使用 sides
的类型来实现这个结果:
import turtle as t
def fract(t, sides, order, size):
if order == 0:
t.forward(size)
elif sides is not None:
for _ in range(sides):
fract(t, None, order, size)
t.right(360 / sides)
else:
for angle in (60, -120, 60, 0):
fract(t, None, order - 1, size / 3)
t.left(angle)
t.speed('fastest') # because I have no patience
fract(t, 4, 2, 300)
t.hideturtle()
t.exitonclick()
我相信这可以在对原始代码进行最小更改的情况下实现您想要的结果。除了生成原始图形的 fract(t, 4, 2, 300)
调用之外,我们还可以进行 fract(t, 3, 3, 300)
:
等变体
您可能要解决的下一个问题是如何使这些图像在屏幕上居中,以便 fract(t, 5, 1, 300)
不会从边缘掉落。
我有一个使用 python turtle
模块绘制分形的递归函数:
def fract(t, order, size):
if order == 0:
t.forward(size)
else:
for angle in (60, -120, 60, 0):
fract(t, order - 1, size / 3)
t.left(angle)
我有另一个函数调用第一个函数并修改最后一个角度,以便分形构建一个圆
def circle(t, order, size):
for i in range(order):
fract(t, 2, size)
t.right(360 / order)
circle(t, 4, 300)
虽然这按预期工作,但真正的目标是在单个递归函数中获得相同的结果。
显然这不是一个真正的编程案例,而是 python 初学者书中的一个任务,我完全坚持了下来。我想这个问题的尴尬标题反映了我对这个问题缺乏理解。
假设您的 fract()
函数应该调用自身,那么我已经能够 运行 您的代码成功。
您所做的是定义一个递归函数 fract()
,您的 circle()
函数会多次调用该函数。这称为组合函数。这是好事。
您的每个函数都有严格定义的行为,即它们是内聚的。这意味着其他程序员可以使用您的函数(尤其是 fract()
)并在他们自己的程序中重用它们。
我的意见是,最好有许多小的内聚函数(以及 类 和模块),它们可以以比最初预期更多的方式组合。
我同意@quamrana 对此事的看法,但让我们解决可能是一个难题。有点诡计。
首先,您的合并函数必须采用四个参数,因为 circle()
的 order
参数与 fract()
的 order
参数无关。我们将把其中的第一个重命名为 sides()
,因为这就是它所代表的。
其次,您的fract()
函数并不完全递归,它在内部使用迭代。我将在我的解决方案中遵循相同的模式。
最后,我们需要一些隐藏信息来处理——您可以使用内部更改的默认第五个参数,但我将使用 sides
的类型来实现这个结果:
import turtle as t
def fract(t, sides, order, size):
if order == 0:
t.forward(size)
elif sides is not None:
for _ in range(sides):
fract(t, None, order, size)
t.right(360 / sides)
else:
for angle in (60, -120, 60, 0):
fract(t, None, order - 1, size / 3)
t.left(angle)
t.speed('fastest') # because I have no patience
fract(t, 4, 2, 300)
t.hideturtle()
t.exitonclick()
我相信这可以在对原始代码进行最小更改的情况下实现您想要的结果。除了生成原始图形的 fract(t, 4, 2, 300)
调用之外,我们还可以进行 fract(t, 3, 3, 300)
:
您可能要解决的下一个问题是如何使这些图像在屏幕上居中,以便 fract(t, 5, 1, 300)
不会从边缘掉落。