def countDown(i):
    if i<> 0:
        For j in countDown( i - 1 ):
            yield j
        yield i                 
if __name__ == '__main__':
    for k in countDown(5):
        print k
        if k == 6 : break
On debugging this code , the execution path was bit different from what I expected. My expectation: The "for" loop in countDown will call the function recursively: countDown(4), countDown(3), countDown(2) , and countDown(1) and countDown(0). At this point the if condition is not satisfied then the "return phase" starts, Yield j will be executed . This will return the control back to for loop in "main" function.
The next iteration of this for loop , again calls countDown(5) which starts where the last Yield left off - Yield j. This executes the for ... countdown(i-1) loop, and calls countDown(4), countDown(3) , CountDown(2).. countDown(0). Then the "return phase" begins and hit the first Yield j( j is now incremented from the first pass earlier). This will return the control back to the for loop in the "main" function.
On debug, this is what I found:
1)once it fails if i<>0 as explained in at the end of recursion, it seems to execute Yield i. Then it seems to Pop out every countDown in Stack before the control goes back to for k ... main.
2) in the Second iteration For k in g , stack enters return phase - top to botom of the stack is countDown(1) ,countDown(2),countDown(3), countDown(4) then it starts "return phase". In this phase j has the value of '1'. So. how come it does not go down to countDown(0) where i = 1 before starting the return phase?
Can anyone please explains the how this is supposed to work - combination of recursion and Generator function? Sorry for the long windy post- had no other way to explain it
Thx. guys for the reply.
My understanding so far :
1) first iteration of for k in countDown(5): entry
Function Instruction
========           ===========
countdown(5)      for j in countDown(4)
countdown(4) for j in countDown(3)
countDown(3) for j in countDown (2)
countDown(2) for j in countDown(1)
countDown(1) for j in countDown(0)
countDown(0) If statement fails and returns nothing
return phase
a)
countdown(5) for j in countDown(4)
countdown(4) for j in countDown(3)
countDown(3) for j in countDown (2)
countDown(2) for j in countDown(1)
CountDown(1) for j in countDown(0)= nothing - since countDown(0) returns nothing (because of failed if condition), j has nothing annd hence yield j, does not get excuted(Yield j is within the For loop). But, Yield i gets executed ,i here is 1 . So countdown(1) returns 1 to the previous recursion.
b) countdown(5) for j in countDown(4)
countdown(4) for j in countDown(3)
countDown(3) for j in countDown (2)
countDown(2) for j in countDown(1)= 1. The value of j is now '1'. SO, the For j in countdown(1) is true . Hence, it excutes Yield j = 1. As a result countDown(2) returns 1 This is where j gets assigned i.
c) countdown(5) for j in countDown(4)
countdown(4) for j in countDown(3)
countDown(3) for j in countDown (2)= 1 The value of j is now '1'. SO, the For j in countdown(2) is true . Hence, it excutes Yield j = 1. As a result countDown(3) returns 1
...
e) Countdown(5) for j in countDown(4) = 1 The value returned by count Down(4) is 1 . Hence, j is 1. So, the for j in countDown(4) gets executed.
               The next statement Yield j  within the For statement gets exceuted.
                it returns 1.
for k in countDow(5) , k will get 1.This will be printed out.
2)Now to the second iteration of for k in countDown(5)
recursion "Entry"
=================
countdown(5) for j in countDown(4) where j = 1 (Yield j was the last statement executed)
countdown(4) for j in countDown(3) where j = 1
countDown(3) for j in countDown (2) where j = 1
countdown(2) for j in countDown(1) where j = 1
countdown(1) executes Yield i , since the previous iteration, step a) yield was the last statement exceuted
recursion return
a) countdown(5) for j in countDown(4) where j = 1 (Yield j was the last statement executed)
countdown(4) for j in countDown(3) where j = 1
countDown(3) for j in countDown (2) where j = 1
countdown(2) for j in countDown(1) where j = 1 Countdown(1) returns a value of 1, j already has a value of 1, so, it executes next step which is yield i where i = 2. countDown(2) returns yield i = 2
b) countdown(5) for j in countDown(4) where j = 1 (Yield j was the last statement executed)
countdown(4) for j in countDown(3) where j = 1
countDown(3)     for j in countDown (2)
                 since countDown(2)  returns 2, j gets this new value j = 2
                 yield j gets executed
c)
countdown(5) for j in countDown(4) where j = 1 (Yield j was the last statement executed)
countdown(4) for j in countDown(3) where j = 1 since countdown(3) returns a value of 2 as shown in b) the new value of j is 2
...
e) countdown(5) for j in countDown(4) j becomes 2
<>in Python, use!=.