How can we define the __mult__ method to return a Complex object?

Click For Summary

Discussion Overview

The discussion revolves around the implementation of a Python class named Vector, focusing on its initialization, methods for vector manipulation, and subclassing to create a Point class. Participants explore how to define methods for vector addition, movement, and the use of tuples versus lists or numpy arrays for coordinate representation.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested
  • Homework-related

Main Points Raised

  • Some participants inquire about the correct way to initialize a tuple in the Vector class and whether to use tuples or lists for coordinates.
  • One participant proposes a method to calculate the Euclidean norm of the vector using the square root of the sum of squares of its coordinates.
  • Another participant suggests implementing a move method to adjust the vector's coordinates and update the norm, questioning the correct approach to modifying the coordinate at a specific index.
  • There is a proposal to implement the __add__ method for vector addition, with some participants expressing confusion about how to handle addition with both numbers and other Vector objects.
  • Some participants discuss switching from tuples to numpy arrays for mutability, while others suggest using lists instead, raising questions about the implications of these choices.
  • One participant expresses interest in creating a Point class as a subclass of Vector, asking about the necessary methods and initialization required for this subclass.
  • Another participant clarifies that subclassing allows the Point class to inherit methods from the Vector class, emphasizing the need to properly initialize the Point class.

Areas of Agreement / Disagreement

Participants generally agree on the need to implement specific methods for the Vector class, but there are multiple competing views regarding the use of data structures (tuples, lists, numpy arrays) and the implementation details of the methods. The discussion remains unresolved on some technical aspects, particularly regarding the addition and movement methods.

Contextual Notes

Participants express uncertainty about the correct implementation details, such as handling coordinate updates and method definitions. There are also discussions about the implications of using different data structures for storing vector coordinates.

Who May Find This Useful

This discussion may be useful for individuals learning about object-oriented programming in Python, particularly those interested in implementing mathematical concepts through classes and methods.

mathmari
Gold Member
MHB
Messages
4,984
Reaction score
7
Hey! 😊

Construct a class named Vector that expresses the meaning of the vector of numbers. The initialization function, __init__ will take as a argument a tuple corresponding to the vector. This tuple will be stored in the variable named coord. Also, __init__ will calculate the Euclidean measure of the vector and store it in the variable norm2. How do we write the tuple as an argument of the function?

Do we write just :
Code:
class Vector : 
    
    def __init__(self, coord): 
         pass

? Or do we have to the elements there and insert these into the tuple?

:unsure:
 
Technology news on Phys.org
Hi mathmari,

Ok so a tuple is an object type that is stored in round parentheses.

Here's an example of how this would work as a list. Can you make it a tuple?

Code:
class Vector :
    
    def __init__(self, coord):
         self.coord = coordvec = Vector([1,2,3])

print(type(vec.coord))
 
Here's my solution to this:
Code:
from math import sqrt

class Vector:
    def __init__(self, coord):
        self.coord = coord
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector((1, 2, 3))
print(vec.norm2)
 
I wish you a Happy New Year! 🎉

Jameson said:
Here's my solution to this:
Code:
from math import sqrt

class Vector:
    def __init__(self, coord):
        self.coord = coord
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector((1, 2, 3))
print(vec.norm2)

I got it!Next I want to write the method move (self, i, x). This method moves the vector by x in the direction of the i-th coordinate. That is, it simply adds the number x to the i-position of the coordinates and updates this variable with the new value. The variables should be updated at norm2. The method does not returns anything, just shifts the vector.

For that I wrote the following :

Code:
def move(self, i, x) :
        if (i < 0 or i > self.dim) :
            print("Error")
        else :
            self.coord[i] += x
            self.norm2 = sqrt(sum(x**2 for x in self.coord))

I defined as self.dim the dimension of the given vector inside the __init__
I get an error at "self.coord += x". Is that wrong to give the new value to the i-th coordinate of the vector?
Also when it is said to update the norm2, is it meant to write that again inside the method or is something else meant?

:unsure:After that I want to write the method __add __ (self, other). This (magic) method is called when the object is involved in algebraic addition expressions. When the variable other is a number then it is added in the vector coordinates and returns a new object of the Vector class. When the variable other is the object of the Vector class, then it is added by point of two vectors and the new vector is returned.

Example :
v = Vector((5,6,7))
w = Vector((1,2,3))
v+w = (6, 8, 10)
v+3 = (5, 6, 7)

For that I wrote :

Code:
    def __add__(self, other):
        if isinstance(other, Vector):
            return Vector(self.coord + other.coord)
        else :
            return Vector(x + other for x in self.coord)

But that doesn't work. How can we write then to add each component of the first vector with the corresponding component of the second vector?:unsure:
 
Last edited by a moderator:
Let's make one change from using tuples to using numpy arrays. Tuples are immutable, meaning cannot be changed, whereas numpy arrays are mutable.

Code:
from math import sqrt
import numpy as npclass Vector:
    def __init__(self, coord):
        self.coord = np.asarray(coord)
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector([1, 2, 3])

print(vec.norm2)

Now try your move code...
 
Jameson said:
Let's make one change from using tuples to using numpy arrays. Tuples are immutable, meaning cannot be changed, whereas numpy arrays are mutable.

Code:
from math import sqrt
import numpy as npclass Vector:
    def __init__(self, coord):
        self.coord = np.asarray(coord)
        self.norm2 = sqrt(sum(x**2 for x in self.coord))

vec = Vector([1, 2, 3])

print(vec.norm2)

