Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialRobert Peters
3,728 PointsI'm completely stuck on this question and can't figure it out at all, can someone help?
.
9 Answers
Jennifer Nordell
Treehouse TeacherHi, Robert Peters! Don't give up First, I'm sure you know what a list
is by now. This class is inheriting from the built-in class of list
. Whenever you create a list or really a string or any other thing, it gets a whole slew of things attached to it. For instance, a string gets a .upper()
and .lower()
method. Yes, it is a data type, but it is wrapped inside an object which provides extra functionality. Similarly the len()
function will tell you how long an iterable is. So any built-in type that you can use len()
on has a __len__
defined on the object. Even lists. It's a little belated, but I made a Halloween-themed example for you:
candy_bucket = ["snickers", "reeses", "skittles"] # just a regular list with some candy
print(len(candy_bucket)) # this prints out 3
class Liar(list):
def __len__(self):
return super().__len__() + 3 # we don't need self passed in and it would cause an error because __len__ takes 0 arguments
fake_bucket = Liar(candy_bucket) # a fake candy bucket
print(len(fake_bucket)) # prints 6
When you make a list you are calling an __init__
method for the list
object. Then it gets a __len__
. You only need to run the __len__
of the list
object (or super) and then modify the results.
Hope this helps!
ygh5254e69hy5h545uj56592yh5j94595682hy95
7,934 Points# Now I want you to make a subclass of list. Name it Liar.
class Liar(list):
# Override the __len__ method
def __len__(self):
# return the wrong number of items in the list
return super().__len__() + 3
Robert Peters
3,728 PointsThanks! can you explain why no 'self' is sent to the
super().__len__(self)?
ygh5254e69hy5h545uj56592yh5j94595682hy95
7,934 Points# It's been a while since I've used OOP but I know that in this case
super().__len__() # __len__() does not accept any arguments
Robert Peters
3,728 PointsIsn't it just working out the length of nothing then?
ygh5254e69hy5h545uj56592yh5j94595682hy95
7,934 Points# Not really
# Take a look at the list class that I created.
# I believe that it might be similar to what the list class looks like for the challenge
class list():
def __init__(self, _list = ["test", "test1", "test2"]):
self._list = _list
def __len__(self):
return len(self._list)
# When we call the
super().__len__()
# It calls the __len__ method of list class and returns the
return len(self._list) # 3
class Liar(list):
def __len__(self):
# so now, super().__len__() would return 3, and 3 + 3 = 6
return super().__len__() + 3
ygh5254e69hy5h545uj56592yh5j94595682hy95
7,934 PointsYou practice by creating short and fun programs. Check out this link, https://www.upgrad.com/blog/python-projects-ideas-topics-beginners/
Robert Peters
3,728 PointsAwesome, cheers! How far do I need to go before I can start doing some of those? Is it years, or if I keep going and actually manage to understand this python track within the next few months, can I do them then?
Robert Peters
3,728 PointsI'm sorry, it's probably a great answer, I just don't think I'm smart enough to be learning to code anymore. I've gone through these object-oriented python videos over and over again and I just seem too dumb
Vincent Zamora
3,872 PointsI feel the same way. Some of the stuff goes right over my head (really). What helps me sometimes is to do a video google search on the subject and walk through them.
I do like Jennifer's example.
ygh5254e69hy5h545uj56592yh5j94595682hy95
7,934 PointsDon't say that. You just need to keep trying and practice some more. Object-Oriented Programming is probably one the hardest thing for new programmers. You just have keep going. If you don't understand some concept just google it or ask us here in the community. We can help you go through this. Most of the times I experience the same thing. I'm trying to code in multiple languages and it's hard sometimes to remember syntax and concepts but I never give up. If I don't remember or understand something I google it. Without google I probably won't be able to code because my head is a mess. The way I learn is by look at other people's code and asking myself why do they use this for that and that for this.. etc. Trust me, I'm at the same position you are in. You just need to keep practicing and don't give up.
Robert Peters
3,728 PointsCheers man, I'll give it shot. I guess I don't know what I'd be googling, maybe "how does len know what to operate on without self?" Or "why does def len(self) have the argument self if it doesn't use it and you don't have to add it later?" Where did it go?
How do you practice by the way?
ygh5254e69hy5h545uj56592yh5j94595682hy95
7,934 PointsYou can start now and try to build it as much as you can. As you learn new things, you can add to your code and improve your old code.
Johnathan Martinez
30 PointsI agree with Stivan! Projects are definitely the way to go. You can also check out this link: https://www.dataquest.io/blog/python-projects-for-beginners/. It discusses why projects are the best way to learn. It's an extremely helpful framework for people just starting out. Good luck!
Ruby Wu
7,989 PointsThank for Jennifer Nordell providing the great example. It really helps me to understand the concept of this challenge. And also thank for Robert Peters to point out the question I also struggle with. I appreciate it!
Robert Peters
3,728 PointsRobert Peters
3,728 PointsThanks for the answer! I really don't get it though. How does it know what to operate on if nothing is sent to it? Without self or a variable containing a list passed to it, how does it know what to tell you the length of?
Jennifer Nordell
Treehouse TeacherJennifer Nordell
Treehouse TeacherHi, again Robert Peters! We did pass in something, though We passed in the
candy_bucket
which is a list. Now you can't actually see the class for list here, but it also has an__init__
. It's setting internal attributes at the time we create a list. The candy_bucket is being passed into the super class. That's how it knows. It's running the__len__
on that list we passed in.If we had done
fake_bucket = Liar()
with no list available it would print out 3. Because the super class of list had nothing passed to it so it has a len() of 0. So printing the len() of a Liar() would print 3.Robert Peters
3,728 PointsRobert Peters
3,728 PointsBut it's not:
super().__len__(candy_bucket)
It hasn't been passed anything, I don't understand sorry. When you define a method the first bit is always self (that's what's taught in the videos), but (dunder)len(dunder) takes no argument?
In Stivan's example he shows:
But no self is passed to it later on, even though it's literally right there as the fist argument required.
How did you pass candy_bucket to it? I can't see it being passed in your code, just
super().__len__() + 3
Jennifer Nordell
Treehouse TeacherJennifer Nordell
Treehouse TeacherHi, Robert Peters! I passed it when I did
Liar(candy_bucket)
. I think the part that's eluding you is the fact that alist
is a class. I cannot show you the internal code for that class because it is built-in to Python. It's not something you nor I wrote. TheLiar
class is inheriting from thelist
class. When you make a newlist
it has an__init__
that it runs and it has methods like.append()
etc. Your Liar class is inheriting all those. The only thing it needs to override is the__len__
method so that it returns something that is inaccurate. I've put together an expanded example that combines different ways to create a list. When you create a list it's running class methods like__init__
inside the list classHoping this helps!
edited for additional information
At the risk of complicating this, I feel obligated to point out that every class in Python gets an
__init__
even if you don't define one. In the case that you haven't provided an__init__
for a subclass, then the__init__
of the super class is called. So when I doLiar(candy_bucket)
the init ofLiar
is called, which is empty so it calls the__init__
oflist
and sends it the list.As far as
__len__()
not taking any arguments, it's the the__len__
of the super class (list) that does not take any arguments besides self. The list class is providingself
because self is different in the super class. It's an instance of list. Not an instance of Liar. So if you were to try and callsuper().__len__(self)
you would be sending in an instance of Liar to thelist
class. And it is already defined as taking itself, an instance of a list. It would be getting one too many things. An instance of list and an instance of Liar.Robert Peters
3,728 PointsRobert Peters
3,728 PointsThanks! I think I'm getting it...
The "So when I do Liar(candy_bucket) the init of Liar is called, which is empty so it calls the init of list and sends it the list." part definitely helped me get some of the previous vids.
Just quickly, does this mean that super() automatically sends self? And if so, does it always send self? The last paragraph about "The list class is providing self because self is different in the super class. It's an instance of list. Not an instance of Liar." is the bit that's getting me I think.
Thanks for the help!
Jennifer Nordell
Treehouse TeacherJennifer Nordell
Treehouse TeacherRobert Peters You're getting it! The list has methods like
__len__
and__init__
itself. So yes, alist
has those methods that takeself
whereself
is the instance of thelist
. But, again, onLiar
, if you send inself
to thesuper().__len__()
it's only expectingself
whereself
is the instance oflist
... notLiar
The
__len__()
of the super class already takesself
The actual code for alist
class is actually implemented in the C language so I can't really reasonably show you that. But imagine, if you will thatclass list()
has adef __len__(self):
It only accepts itself. Not any subclass's
self