Изменение рекурсивной функции на заданной глубине - PullRequest
0 голосов
/ 12 мая 2018

У меня есть рекурсивная функция рисования фрактала с использованием модуля 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)

Хотя это работает так, как задумано, реальная цель - получить тот же результат в одной рекурсивной функции.

Очевидно, что это не реальный пример программирования, а задача из книги начинающего питона, с которой я полностью застрял. Я полагаю, что неловкое название вопроса отражает мое непонимание проблемы.

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Я согласен с мнением @quamrana по этому вопросу, но давайте решим, что может быть трудной проблемой. С небольшой хитростью.

Во-первых, ваша консолидированная функция должна принимать четыре аргумента, поскольку аргумент order для circle() не связан с аргументом order для fract(). Мы переименуем первый из них в 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):

enter image description here

Следующая проблема, которую вы, возможно, захотите решить, - это центрирование этих изображений на экране, чтобы fract(t, 5, 1, 300) не падало с края.

0 голосов
/ 12 мая 2018

Если предположить, что ваша fract() функция должна вызывать сама себя, тогда я смог успешно запустить ваш код.

Что вы сделали, это определили рекурсивную функцию fract(), которая называется множественнойраз вашей circle() функцией.Это называется составлением ваших функций.Это хорошо.

Каждая из ваших функций имеет строго определенное поведение, то есть они взаимосвязаны.Это означает, что другие программисты могут выбирать ваши функции (особенно fract()) и повторно использовать их в своих собственных программах.

Мое мнение таково, что лучше всего иметь много небольших связанных функций (а также классов и модулей), которыеможно комбинировать многими способами, чем предполагалось изначально.

...