I have created an object with infinite nesting inside Is it bad. Python

I am creating my own object in the project. It is a vector of the state of some physical system.

Performance, despite the strange code, suits me, but if you experiment with it in the console, you can find an infinite nesting of elements

git: https://github.com/dedvassi/CST

Tell me if it’s bad. I didn’t find any problems.

Here is my code:

import numpy as np
from scipy.optimize import minimize

class Q_v_state:
    """
    Этот класс позволяет создавать и модифицировать вектор состояния q (7-вектор)
    """

    class VectorState:
        def __init__(self, outer_instance, init_value, sys, a_oze, b_oze, r_oze_sr):
            self.__outer_instance = outer_instance
            self.__value = init_value
            self.__sys = sys
            self.__a_oze = a_oze
            self.__b_oze = b_oze
            self.__r_oze_sr = r_oze_sr

            self.__grin_for_calculation_h = None
            self.__height_above_ellipsoid = None
            self.__proj_point = None

            self.__depth = 0

        def __str__(self):
            return str(self.__value)

        def __repr__(self):
            if self.__depth > 2:  # Ограничиваем глубину до 2
                return "..."
            self.__depth += 1
            result = f"VectorState(value={self.__value}, height={self.height}, proj_point={self.proj_point})"
            self.__depth -= 1
            return result

        def __call__(self):
            return self.__value

        def __array__(self):
            return self.__value

        def __getitem__(self, item):
            return self.__value[item]

        def __add__(self, other):
            if isinstance(other, self.__class__):
                return self.__class__(self.__value + other.value, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            elif isinstance(other, np.ndarray):
                return self.__class__(self.__value + other, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            else:
                raise TypeError("Unsupported type for additional")

        def __iadd__(self, other):
            if isinstance(other, self.__class__):
                return self.__class__(self.__value + other.value, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            elif isinstance(other, np.ndarray):
                return self.__class__(self.__value + other, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            else:
                raise TypeError("Unsupported type for additional")


        @property
        def in_st(self):
            return self.__outer_instance.q_st_in

        @property
        def in_ekv(self):
            return self.__outer_instance.q_ekv_in

        @property
        def in_gr(self):
            return self.__outer_instance.q_gr

        @property
        def r(self):
            """
            Возвращает текущий вектор скорости.
            """
            return np.array(self.__value[:3])
        @property
        def speed(self):
            return np.array(self.__value[3:6])

        @property
        def value(self):
            return self.__value

        @value.setter
        def value(self, new_value):
            self.__value = new_value
            self.__outer_instance.set_value(self.__value, self.__sys)
            self.__height_above_ellipsoid = None
            self.__proj_point = None

        @property
        def system(self):
            return self.__sys

        def __proj_and_height(self):
            """Вычисляет точку проекции на ОЗЭ и расстояние до нее."""
            def project_point_to_sphere(q):

                r = np.array(q[:3])
                r_norm = np.linalg.norm(r)
                return (self.__r_oze_sr / r_norm) * r

            # Функция для проекции точки на эллипсоид
            def project_point_to_ellipsoid(q):
                x, y, z = q[:3]

                def distance_to_point(p):
                    x_, y_, z_ = p
                    return np.sqrt((x - x_) ** 2 + (y - y_) ** 2 + (z - z_) ** 2)

                def ellipsoid_constraint(p):
                    x_, y_, z_ = p
                    return (x_ ** 2 / self.__a_oze ** 2) + (y_ ** 2 / self.__a_oze ** 2) + (z_ ** 2 / self.__b_oze ** 2) - 1

                def is_inside_ellipsoid(x, y, z):
                    return (x ** 2 / self.__a_oze ** 2) + (y ** 2 / self.__a_oze ** 2) + (z ** 2 / self.__b_oze ** 2) - 1 < 0

                x_initial = project_point_to_sphere(q)  # Начальное приближение по проекции на сферу
                constraint = {'type': 'eq', 'fun': ellipsoid_constraint}
                result = minimize(distance_to_point, x_initial, constraints=[constraint], method='SLSQP')

                if result.success:
                    optimal_point = result.x
                    distance = result.fun  # Вычисляем расстояние между q и найденной точкой на эллипсоиде
                    if is_inside_ellipsoid(x, y, z):
                        distance = -distance  # Отрицательное расстояние, если точка внутри эллипсоида
                    return np.array(optimal_point), np.array(distance)
                else:
                    raise ValueError("Оптимизация не удалась: " + result.message)
            if self.__sys != 3:
                self.__grin_for_calculation_h = self.__outer_instance.q_gr
                self.__proj_point, self.__height_above_ellipsoid = project_point_to_ellipsoid(self.__grin_for_calculation_h)
            else:
                self.__proj_point, self.__height_above_ellipsoid = project_point_to_ellipsoid(self)

        @property
        def proj_point(self):
            if self.__proj_point is None:
                self.__proj_and_height()
            return self.__proj_point
        @property
        def height(self):
            if self.__height_above_ellipsoid is None:
                self.__proj_and_height()
            return self.__height_above_ellipsoid

    def __init__(self, matrix, q_non_sys, system_coord, a_oze=6378136.0, b_oze=6356751.361795686, r_oze_sr=6371110.0):
        """
        Инициализирует вектор состояния q в заданной системе координат.

        Args:
            matrix (Matrix): Экземпляр класса Matrix.
            q_non_sys (np.array): Вектор состояния q.
            system_coord (int): Номер системы координат (1 - стартовая, 2 - экваториальная, 3 - Гринвичская).
            a_oze (float, optional): Параметр a эллипсоида. Defaults to 6378136.0.
            b_oze (float, optional): Параметр b эллипсоида. Defaults to 6356751.361795686.
            r_oze_sr (float, optional): Средний радиус Земли. Defaults to 6371110.0.
        """
        self.__matrix = matrix
        self.__value = q_non_sys
        self.__sys = system_coord
        self.__a_oze = a_oze
        self.__b_oze = b_oze
        self.__r_oze_sr = r_oze_sr

        self.__q_st_in = None
        self.__q_ekv_in = None
        self.__q_gr = None

        self.__r_st_in = None
        self.__r_ekv_in = None
        self.__r_gr = None

        self.__v_st_in = None
        self.__v_ekv_in = None
        self.__v_gr = None

        if self.__sys == 1:
            self.__q_st_in = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze,
                                              self.__r_oze_sr)
            x, y, z = self.__q_st_in[:3]
            vx, vy, vz = self.__q_st_in[3:6]
            self.__r_st_in = np.array([x, y, z])
            self.__v_st_in = np.array([vx, vy, vz])

        elif self.__sys == 2:
            self.__q_ekv_in = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze,
                                               self.__r_oze_sr)
            ksi_1, ksi_2, ksi_3, v_ksi_1, v_ksi_2, v_ksi_3 = self.__q_ekv_in[:6]
            self.__r_ekv_in = np.array([ksi_1, ksi_2, ksi_3])
            self.__v_ekv_in = np.array([v_ksi_1, v_ksi_2, v_ksi_3])

        elif self.__sys == 3:
            self.__q_gr = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            ksi_gr_1, ksi_gr_2, ksi_gr_3, v_ksi_gr_1, v_ksi_gr_2, v_ksi_gr_3 = self.__q_gr[:6]
            self.__r_gr = np.array([ksi_gr_1, ksi_gr_2, ksi_gr_3])
            self.__v_gr = np.array([v_ksi_gr_1, v_ksi_gr_2, v_ksi_gr_3])
        else:
            raise ValueError("Несуществующая СК")

    def __call__(self):
        """
        Возвращает вектор состояния q в его начальной системе координат.
        """
        if self.__sys == 1:
            return self.__q_st_in
        elif self.__sys == 2:
            return self.__q_ekv_in
        elif self.__sys == 3:
            return self.__q_gr
        else:
            raise ValueError("Неверно инициализировано начальный вектор")

    @property
    def value(self):
        """
        Возвращает текущее значение вектора состояния q.
        """
        return self.__value

    @value.setter
    def value(self, new_value):
        """
        Устанавливает новое значение вектора состояния q и пересчитывает его в текущей системе координат.
        Предполагает применение к экземпляру класса Q_v_state
        """
        self.__value = new_value

        self.__q_st_in = None
        self.__q_ekv_in = None
        self.__q_gr = None

        self.__r_st_in = None
        self.__r_ekv_in = None
        self.__r_gr = None

        self.__v_st_in = None
        self.__v_ekv_in = None
        self.__v_gr = None

        if self.__sys == 1:
            self.__q_st_in = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze,
                                              self.__r_oze_sr)
            x, y, z = self.__q_st_in[:3]
            vx, vy, vz = self.__q_st_in[3:6]
            self.__r_st_in = np.array([x, y, z])
            self.__v_st_in = np.array([vx, vy, vz])

        elif self.__sys == 2:
            self.__q_ekv_in = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze,
                                               self.__r_oze_sr)
            ksi_1, ksi_2, ksi_3, v_ksi_1, v_ksi_2, v_ksi_3 = self.__q_ekv_in[:6]
            self.__r_ekv_in = np.array([ksi_1, ksi_2, ksi_3])
            self.__v_ekv_in = np.array([v_ksi_1, v_ksi_2, v_ksi_3])

        elif self.__sys == 3:
            self.__q_gr = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            ksi_gr_1, ksi_gr_2, ksi_gr_3, v_ksi_gr_1, v_ksi_gr_2, v_ksi_gr_3 = self.__q_gr[:6]
            self.__r_gr = np.array([ksi_gr_1, ksi_gr_2, ksi_gr_3])
            self.__v_gr = np.array([v_ksi_gr_1, v_ksi_gr_2, v_ksi_gr_3])
        else:
            raise ValueError("Несуществующая СК")

    def set_value(self, new_value, sys):
        """
        Устанавливает новое значение вектора состояния q и пересчитывает его в указанной системе координат.
        Последняя по задумке передается из экземпляров класса VectorState, или при желании извне!

        Args:
            new_value (np.array): Новое значение вектора состояния q.
            sys (int): Система координат (1 - стартовая, 2 - экваториальная, 3 - Гринвичская).
        """
        self.__value = new_value
        self.__sys = sys
        self.__q_st_in = None
        self.__q_ekv_in = None
        self.__q_gr = None

        self.__r_st_in = None
        self.__r_ekv_in = None
        self.__r_gr = None

        self.__v_st_in = None
        self.__v_ekv_in = None
        self.__v_gr = None
        if self.__sys == 1:
            self.__q_st_in = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze,
                                              self.__r_oze_sr)
            x, y, z = self.__q_st_in[:3]
            vx, vy, vz = self.__q_st_in[3:6]
            self.__r_st_in = np.array([x, y, z])
            self.__v_st_in = np.array([vx, vy, vz])

        elif self.__sys == 2:
            self.__q_ekv_in = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze,
                                               self.__r_oze_sr)
            ksi_1, ksi_2, ksi_3, v_ksi_1, v_ksi_2, v_ksi_3 = self.__q_ekv_in[:6]
            self.__r_ekv_in = np.array([ksi_1, ksi_2, ksi_3])
            self.__v_ekv_in = np.array([v_ksi_1, v_ksi_2, v_ksi_3])

        elif self.__sys == 3:
            self.__q_gr = self.VectorState(self, self.__value, self.__sys, self.__a_oze, self.__b_oze, self.__r_oze_sr)
            ksi_gr_1, ksi_gr_2, ksi_gr_3, v_ksi_gr_1, v_ksi_gr_2, v_ksi_gr_3 = self.__q_gr[:6]
            self.__r_gr = np.array([ksi_gr_1, ksi_gr_2, ksi_gr_3])
            self.__v_gr = np.array([v_ksi_gr_1, v_ksi_gr_2, v_ksi_gr_3])
        else:
            raise ValueError("Несуществующая СК")


    @property
    def q_st_in(self):
        """
        Возвращает вектор состояния q в стартовой инерциальной геоцентрической СК.
        """
        if self.__q_st_in is None:
            if self.__q_ekv_in is None:
                self.__q_ekv_in = self.q_ekv_in

            self.__r_st_in = np.dot(self.__matrix.d, self.__r_ekv_in)
            self.__v_st_in = np.dot(self.__matrix.d, self.__v_ekv_in)
            q = np.concatenate((self.__r_st_in, self.__v_st_in, np.array([self.__q_ekv_in[6]])))
            self.__q_st_in = self.VectorState(self, q, np.float64(1), self.__a_oze, self.__b_oze, self.__r_oze_sr)
        return self.__q_st_in

    @property
    def q_ekv_in(self):
        """
        Возвращает вектор состояния q в экваториальной инерциальной геоцентрической СК.
        """
        if self.__q_ekv_in is None:
            if self.__q_st_in is not None:
                self.__r_ekv_in = np.dot(self.__matrix.d.T, self.__r_st_in)
                self.__v_ekv_in = np.dot(self.__matrix.d.T, self.__v_st_in)
                q = np.concatenate((self.__r_ekv_in, self.__v_ekv_in, np.array([self.__q_st_in[6]])))
                self.__q_ekv_in = self.VectorState(self, q, np.float64(1), self.__a_oze, self.__b_oze, self.__r_oze_sr)

            elif self.__q_gr is not None:
                self.__r_ekv_in = np.dot(self.__matrix.T_G.T, self.__r_gr)
                self.__v_ekv_in = np.dot(self.__matrix.T_G.T, self.__v_gr) + np.cross(self.__matrix.Ω_vector,
                                                                                      self.__r_ekv_in)
                q = np.concatenate((self.__r_ekv_in, self.__v_ekv_in, np.array([self.__q_gr[6]])))
                self.__q_ekv_in = self.VectorState(self, q, np.float64(1), self.__a_oze, self.__b_oze, self.__r_oze_sr)
            else:
                raise ValueError("Неудалось преобразовать вектор в Экваториальную геоцентрическую инерциальную систему.n"
                                 "Исключение в свойстве 'q_ekv_in' - не найдены иные формы вектора")

        return self.__q_ekv_in

    @property
    def q_gr(self):
        """
        Возвращает вектор состояния q в Гринвичской СК.
        """
        if self.__q_gr is None:
            if self.__q_ekv_in is None:
                self.__q_ekv_in = self.q_ekv_in

            self.__r_gr = np.dot(self.__matrix.T_G, self.__r_ekv_in)
            self.__v_gr = np.dot(self.__matrix.T_G, self.__v_ekv_in) - np.cross(self.__matrix.Ω_vector, self.__r_gr)
            q = np.concatenate((self.__r_gr, self.__v_gr, np.array([self.__q_ekv_in[6]])))
            self.__q_gr = self.VectorState(self, q, np.float64(3), self.__a_oze, self.__b_oze, self.__r_oze_sr)
        return self.__q_gr

    @property
    def r(self):
        """
        Возвращает текущий радиус-вектор.
        """
        if self.__sys == 1:
            return self.__r_st_in
        if self.__sys == 2:
            return self.__r_ekv_in
        if self.__sys == 3:
            return self.__r_gr

    @property
    def speed(self):
        """
        Возвращает текущий вектор скорости.
        """
        if self.__sys == 1:
            return self.__v_st_in
        if self.__sys == 2:
            return self.__v_ekv_in
        if self.__sys == 3:
            return self.__v_gr

    @property
    def system(self):
        """
        Возвращает текущую СК.
        """
        return self.__sys

