Basta Fazoolin'

Hi
I’m stuck on this Basta Fazoolin’ challenge. I keep getting the error:
Traceback (most recent call last):
File “script.py”, line 59, in
print(flagship_store.available_menus(1200))
File “script.py”, line 46, in available_menus
for menu in self.menus:
TypeError: ‘type’ object is not iterable

So far everything runs fine up to item 16 where you need to iterate through the menus to find which ones are available at a given time.
I’ve checked the ‘help’ video’s code as well as others on this site and i can’t figure out what’s going on.

def available_menus(self, time):
    menus_list=[]
    for menu in self.menus:
      if time >=menu.start_time and time <=menu.end_time:
        menus_list.append(menu)
    return menus_list`

“menus” is a list of the menu names as the help video shows to do vs using inheritance`

If something isn’t iterable, then you might consider whether you think it should be, and why so, and then it probaly isn’t that thing and you’d fix the part where you put that there, or maybe it shouldn’t be iterable and then you’d stop trying to iterate through it.

It should be - menus is a list of names of menus. A list is iterable. So I think i’m on the right path? the answer key also states this to be what i’m supposed to be doing.
I believe self.menus is referencing the list via Franchise’s init where i set self.menus=menus

if it’s a list it’s iterable. if it’s not iterable then it’s not a list.

I understand this - I understand a list is iterable and if it is not iterable than it is not referencing the/a list
so self.menus is clearly trying to iterate something else - which has me quite confused.
I just tried to print my “menus” list and it printed my Menu class string method for each menu in the list. …as a list.
ex: [“the kids menu is available from 11am to 9pm”,…]
So even with this list it should iterate as a list…even though it’s the wrong list.

i changed my menus list to include the names in quotes (which is NOT what the video walkthrough does) and now print(menus) prints a list of menu names as strings. So that’s progress… but regardless, still get the same ‘type object not iterable’ message.

no you’re trying to iterate through self.menus, to which you are getting the response that it is not iterable and therefore not a list

if you meant for it to be a list, then you put the wrong thing there and would fix the part where you put something there

I’m a bit confused. Where is “there”? the menus list? or where i initialized it in the Frachise’s init?

there’s no menus list, you have menus but it isn’t a list

I created a list… as the video did:
menus=[brunch, early_bird, dinner, kids]

maybe you’d want to iterate through that one
you’ve shown that self.menus isn’t that, because if it was it would be iterable

a = 5  # maybe you'd want to put a list here instead

for x in a:  # a is not iterable
    ...

i’ve tried that
it gives me more errors:
if time >=menu.start_time and time <=menu.end_time:
AttributeError: ‘str’ object has no attribute ‘start_time’

and is not what the video walkthrough does - which my code has mostly lined up with thus far.

if i try self.start_time and self.end_time it tells me those don’t exist in Franchise… which they should not since we are not using inheritance here.

I had one error that popped up a few times "Traceback (most recent call last):
File “script.py”, line 60, in " but this went away as I corrected the code and have no had any errors up to task 16.

does it give you more errors or do you already have more errors elsewhere?

Well you’d do the same thing regardless of which error you’re dealing with. You’d read it because it says where and it says what the impossible situation is. Then you’d compare that situation to what you meant should be happen there, and adjust accordingly.

If something isn’t iterable and it should be iterable… change it to something iterable.
If something is a string instead of a menu entry, go swap it out.

correct. The issue is I can not do that if I do not know where to do that.

in your responses you have told me if i’m iterating through the wrong thing then to change what i’m iterating through - I have changed it form self.menus to just menus as you pointed out…
but now that i’m doing that, isn’t it no longer referencing anything from the Menu class? That is - it’s ONLY referencing the items in the list now?
all of the errors I get now point out that there is no “start_time” or “end_time” to use in the if statement.
if i try taking away the *. in front: it says start_time and end_time are not defined and in any other configuration (self or menu, or menus .start_time) it says the list object has no attribute - i’m assuming because i’m pulling from a list I created that is not referencing anything but the items in the list.?

No you’d probably iterate through self.menus, that’s what you meant, isn’t it?

But self.menus is the wrong value. You say it should be iterable. It’s not. So you put the wrong thing there.

that’s the same situation.
if you expect there to be start_time and end_time attributes on a menu, then that’s because you expect a menu to be an instance of some class you made. but your error message says it’s a string. so did you mean to put a string there, or a menu item? if you meant for it to be a string then you should probably not be trying to read those attributes. or if you did not mean for it to be a string, then go fix the code that put that string there

