Python : Class - Vector

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...In summary, the Vector class stores a tuple of the coordinates of the vector. The initialization function, __init__, takes a tuple as an argument. This tuple will be stored in the variable named coordf
  • #1

mathmari

Gold Member
MHB
5,050
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:
 
  • #2
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 = coord


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

print(type(vec.coord))
 
  • #3
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)
 
  • #4
I wish you a Happy New Year! 🎉

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:
  • #5
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 np


class 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...
 
  • #6
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 np


class 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:
 
  • #7
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)
 
  • #8
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:
  • #9
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
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
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.
 

Suggested for: Python : Class - Vector

Replies
9
Views
712
Replies
2
Views
142
Replies
1
Views
904
Replies
10
Views
1K
Replies
3
Views
581
Replies
2
Views
492
Replies
6
Views
682
Replies
24
Views
1K
Replies
2
Views
657
Replies
1
Views
626
Back
Top