That’s what I mean.

the initialization that I use for debugging:

matrix = Matrix(np.array([2.1489035e+05, 6.4652197e+06, 4.9219371e+04, 3.5701399e+03, 8.0158688e+02, 1.5086193e+02, 1.9668010e+02]), np.array([7.292115e-05, 1.966801e+02]))


q_non_sys = np.array([2.1489035e+05, 6.4652197e+06, 4.9219371e+04, 3.5701399e+03, 8.0158688e+02,
 1.5086193e+02, 1.9668010e+02])
sys = 1
q = Q_v_state(matrix, q_non_sys, sys)()

matrix is an instance of a class with matrices

import numpy as np


class Matrix:
    """Инициализирует матрицы перехода между системами

        - Матрица d инициализируется единоразово и не изменяется в рамках сессии. Для ее получения использовать:

            >>d = self.d (пример с присвоением значения переменной d)

        - Матрица T_G динамична. Для обновления и получения ее нового значения следует использовать:

            >>self.data_T_G = new_value*
            >>T_G = self.T_G (пример с присвоением значения переменной T_G)

        *new_value - массив numpy (np.ndarray), содержит угловую скорость вращения Земли и время в соответствующем порядке

    """

    def __init__(self, dt_1, dt_2):
        self.__data_d = dt_1
        self.__d = None

        self.__data_T_G = dt_2
        self.__T_G = None

        self.Ω_vector = np.array([0, 0, dt_2[0]])

    @property
    def d(self):
        if self.__d is None:
            Φ, λ, _, P = self.__data_d[:4] * np.pi / 180
            d11 = (-1) * np.cos(P) * np.sin(Φ) * np.cos(λ) - np.sin(P) * np.sin(λ)
            d12 = (-1) * np.cos(P) * np.sin(Φ) * np.sin(λ) + np.sin(P) * np.cos(λ)
            d13 = np.cos(P) * np.cos(Φ)

            d21 = np.cos(Φ) * np.cos(λ)
            d22 = np.cos(Φ) * np.sin(λ)
            d23 = np.sin(Φ)

            d31 = np.sin(P) * np.sin(Φ) * np.cos(λ) - np.cos(P) * np.sin(λ)
            d32 = np.sin(P) * np.sin(Φ) * np.sin(λ) + np.cos(P) * np.cos(λ)
            d33 = (-1) * np.sin(P) * np.cos(Φ)

            self.__d = np.array([[d11, d12, d13],
                                 [d21, d22, d23],
                                 [d31, d32, d33]])

        return self.__d

    @property
    def data_T_G(self):
        return self.__data_T_G

    @data_T_G.setter
    def data_T_G(self, value):
        self.__data_T_G = value
        self.__T_G = None

    @property
    def T_G(self):
        if self.__T_G is None:
            Ω = self.data_T_G[0]
            t = self.data_T_G[1]  # извлекает время
            self.__T_G = np.array([
                [np.cos(Ω * t), np.sin(Ω * t), 0],
                [-np.sin(Ω * t), np.cos(Ω * t), 0],
                [0, 0, 1]
            ])
        return self.__T_G

New contributor

Vassi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật