0

I am trying to automatically update class variables that are in a fix relation. E.g.

class vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
        self.r = (x**2+y**2+z**2)**0.5
        self.theta = tan((x**2+y**2)**0.5/z)
        self.phi = tan(y/x)

If I change the value x of an instance of this class, I want to update the radius and the angles automatically. And if I change an angle or the radius, I want to update the x,y,z components automatically. Is there any way to do this?

Edit: Okay I have the following solution now. Please correct me if there is a mistake or not conventional what I did.

from math import tan, cos, sin

class Vector:
    def __init__(self, x, y, z):
        self._x = x
        self._y = y
        self._z = z
        self._r = (self._x**2+self._y**2+self._z**2)**0.5
        self._theta = tan((self._x**2+self._y**2)**0.5/self._z)
        self._phi = tan(self._y/self._x)

    @property
    def x(self):
        return self._x
    @x.setter
    def x(self, new_x):
        self._x = new_x
        self._r = (self._x**2+self._y**2+self._z**2)**0.5
        self._theta = tan((self._x**2+self._y**2)**0.5/self._z)
        self._phi = tan(self._y/self._x)

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, new_y):
        self._y = new_y
        self._r = (self._x**2+self._y**2+self._z**2)**0.5
        self._theta = tan((self._x**2+self._y**2)**0.5/self._z)
        self._phi = tan(self._y/self._x)

    @property
    def z(self):
        return self._z

    @z.setter
    def z(self, new_z):
        self._z = new_z
        self._r = (self.x**2+self.y**2+self.z**2)**0.5
        self._theta = tan((self._x**2+self._y**2)**0.5/self._z)
        self._phi = tan(self._y/self._x)

    @property
    def r(self):
        return (self._x**2+self._y**2+self._z**2)**0.5

    @r.setter
    def r(self, new_r):
        self._r = new_r
        self._x = self._r*cos(self._theta)*cos(self._phi)
        self._y = self._r*cos(self._theta)*sin(self._phi)
        self._z = self._r*sin(self._theta)

    @property
    def theta(self):
        return tan((self._x**2+self._y**2)**0.5/self._z)

    @theta.setter
    def theta(self, new_theta):
        self._theta = new_theta
        self._x = self._r*cos(self._theta)*cos(self._phi)
        self._y = self._r*cos(self._theta)*sin(self._phi)
        self._z = self._r*sin(self._theta)

    @property
    def phi(self):
        return tan(self._y/self._x)

    @phi.setter
    def phi(self,new_phi):
        self._phi = new_phi
        self._x = self._r*cos(self._theta)*cos(self._phi)
        self._y = self._r*cos(self._theta)*sin(self._phi)
        self._z = self._r*sin(self._theta)

2 Answers 2

2

You are looking for the @property decorator, which sets an object's variable via a function statement.

from math import tan

class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    @property
    def r(self):
        return (self.x**2+self.y**2+self.z**2)**0.5

    @property
    def theta(self):
        return tan((self.x**2+self.y**2)**0.5/self.z)

    @property
    def phi(self):
        return tan(self.y/self.x)

Therefore,

v = Vector(1, 2, 3)
v.phi # -2.185039863261519
Sign up to request clarification or add additional context in comments.

1 Comment

That's what I was looking for, thanks. Is there a way to do the same in the other direction? So changing the angles and radius and obtaining the new x,y,z coordinates? I am new to decorator and haven't found anything usable yet.
1

You could rewrite your class as below

import math

class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    @property
    def radius(self):
        return (self.x**2+self.y**2+self.z**2)**0.5

    @property
    def theta(self):
        return math.tan((self.x**2+self.y**2)**0.5/self.z)

    @property
    def phi(self):
        return math.tan(self.y/self.x)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.