2016-04-15 2 views
1

Это мой первый вопрос, и я надеюсь, что некоторые из вас найдут время ответить.Невозможно понять этот рекурсивный код python черепахи

Итак, моя цель - написать скрипт python, используя модуль черепахи, чтобы закодировать дерево pythagoras.

Я провел там несколько дней, и я действительно не мог продвинуться в прошлое, поэтому я посмотрел онлайн, чтобы помочь мне. Я нашел код, который делает то, что я хочу, но с очень небольшим строк кода:

import turtle 
t = turtle.Pen() 




LIMIT =11 
SCALAR = 0.5 * (2 ** 0.5) 


def drawTree(size, depth): 

    drawSquare(size) 

    if depth + 1 <= LIMIT: 

     t.left(90) 
     t.forward(size) 
     t.right(45) 
     drawTree(size * SCALAR, depth + 1) 

     t.forward(size * SCALAR) 
     t.right(90) 
     drawTree(size * SCALAR, depth + 1) 

     t.left(90) 
     t.backward(size * SCALAR) 
     t.left(45) 
     t.backward(size) 
     t.right(90) 



def drawSquare(sideLength): 

    for i in range(4): 
     t.forward(sideLength) 
     t.left(90) 



t.up(); t.goto(-100, -200); t.down() 
drawTree(170.0, 0) 

Так я понимаю, что большая часть кода, за исключением второго и третьего пункта «если»: почему они когда-либо выполняются? Если функция продолжает повторяться, она никогда не достигает этой точки в обычном режиме! Я уверен, что мне не хватает чего-то действительно легкого здесь, и я надеюсь, что вы все поняли мой вопрос :) Еще раз спасибо!

+0

Это все о 'depth' переменной. Первая функция 'drawTree' имеет глубину 0, поэтому оператор' if' равен true, а 'drawTree' вызывается с глубиной' 1', что также верно ... до тех пор, пока 'drawTree' не будет вызывается с глубиной '11', тогда оператор' if' является ложным, больше вызовов на drawTree больше нет, и функция возвращает, продолжая выполнение 't.forward ...' вперед на глубине '10' –

+0

Но с глубиной 11, когда утверждение if становится ложным, не должно ли оно просто полностью выйти из функции? В любом случае, спасибо за ваш вклад! – zeldamia

+0

Что сказал Симон. 'drawTree' не продолжает называть себя вечно, так что в итоге заявления после рекурсивного вызова _do_ выполняются. Когда рекурсивный вызов на глубине == LIMIT возвращается, управление переходит обратно к предыдущему вызову, где depth == LIMIT-1. И т. Д. Я предлагаю вам попробовать запустить код с 'LIMIT = 4' (или некоторым другим небольшим значением) с' print ('' * глубина, глубина, размер) 'непосредственно под' if'. –

ответ

0

Функция drawTree не перестает называть себя вечно, поэтому в конечном итоге выполняются инструкции после рекурсивного вызова do. Когда рекурсивный вызов в depth == LIMIT возвращается, тогда управление переходит к предыдущему вызову, где depth == LIMIT-1.

Вот несколько измененная версия вашего кода с паролем вызываемых вызовов print, которые помогут отслеживать выполнение.

Я также внес несколько других незначительных изменений. Я упростил расчет SCALAR: 0.5 * sqrt(2) == sqrt(0.5), и я только положил перо, когда черепаха на самом деле рисует квадрат. Я также добавил вызов turtle.mainloop(), чтобы окно оставалось открытым, когда чертеж закончен.

from __future__ import print_function 
import turtle 

LIMIT = 3 
SCALAR = 0.5 ** 0.5 
INDENT = ' ' * 4 

def drawTree(size, depth, branch): 
    print(INDENT * depth, branch, depth, 'start') 

    drawSquare(size) 

    if depth + 1 <= LIMIT: 

     t.left(90) 
     t.forward(size) 
     t.right(45) 
     drawTree(size * SCALAR, depth + 1, 'left ') 

     t.forward(size * SCALAR) 
     t.right(90) 
     drawTree(size * SCALAR, depth + 1, 'right') 

     t.left(90) 
     t.backward(size * SCALAR) 
     t.left(45) 
     t.backward(size) 
     t.right(90) 

    print(INDENT * depth, branch, depth, 'stop') 


def drawSquare(sideLength): 
    t.down() 
    for i in range(4): 
     t.forward(sideLength) 
     t.left(90) 
    t.up() 


t = turtle.Pen() 
t.up() 
t.goto(-100, -200) 
drawTree(100.0, 0, 'root') 

turtle.mainloop() 

выход

root 0 start 
    left 1 start 
     left 2 start 
      left 3 start 
      left 3 stop 
      right 3 start 
      right 3 stop 
     left 2 stop 
     right 2 start 
      left 3 start 
      left 3 stop 
      right 3 start 
      right 3 stop 
     right 2 stop 
    left 1 stop 
    right 1 start 
     left 2 start 
      left 3 start 
      left 3 stop 
      right 3 start 
      right 3 stop 
     left 2 stop 
     right 2 start 
      left 3 start 
      left 3 stop 
      right 3 start 
      right 3 stop 
     right 2 stop 
    right 1 stop 
root 0 stop 
0

Например, «глубина» - 10 и программа называется drawTree (размер * SCALAR, 10 + 1) в первом абзаце. «глубина» равна 11, IF - false, а программа возвращается обратно в drawTree, где «глубина» равна 10. А затем программа выполняет следующую строку, первую строку во втором абзаце.

Точно так же программа, называемая drawTree() во втором абзаце, в то время как «depth» не достигает LIMIT, затем возвращается назад и переходит в первую строку третьего абзаца.

Смежные вопросы