Event Coordinator

Learn Intermediate Python 3 | Codecademy

Currently I am doing Generator’s objective in which I found difficulty in solving it.
Here I am getting error like this:

Traceback (most recent call last):
File “script.py”, line 18, in
print(next(r1))
File “script.py”, line 6, in read_guestlist
if len(line_data) < 2:
TypeError: object of type ‘NoneType’ has no len()

Another thing I found out that every next(r1) call the value from file and a None value why?

Here is my code:

guests = {} def read_guestlist(file_name): text_file = open(file_name,'r') while True: line_data = yield text_file.readline().strip().split(",") if len(line_data) < 2: # If no more lines, close file text_file.close() break name = line_data[0] age = int(line_data[1]) guests[name] = age r1 = read_guestlist("guest_list.txt") for i in range(10): print(next(r1))

guest_list.txt

Tim,22
Tonya,45
Mary,12
Ann,32
Beth,20
Sam,5
Manny,76
Kenton,15
Kenny,27
Dixie,46
Mallory,32
Julian,4
Edward,71
Rose,65

Can Anyone help me out in how to solve this error?
Thank you.

Be careful about what you return/yield from a function. Double check what the the type of the return is as it appears to be something other than what you expect.

Thank you for the reply

Can you tell me why its giving me the None value?

And which value do I yield if the question in as below?

Modify this function to be a generator function that will yield each read line so that each guest name is yielded each time for the generator.

This is the program which have given by the codecademy:

guests = {}
def read_guestlist(file_name):
    text_file = open(file_name,'r')
    while True:
        line_data = text_file.readline().strip().split(",")
        if len(line_data) < 2:
        # If no more lines, close file
            text_file.close()
            break
        name = line_data[0]
        age = int(line_data[1])
        guests[name] = age

I think you might be mixing up standard generators and the additional options with .send you can use for co-routines and such.

In short, yield normally returns None. Whilst you can pass values in with .send there is no good reason to do it here. Consider the structure/flow of your code so that you’re not attempting to store anything from yield.

This has nothing to do with the problem of None being returned but it might also be worth considering what lines are actually worth adapting from that example, there’s a lot of chaff that never gets used (and for the sake of this example I’ll pretend I didn’t see unclosed file objects drifting around :grinning_face_with_smiling_eyes:).

Thank you for the reply.

I have seen how yield works and how it returns none, but still I can not get the desired output.

Can you tell me which value to yield if I want all the name inside the guests dictionary including the "Jane,35" which I will send it using .send method?

You’ve lost me there but I’ve not actually done this lesson. If you covered using the .send method in a previous lesson consider recapping how you did that as I assume you’d be looking for a similar option.

I gone through them twice still cannot get the idea to solve this last objective. If I skip the None value I can get the output but in the guests list there is only one guest available which I sent using object.send('Jane,35')

Hey there,

I seem to have the same problem as @dhruvp1997. I have managed to make the code runs smoothly for all steps, but I can’t find a way to add “Jane,35” into the dictionary using .send() method. Does anyone know how to solve it?

I found the solution after another user shared his solution on my thread (thanks @raultozetto019835826 for your help)

guests = {}
def read_guestlist(file_name):
    text_file = open(file_name,'r')
    while True:
        x = yield
        if x is None:
          line_data = text_file.readline().strip().split(",")
        else:
          line_data = x.split(",")
        if len(line_data) < 2:
        # If no more lines, close file
            text_file.close()
            break
        name = line_data[0]
        age = int(line_data[1])
        guests[name] = age
        yield name 
                                            
guestlist = read_guestlist('guest_list.txt')

for k in range(20):
  print(next(guestlist))

#Add Jane,35 to the generator
next(guestlist)
guestlist.send("Jane,35")

for k in range(8):
  print(next(guestlist))

def guest_age(guest_dict):
  for key,val in guest_dict.items():
    if val > 21:
      yield key

age_of_guest = guest_age(guests)

for obj in age_of_guest:
  print(obj)

def table_one():
  for j in range(1,2):
    for k in range(1,6):
      yield "Chicken", "Table {}".format(j),"Seat {}".format(k)

def table_two():
  for j in range(2,3):
    for k in range(6,11):
      yield "Beef", "Table {}".format(j), "Seat {}".format(k)

def table_three():
  for j in range(3,4):
    for k in range(11,16):
      yield "Fish", "Table {}".format(j), "Seat {}".format(k)


def combined_tables():
  yield from table_one()
  yield from table_two()
  yield from table_three()

combined_tables = combined_tables()

def guest_assignment():
  for name in guests.keys():
    yield name, next(combined_tables)

guest_assignment = guest_assignment()
for person in guest_assignment:
  print(person)
3 Likes

That’s great. Thank you for the answer.

This is my solution but it does not work for me when I go to send the Jane information. I get the StopIteration exception and I have to move the guests dictionary inside of the generator or else I get a TypeError saying generator object does not support item assignment (the statement guests[name] = age). Did this code actually work for you? I can’t seem to find why it’s not working for me as so many people share this answer and have stated it works for them.