I struggled for days with this question, which is part of a course project. In the question, you are asked to create a generator and to use 'send', hence using 'yield'. As Blenderinho says, the dictionary relates to another question in the project.
Someone very kindly gave me their solution to the whole project - which worked! - and I think I maybe now understand 'send' and 'yield' a bit better. I thought the best way to test my own understanding is to attempt an explanation of 'send' and 'yield' - below is my attempt. The code below is pared down to the minimum to try to make it clear what they do.
Input:
def addPerson():
while True:
newName = yield
yield newName
g=addPerson()
print(next(g)) #1
print(g.send('Jane, 35')) #2
print(next(g)) #3
print(g.send('Liz, 50')) #4
print(next(g)) #5
Output:
None #1
Jane, 35 #2
None #3
Liz, 50 #4
None #5
#1 The value of 'next(g)' here is 'None' and the generator regards this as the current value of 'yield'. So, because newName is assigned yield's value via the line, 'newName = yield', the value of newName is now 'None'. The generator then reaches the line, 'yield newName'. Since the current value of newName is 'None', it yields 'None' and 'None' is the output.
#2 The value, 'Jane, 35' is 'sent' to the generator. This value becomes the value of 'yield'. So, because newName is assigned yield's value via the line, 'newName = yield', the value of newName is now 'Jane, 35'. The generator then reaches the line, 'yield newName'. Since the current value of newName is 'Jane, 35', it yields 'Jane, 35' and 'Jane, 35' is the output.
#3 The value of 'next(g)' is None so step 1 is repeated.
#4 The value, 'Liz, 50' is sent to the generator so step 2 is repeated, but this time with the value 'Liz, 50' instead of the value, 'Jane, 35'.
#5 The value of 'next(g)' is None so step 1 is repeated.
After this, there are no further next(g) or send lines, so the 'while True' loop terminates.
So, in summary:
The first mention of 'yield' - in this case in the line, 'newName = yield' - assigns to 'yield' the value of the 'next(g)' or the value of 'send' that is currently going through the while True loop.
The value of yield, in turn, can then be assigned to another variable eg newName. Here, this is done in the same line, 'newName = yield'.
The output of the current loop is the value of 'yield' at the point the generator reaches the line 'yield [variable]', here 'yield newName'. Once it has reached the line 'yield [variable]' line the current loop terminates.
You can't 'send' before at least one 'next(g)' has gone through the generator. This is because 'send' replaces the existing yield with 'its' value. If there is no existing yield to replace because nothing has yet been 'yielded', 'send' cannot work.
If the generator has been passed something with a finite number of values, such as a list or dictionary, as in:
def addPerson(list):
and g=addPerson(list)
each item in the list or whatever passed to the generator is assigned as the value of 'yield'. When all the items have been processed by the generator, there are no more values assigned to 'yield', 'while True' no longer holds, and stopIteration is raised. So 'while True' holds only while values are being assigned to yield.