I notice a lot of people seem to be confused with how these functions seem to be triggered without calling them. Remember these are built in functions that have already been defined. By redefining each of the functions Tim has showed in this video, when the addition, subtraction, multiplication etc is used within this program the redefined or in other words "overloaded" functions like __add__, __sub__ etc will be used when the corresponding arithmetic operators are used like +, - , * etc. Now for strings, the "+" is used to concatenate two strings together. (Just to clear that up for those that asked this question)
Thanks for explaining the video in simpler words, one more question, could you tell why certain methods inside class start with underscores eg: __func__ ()??
@@shyren_more So the methods that start with underscores are to let python know "Hey those methods already exist" hence built in methods but are methods in which we are able to redefine the definition of that method within this particular class.
overloading methods like: _add__, __sub_, etc. so in this example where are overriding methods? another question is if we can create new operators that do not exist in python with these methods?
Leaving this here for anyone who sees this in the future: I *think* there's a mistake toward the end of the video, when Tim quickly says that he could have used __len__ instead of the length() method that he made. I'm not sure if I'm understanding 100% correctly, but I don't think this makes sense. __len__ looks for the number of items (attributes) in an object. In this case, every Point() object has two attributes. The length() method, on the other hand, is literally a mathematical formula for determining the distance of a point from the origin 0,0. These are two completely different things. For example, if we have Point(1,2), the __len__ of that is 2, because there are two attributes (x and y). However, the *length*, which is a numerical value as determined by that formula, would be sqrt(1**2 + 2**2), which is about 2.23. This is why some of you are getting errors about float types not being integers. __len__ is trying to find the integer value of how many attributes are in the object, whereas length() is an actual float number derived from a calculation. Other than that this is rock solid, all of Tim's videos are amazing. I have learned more about OOP in a couple hours watching these than I did taking a Python Bootcamp course from Udemy. Tim, if you ever read this, you seriously rock. You are going to go far in the CS world.
Actually, the only issue is that the __len__ method must always return an Int. That's pretty much all of it. If you take the result of that formula he used for the length of the vector (which is a Float) and use int() on it, you won't get type errors (which kinda means that, for this use, __len__ isn't ideal).
One tip : If you are a beginner, I understand these concepts would be hard to understand, so my tip is make some projects with basic concepts of Object-Oriented Programming and then start defining these special methods in your new and a bit advanced projects if they are needed..
1:21 Tim: "you'll see what i mean in just a second". 5 hours later, me: "this is a very long second..." Anyways bro, my ineptitude not yours. You're the best out there thanks a million for all your help!
one thing i think you should mention is how it is important to define certain functions before others, like if you were to write the def length function you created after all the comparisons, the boolean value wouldn't be able to execute true or false if it didn't have a way to use your length function
@@vagifk2864 Well atleast in this case for efficiency, but it is maybe better to do "from math import sqrt" and optionally "del sqrt" for larger projects.
I think you're wrong about your def __eq__. They can still have the same length if their x or y coordinates are the same. For example: if they were like this: (3,2) and (2,3). Still great videos and good explanation, though.
Instead of using built in function, I did used print(p1.__div__(p2)) to do division function. It did result same as the built in function, just to show there is another method to do the operation if the class had these methods :)
W OOPs. Too involved for me. I just made the __add__ method print text "Hello". Said the same thing but a lot shorter. But, saying that, I didn't know you could override built in methods and will be tinkering with it later. Thanks for another great insight Tim.
The equals method is wrong because two points can have the same length without being the same coordinate. For example (5,5) and (-5,-5), they have the same length but they are two different coordinates
For p1, (3,4) FOr p2, (3,2) So the first 3 is self.x and the second 3 is p.x Nd for the 4 is self.y and 2 is the p.y right? So, why the second x is p.x?
Great tutorial and serie. It's very good for a beginner like me. One question. the page you mention at the end is shut down. Any ideas where I can find something similar?
SinanM, I think it stands for "moving the original point horizontally by x, and vertically by y, where x and y is the parameters passed by method calls.
I wonder if people find it hard because of the linear algebra concepts he used as examples or because the actual approach? Because I have some modest physics background the linear algebra example made it really click
I disagree with the way you defined the "equals" method. The other comparators were comparing the scalar lengths (magnitude), while the "equals" method seem to be defined to compare identities? For example, length(2,2) == length(-2, -2), but clearly they are not the same point. The method as defined in your video would be more suited to an "is" method or something else. This is an identity vs equality issue.
I think I understand what you're saying, but it seems like the expression tim used for the equals would actually work. I 'd really be honored if you reply with more insights on what you mean.
@@aminuabdusalam3086 I'm not the original commenter, but felt I could help. Just simply think about mirrored points in relation to the origin. For example (3, 3) and (-3, -3). They have different coordinates, however, the length of both are equal. Or also (3, 4) and (4, 3). You'll see both lengths are equal to 5, despite the x and y values not being the same. Had Tim used the expression he used for the others (sqrt(x² + y²)), it would indeed work, but he changed it. I basically just repeated what OP said, but hope it helped.
I think this is an awesome series, but in this case I agree with djfoo000. We need to be clear what we mean by p1 > p2, p1 < 2 and p1 = p2. if we mean the length of the vector (which is what was used to calculate p1 > p2 and p1 < p2), then we can't say p1 = p2 only when p1.x == p2.x and p1.y == p2.y, as there are an infinite number of vectors with the same length but the equality test only allows for the two vectors to be the same vector. If it were just a matter of rounding errors and how the calculations were done, then the definitions should be done in this order: def __eq__(self, p): # put the "better" definition of the = operator here def __ge__(self,p): return (self.length() > p.length()) or (self == p)) ;;; def __le__(self.[): return (self.length() < p.length) or (self == p) One thing I am wondering about though, is should "import math" be done at the class level rather than within the length method? Does it make a difference performance wise? (I know you could've also skipped importing math and just used exponents with 1/2 for the square root , but my question is more about when you do need to import a module, where is the best place to put the import statement).
def __eq__(self,p): return self.x == p.x and self.y == p.y actually this is not going to work imagine that the -len- as a variable which hold a specific distance from (0,0), the collection of dots with this distance are the circumference of a circle with center of (0,0) and -len- as radius so that gonna be a bunch of dots but you will return True only when the points are same example of cases that True was supposed to be returned (3,2) == (-3,2) (3,6) == (6,3) ... although it was a nice tutorial series. Good luck ; )
Im still a newbie and Im starting to code a bot as a practice, is it important to code it as a class structure right away? I dont know yet if its going to be complicated later on. Can you maybe make a tutorial on the best practice to start a project and develop?
overloading methods like: _add__, __sub_, etc. so in this example where are overriding methods? another question is if we can create new operators that do not exist in python with these methods?
it was ok till the point where you defined the length method. It was returning Math.sqrt(self.x**2+self.y**2). But then how did you invoke the length method on p? Can you please elaborate on that?
The last few tutorials I was able to follow along but you lost me here at about 2 minutes in. I've tried rewatching it a couple times but it's just too much of a jump for me. Hopefully at some point I'll be able to understand what is happening here.
I'd say due to a similar behavior to built-in methods such as __init__. As in when you initialize the class it triggers them. If anyone would confirm or clarify, by all means.
@@rishabhroy230 Try to go in depth into built-in methods, overloading and the return keyword. One of them or the combination of them will probably give you insight. Pay attention to how he is using () to invoke the instances of the classes as well. Additionally, he is using print. __str__ can be used to manipulate the string you print when printing your class/instance.
Nope, that would be when you redefine a method in a child class that overrides (hides) the inherited def in a parent. Here we are overloading some standard python operators so that they apply to your home spun objects.
at 10.26 the def __eq__ is wrong... cause if we have p1(2, 1) and p2(1, 2) the lenght is the same but neither p.x and self.x are equal or p.y and self.y
hey there, nice tutorial. Tried overloading __len__, just one issue, got a type error as 'float' object cannot be interpreted as integer, how would one go about fixing it so using len makes it able to output floats
@@olaseni92 it is possible for a single method/function to return 2 values. If you want to, place a comma between the 2 values (e.g. return str(self.x) , str(self.y) ) , however, the return value would be a 2-tuple and not a string. The __str__ method has to yield a str value and thus would not work when calling the object directly (e.g. a=point(2,3); print(a) ). However it could still work when using the method directly (e.g. a=point(2,3); print(a.__str__()) ) Also in my previous reply, I think using: return str(self.x) + ',' + str(self.y) would be more accurate as the comma between the 2 other strings helps to represent the data better. My apologies