Я вычисляю 1 - x + x^2 - x^3 + ..... с помощью рекурсии. Так что это 1 - x*(1 - x*(1 - x*..., и мне нужно вызвать 1 - x*F(x) на этапе рекурсии Земли. Код на Python находится здесь:

def F(x, epsilon, k, y, iteration, value):
    if(iteration == k):
        print('run out of iterations', )
        return 1 - x 
    else:
        return 1 - x * F(x, epsilon, k, y, iteration + 1)

Интересно, есть ли способ узнать мгновенное значение F для текущего вызова. Банкомат на мой взгляд, я не могу это сделать. Критики приветствуются!

0
user6557479 12 Дек 2016 в 16:19

4 ответа

Лучший ответ

Для простых задач или для понимания, я обычно просто запускаю свой отладчик (теперь я использую Spyder) и смотрю на различные значения, изменяющиеся на разных уровнях рекурсии. Если возвращаемое значение является проблемой, как это часто бывает, я сохраняю это значение в локальной переменной, прежде чем вернуть его, чтобы увидеть его непосредственно в отладчике. В вашем примере кода это означает изменение ваших return строк на

result = 1 - x
return result

И

result = 1 - x * F(x, epsilon, k, y, iteration + 1)
return result

Конечно, в вашем случае вы могли бы просто иметь одну строку return в конце функции после присвоения результата, что в любом случае является лучшим стилем. Обычно этого достаточно. В более серьезной ситуации я печатаю значения в консоль, добавляя строку

print(iteration, result)

Между строками result = и return, возможно, с паузой input('Press any key to continue...') после печати. Если проблема действительно серьезная, я сохраняю значения в текстовом файле, но это теряет непосредственность просмотра при сохранении его для анализа.

0
Rory Daulton 12 Дек 2016 в 13:34

Вы имеете в виду что-то вроде:

def F(x, epsilon, k, y, iteration, value):
    if(iteration == k):
        print('run out of iterations', )
        return 1 - x 
    else:
        a=1 - x * F(x, epsilon, k, y, iteration + 1)
        print a
        return a
0
Dadep 12 Дек 2016 в 13:28

Это похоже на хороший пример использования функции . Это функция, которая автоматически применяется к «украшенной» функции, заменяя ее расширенной версией.

Для отслеживания вы можете использовать что-то вроде этого. Это напечатает все вызовы вашей функции с соответствующими параметрами и результатами, все с хорошим отступом, так что вы увидите, что называется чем.

def trace(f):
    trace.depth = 0
    def _f(*args, **kwargs):
        print("  " * trace.depth, ">", f.__name__, args, kwargs or "")
        trace.depth += 1
        res = f(*args, **kwargs)
        trace.depth -= 1
        print("  " * trace.depth, "<", res)
        return res
    return _f

Таким образом, вам не нужно добавлять какие-либо операторы print в саму функцию. Просто примените декоратор к вашей функции следующим образом:

@trace
def F(x, epsilon, k, y, iteration, value):
    ...

Это эквивалентно F = trace(F); тогда просто вызовите свою функцию.

Вот пример использования простой функции Фибоначчи:

@trace
def fib(n):
    return 1 if n < 2 else fib(n - 1) + fib(n - 2)

>>> fib(2)
 > fib (2,) 
   > fib (1,) 
   < 1
   > fib (0,) 
   < 1
 < 2
0
tobias_k 12 Дек 2016 в 16:15

Вы можете поместить результат в переменную перед его возвратом, т.е.

def F(x, epsilon, k, y, iteration, value):
    if(iteration == k):
        print('run out of iterations', )
        res = 1 - x
    else:
        res = 1 - x * F(x, epsilon, k, y, iteration + 1)

    print(res)

    return res
0
Ilia Novoselov 12 Дек 2016 в 13:28