Now try your move code...

Ahh ok! :geek: Since we haven't seen the numpy library yet, do we maybe do the changes of the tuples using lists? I mean to turn the tuple into a list then make the desired changes and then turn the result again into a tuple.

:unsure:
 
Actually a list works the same way it seems. I removed the above numpy reference and this seems to work.

Code:
class Vector:
    def __init__(self, coord):
        self.coord = coord
        self.norm2 = sqrt(sum(x**2 for x in self.coord))
    
    def move(self, i, x):
        if (i < 0):
            print("Error")
        else :
            self.coord[i] += x
            self.norm2 = sqrt(sum(x**2 for x in self.coord))vec = Vector([1, 2, 3])

print(vec.norm2)
vec.move(1, 1)
print(vec.coord)
 
mathmari said:
After that I want to write the method __add __ (self, other). This (magic) method is called when the object is involved in algebraic addition expressions. When the variable other is a number then it is added in the vector coordinates and returns a new object of the Vector class. When the variable other is the object of the Vector class, then it is added by point of two vectors and the new vector is returned.

Example :
v = Vector((5,6,7))
w = Vector((1,2,3))
v+w = (6, 8, 10)
v+3 = (5, 6, 7)

For that I wrote :

Code:
    def __add__(self, other):
        if isinstance(other, Vector):
            return Vector(self.coord + other.coord)
        else :
            return Vector(x + other for x in self.coord)

But that doesn't work. How can we write then to add each component of the first vector with the corresponding component of the second vector?:unsure:

Ok for this part I would try something like this as a hint, if we are using lists to input.

Code:
    def __add__(self, other):
        if len(self.coord) != len(other.coord):
            print("Error")
        else:
            new_coord = []
            for i in range(len(self.coord)):

Loop over each Vector's coordinates and add them to the new list, then make that list part of a new Vector.
 
Last edited:
I see! Now my code works properly! :geek: Now I want to construct a Point class that expresses the meaning of the point in the plane ($\mathbb{R}^2$). We can define it as a subclass of Vector. Point should additionally include the following methods:
- get_angle(self)
- get_polar(self)

So do we just call a Vector instance (x,y) for Point ? Or how do we define that? :unsure:
 
  • #10
You make subclasses in Python like this...
Code:
class Point(Vector):
    def __init__(self, coord):

You still need to initialize all the proper inputs, but if you write a subclass like this then Point should have a move() method based on inheriting from Vector.
 
  • #11
Jameson said:
You make subclasses in Python like this...
Code:
class Point(Vector):
    def __init__(self, coord):

You still need to initialize all the proper inputs, but if you write a subclass like this then Point should have a move() method based on inheriting from Vector.

Ah ok! So when we have saved both .py file in the same directory we can use also the functions that we defined at the class Vector for Point, right? :unsure:

So at this part of the exercise what do we have to define in __init__ ? Do we just write "pass" ? Or do we write "self.coord = coord" ? Or do we have the same __init__ as in the Vector class? And other than __init__ we just define the two methods "get_angle(self)" and "get_polar(self)", or not ? :unsure:
 
  • #12
The key word I saw that led me to use this idea was "subclass". One of the core functions of classes in Python is the ability to inherit from other classes into a subclass. Yes you will need to fill out the __init___ with all the key inputs, but it should auto carry over the methods that you wrote in Vector. So if you do this correctly, Point should have a move() method once you initialize it because it inherits that from Vector.

Try to finish the __init___ method and then test if you have a move method. There are multiple ways to do this but I don't want to make this too complicated. Then I would try to move on to writing get_angle() and get_polar(), yep.
 
  • #13
Jameson said:
The key word I saw that led me to use this idea was "subclass". One of the core functions of classes in Python is the ability to inherit from other classes into a subclass. Yes you will need to fill out the __init___ with all the key inputs, but it should auto carry over the methods that you wrote in Vector. So if you do this correctly, Point should have a move() method once you initialize it because it inherits that from Vector.

Try to finish the __init___ method and then test if you have a move method. There are multiple ways to do this but I don't want to make this too complicated. Then I would try to move on to writing get_angle() and get_polar(), yep.
I wrote that and it works! :giggle:
The angle is calculated as arctan(y/x), right? :unsure:

After that I want to do the following :

Construct a class Complex that expresses the meaning of the point in the complex plane (C). You can define this class as a subclass of Point. The Complex should implement the multiplication (__mul__) as the multiplication of complex numbers. Implement methods to get the real (self.re) and the imaginary (self.im) part of the number.

I have some questions about that.. For the multiplication do we return a tuple in the form [real part, imaginary part] ? I mean $[ac-bd, ad+bc]$ ? Or what should the __mul__ return? :unsure:

To give the real and the imaginary part do we not just give the first and the second coordinate? Or what should we do here exactly? :unsure:
 
  • #14
I'm not really sure why we want to make Complex a subclass of Point, but it seems for both they want to assume that the input space is $\mathbb{R}^2$. I would add a condition in the __init__ method to check for this perhaps, just to be safe.

After that yep you can made the __mult__ method and define it like you suggested. it should return a Complex object. When we add two Complex objects we return a new Complex object, and similarly so if we multiply them.
 

Similar threads

  • · Replies 9 ·
Replies
9
Views
1K
  • · Replies 23 ·
Replies
23
Views
2K
  • · Replies 43 ·
2
Replies
43
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
Replies
5
Views
15K
  • · Replies 15 ·
Replies
15
Views
5K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 3 ·
Replies
3
Views
1K