-1

i cant figure out why my generator is not returning value =11, here is my code:

    def monG(borneinf,bornesup):
        while True:
            if bornesup < borneinf:
                 bornesup, borneinf = borneinf, bornesup
            borneinf += 1
            if borneinf==bornesup:
                 break
            x=(yield borneinf)
            if x is not None:
               borneinf = x

     c=monG(2,10)
     for a in c:
        if a==5:
            c.send(20)
        print(a)

Output:

3
4
5
12
13
14
15
16
17
18
19

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • for others that did not encounter this weird `x = yield ..` and `gen.send(20)` thingy: [realated questions regarding generator.send()](https://stackoverflow.com/questions/19302530/python-generator-send-function-purpose) – Patrick Artner Jan 17 '19 at 18:23
  • 6
    You are throwing away the result of c.send(20), which is 11. – MisterMiyagi Jan 17 '19 at 18:23
  • When you get to a resolution, please remember to up-vote useful things and accept your favourite answer (even if you have to write it yourself), so Stack Overflow can properly archive the question. I think you also get a few reputation points for doing that. – Prune Jan 17 '19 at 21:58
  • how can i do that? it says i dont have enough reputation points, sorry but im new here. – Newgate Ace Jan 17 '19 at 23:07

2 Answers2

2

Let's trace the operation a little more closely:

def monG(borneinf,bornesup):
    while True:
        if bornesup < borneinf:
            bornesup, borneinf = borneinf, bornesup
        borneinf += 1
        if borneinf==bornesup:
            break

        print("TRACE", borneinf, bornesup)
        x=(yield borneinf)
        if x is not None:
            borneinf = x

c = monG(2,10)
print(type(c))
for a in c:
    if a==5:
        print(c.send(20), "a==5")
    print(a)

This gives us a special tag on the c.send line, as well as a peek just before the yield

Output:

<class 'generator'>
TRACE 3 10
3
TRACE 4 10
4
TRACE 5 10
TRACE 11 20
11 a==5
5
TRACE 12 20
12
TRACE 13 20
13
TRACE 14 20
14
TRACE 15 20
15
TRACE 16 20
16
TRACE 17 20
17
TRACE 18 20
18
TRACE 19 20
19

As MisterMiyagi pointed out, yield does return 11, but you threw it away. Perhaps you wanted to assign that value to a -- although messing with loop parameters is a definite code smell. If you make that assignment, you print out 11 instead of 5 on that iteration.

I think that your basic problem is that you interfered with your iteration flow, forcing an extra yield inside the loop. In the loop you coded, that implicit yield means that you don't get both 5 and 11 on successive iterations.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • thanks for the clarification, i see what is going wrong now, i actually didnt know that i could catch the result in c.send(20). i should learn more about generators methods – Newgate Ace Jan 17 '19 at 20:56
  • I know the feeling; I just did some of that research so I could answer your question. – Prune Jan 17 '19 at 21:57
1

Because in any case you increase the value!

Add the "else" block:

Like this:

def monG(borneinf,bornesup):
    while True:
        if bornesup < borneinf:
            bornesup, borneinf = borneinf, bornesup

        if borneinf==bornesup:
            break

        x=(yield borneinf)
        if x is not None:
            borneinf = x
        else:
            borneinf += 1

c=monG(2,10)
for a in c:
    if a==5:
        c.send(20)
    print(a)

Output:

2
3
4
5
11
12
13
14
15
16
17
18
19
Jundullah
  • 113
  • 2
  • 11