If you put a bunch of menu items in a list.

And then read that list, you’ll find menu items in it.

If you do not put menu items in a list, then you will not find menu items in it.

And if you look in your list and you don’t find menu items in it, then you can conclude that you did not put menu items in it.

There’s nothing more complicated than that involved. You put the wrong thing there, you get the wrong thing when you look.

what you are saying is not what I’m looking for. I am looking for menu names to iterate through in order to reference the menu’s and check agains their start and end times…

is it easier for you to help me if i just past my code here?

i don’t think we are on the same page and it’s making me more confused.

There are a few things going on here that i’ve touched on. When I make the changes you discuss they flip flop back and forth between the same errors in different configuration.
I am feeling you are continually just telling me to change something that wants to be a string to a string and something that wants to be an iterable list into a list… these comments are not helping me. On the base level I understand if it’s saying it wants a string - replace it with a string… if it wants a list… give it a list etc. I understand you can’t add a string to an int by means of simplistic dog = “cat”+1

my confusion goes into how these classes are communicating with each other via ‘self’ and how to actually use the different elements within the code for the task. I am very clear that i am feeding the for loop the wrong information but for hours I have not been able to figure out where that information is going wrong.

what I think is the biggest breakthrough is that if i try to print the list i made:
menus=[brunch, early_bird, dinner, kids]
via print(menus) the output is the message created in the repr in the Menu class. So, i would assume the for loop is trying to iterate through the entire message:
[this is the Brunch menu. It is available from 1100 to 1600, this is the Early-Bird menu. It is available from 1500 to 1800, this is the Dinner menu. It is available from 1700 to 2100, this is the Kids menu. It is available from 1100 to 2100]
rather than just the names in the list.
IF it were to actually be using the right menu names, continuing to the if statements - I don’t know what to use to reference the start and end times because using “self” in this case does not work. The error says This is because there is no initializing of start or end within Franchise.
The video walkthrough uses the items from the for loop (menu.start_time)- which may work for me if i could get the for loop to actually look at the right thing to iterate through and produce the right items

If you have a list of Menu, like so:

for menu in [Menu(), Menu(), Menu()]:
    print(menu.start_time, menu.end_time)

then you’d be able to use those attributes just fine.

but instead, as your error message says, you have:

for menu in ['', '', '']:
    print(menu.start_time, menu.end_time)

so then you’d have to ask yourself, hey, what was supposed to be in this list? Menu’s, or strings? If you put the wrong things in that list, then you’d have to go fix that in the location where you put the wrong things in it.

and then if you fix something and end up finding another problem, that would be progress, and you’d move on to fixing the next problem.

if that puts you in a loop of endlessly fixing the same two things, then you’re not fixing them at all, and maybe you’re forgetting to consider what should actually happen.

you fix a bug by looking at the situation and comparing to what you mean should happen. you adjust the thing that is different.

alright - all these hours have come down to formatting.
I pulled all of the class and methods up to the top of the console and pushed all of the data to the bottom and now it works
The original code I had was the correct code - in that i was supposed to use self. menus and menus.start/stop_time as my code was.

Ionatan - I really appreciate you trying to help me with this but I think we ended up going in the wrong direction for a very long time.

in regards to following the causes and figuring out the mistakes - this was a doooozie for me since none of the errors related to what was the issue and caused me to change my correct chunks of code several times and destroy what was working more and more.
reverting it back to what I had and just shifting everything’s placement on the page was the fix that I would not have thought of

Perhaps I didnt absorb the section in this module where I would have seen that you can’t put data between the two classes and your classes should be put together above your data. … which I guess makes sense for creating methods…like importing modules

doesn’t matter what’s causing it.
whatever it is, you would observe and adjust and follow the causes and you would end up reaching the location where the mistake is

you’re going to make trivial mistakes all over the place

you can’t just decide to stop making mistakes

regardless of the mistake, you’d do the same thing

if you do this:

a = "wrong value"
b = "right value"

print(a)

then you’d see it prints the wrong value. why is that? where is that coming from? well you’re printing a, so you would look at the definition of a. is the definition of a correct? maybe it is, maybe you meant to use b, not a. or maybe a should be referring to the right value, in which case you’d fix the definition.

so you would change to one of these:

a = "wrong value"
b = "right value"

print(b)
a = "right value"

print(a)

you may have been setting your variable in some other function or method at some other time, but that’s still something you can trace back from where you discovered the problem.

nothing wants to be one thing or another.
they are whatever you make them. you’re the one responsible for all of that. if it’s the wrong thing, you’d change it to what it should be.