Beispiel #1
0
    def __init__(self, spot1_type, spot2_type):
        super().__init__()

        if spot1_type not in ('start', 'end', 'center'):
            raise IncorrectParamValue(f'Incorrect spot1_type {spot1_type}.')
        self._spot1_type = spot1_type

        if spot2_type not in ('start', 'end', 'center'):
            raise IncorrectParamValue(f'Incorrect spot2_type {spot2_type}.')
        self._spot2_type = spot2_type
Beispiel #2
0
    def add_restriction_equations(self, restriction_name: str,
                                  equations: list):
        """
        Add equations for one restriction.

        Parameters
        ----------
        restriction_name: str

        equations: list[sympy.Eq]
            List of equations.

        Raises
        ------
        IncorrectParamValue: if given restriction has already exist.
        """
        if restriction_name in self._restrictions_names:
            raise IncorrectParamValue(
                f'Restriction {restriction_name} has already exist.')

        equations_names = [
            compose_full_name(restriction_name, str(i))
            for i in range(len(equations))
        ]
        new_equations = {
            name: eq
            for name, eq in zip(equations_names, equations)
        }
        self._equations.update(new_equations)
        self._update_graph()
Beispiel #3
0
    def remove_restriction_equations(self, restriction_name: str):
        """
        Remove all equations for given restriction.

        Parameters
        ----------
        restriction_name: str
            Name of restriction.

        Raises
        -------
        IncorrectParamValue: if there is no such restriction.
        """

        if restriction_name not in self._restrictions_names:
            raise IncorrectParamValue(
                f'Restriction {restriction_name} does not exists.')

        equations_to_delete = [
            name for name in self._equations.keys()
            if split_full_name(name)[0] == restriction_name
        ]

        for equation_name in equations_to_delete:
            self._equations.pop(equation_name)
        self._update_graph()
Beispiel #4
0
    def add_figure_symbols(self, figure_name: str, symbols_names: list):
        """
        Add symbols for one figure.
        Cannot add symbols for existing figure.

        Parameters
        ----------
        figure_name: str
            Name of figure.
        symbols_names: list[str]
            Names f symbols for figure.

        Raises
        ------
        IncorrectParamValue: if given figure has already exist.
        """
        if figure_name in self._figures_names:
            raise IncorrectParamValue(
                f'Figure {figure_name} has already exist.')

        symbols_names = [
            compose_full_name(figure_name, sym) for sym in symbols_names
        ]
        new_symbols = {name: Symbol(name) for name in symbols_names}
        self._symbols.update(new_symbols)
        self._update_graph()
Beispiel #5
0
    def get_setter_equations(self, symbols: dict, param: str, value: float):
        """Return equations for setting parameters of point.

        Parameters
        ----------
        symbols: list[sympy.Symbol]
            Symbols for segment.
            Must contain 2 elements: symbols for x, y.
        param: str
            Name of parameter to set value.
            Must be in ['x', 'y'].
        value: int or float
            Value to set.

        Returns
        -------
        equations: list[Eq]
            List of equations.

        Raises
        ------
        IncorrectParamValue: if param is incorrect.
        """
        x, y = symbols['x'], symbols['y']
        if param == 'x':
            return [Eq(x, value)]
        elif param == 'y':
            return [Eq(y, value)]
        else:
            raise IncorrectParamValue(f'Unexpected param {param}')
Beispiel #6
0
    def set_base_param(self, param_name, value):
        """Set parameter of figure.

        Parameters
        ----------
        param_name: str
            Name of parameter to set value.
            Must be in ['x', 'y'].
        value: int or float
            Value too set.

        Returns
        -------
        self

        Raises
        ------
        IncorrectParamValue: if param is incorrect.
        """

        if param_name == 'x':
            self._base = (float(value), self._base[1])
        elif param_name == 'y':
            self._base = (self._base[0], float(value))
        else:
            raise IncorrectParamValue(
                f'Incorrect name of parameter: {param_name}.')

        return self
Beispiel #7
0
    def __init__(self, x, y, spot_type):
        super().__init__()
        self._x = x
        self._y = y

        if spot_type not in ('start', 'end', 'center'):
            raise IncorrectParamValue(f'Incorrect spot_type {spot_type}.')
        self._spot_type = spot_type
Beispiel #8
0
    def change_figure(self, figure_name: str, param: str, value: float):
        """Change one parameter of one figure.

        Parameters
        ----------
        figure_name: str
            Name of figure to change.
        param: str
            Name of parameter to change.
        value: int or float
            New value for parameter.
        """

        if figure_name not in self._figures:
            raise IncorrectParamValue(f'Invalid figure_name {figure_name}')

        figure = self._figures[figure_name]
        if param not in figure.all_parameters:
            raise IncorrectParamValue(
                f'Parameter must be one of {figure.all_parameters}')

        figure_symbols = self._system.get_symbols(figure_name)
        equations = figure.get_setter_equations(figure_symbols, param, value)

        current_values = self._get_values()
        try:
            new_values = self._system.solve_new(equations, current_values)
        except CannotSolveSystemError as e:
            raise e

        try:
            self._set_values(new_values)
        except Exception as e:
            self._rollback()
            raise e
        else:
            self._commit()
Beispiel #9
0
    def get_symbols(self, figure_name: str, symbol_name: str = None):
        """
        Return symbols for one figure.

        Parameters
        ----------
        figure_name: str
            Name of figure.
        symbol_name: str or None, optional, default None
            If string, returns symbol with this name.
            If None, returns dictionary with all symbols of given figure.

        Returns
        -------
            symbols or symbol: dict(str -> sympy.Symbol) or sympy.Symbol

        Raises
        ------
            IncorrectParamValue: if there is no such figure or if symbol name
            is given, but such symbol for such figure does not exist.
        """
        if figure_name not in self._figures_names:
            raise IncorrectParamValue(f'Figure {figure_name} does not exist.')

        if symbol_name is not None:
            symbol_name = compose_full_name(figure_name, symbol_name)
            if symbol_name not in self._symbols:
                raise IncorrectParamValue('No such symbol.')
            return self._symbols[symbol_name]
        else:
            result = dict()
            for name, sym in self._symbols.items():
                base_name, object_name = split_full_name(name)
                if base_name == figure_name:
                    result[object_name] = sym
            return result
Beispiel #10
0
    def get_setter_equations(self, symbols: dict, param: str, value: float):
        """Return equations for setting parameters of segment.

        Parameters
        ----------
        symbols: list[sympy.Symbol]
            Symbols for segment.
            Must contain 4 elements: symbols for x1, y1, x2, y2.
        param: str
            Name of parameter to set value.
            Must be in ['x1', 'y1', 'x2', 'y2', 'length', 'angle'].
        value: int or float
            Value to set.

        Returns
        -------
        equations: list[Eq]
            List of equations.

        Raises
        ------
            IncorrectParamValue: if param is incorrect.
        """
        x1, y1 = symbols['x1'], symbols['y1']
        x2, y2 = symbols['x2'], symbols['y2']
        if param == 'x1':
            return [Eq(x1, value)]
        elif param == 'y1':
            return [Eq(y1, value)]
        elif param == 'x2':
            return [Eq(x2, value)]
        elif param == 'y2':
            return [Eq(y2, value)]
        elif param == 'length':
            return [Eq((x2 - x1)**2 + (y2 - y1)**2, value**2)]
        elif param == 'angle':
            # sign = np.sign(simplify_angle(value) - np.pi)
            return [
                Eq((y2 - y1), (x2 - x1) * np.tan(value)),
                # Eq(sympy_sign(y2 - y1), sign),
            ]
        else:
            raise IncorrectParamValue(f'Unexpected param {param}')
Beispiel #11
0
    def set_param(self, param_name, value):
        """Set parameter of figure.

        Parameters
        ----------
        param_name: str
            Name of parameter to set value.
            Must be in ['x1', 'y1', 'x2', 'y2', 'length', 'angle'].
        value: int or float
            Value too set.

        Returns
        -------
        self

        Raises
        ------
        IncorrectParamValue: if param is incorrect.
        """

        if param_name == 'x1':
            self._base = (float(value), self._base[1])
        elif param_name == 'y1':
            self._base = (self._base[0], float(value))
        elif param_name == 'length':
            self._length = float(value)
        elif param_name == 'angle':
            self._angle = float(value)
        elif param_name in ('x2', 'y2'):
            base_repr = list(self.get_base_representation())
            if param_name == 'x2':
                base_repr[2] = value
            else:
                base_repr[3] = value  # y2
            length = segment_length(*base_repr)
            angle = segment_angle(*base_repr)
            self._length, self._angle = length, angle
        else:
            raise IncorrectParamValue(
                f'Incorrect name of parameter: {param_name}.')

        return self
Beispiel #12
0
    def remove_restriction(self, restriction_name: str):
        """Remove restriction.

        Parameters
        ----------
        restriction_name: str
            Name of restriction to remove.
        """
        if restriction_name not in self._restrictions:
            raise IncorrectParamValue(f'Invalid restriction_name'
                                      f' {restriction_name}')

        try:
            self._restrictions.pop(restriction_name)
            self._system.remove_restriction_equations(restriction_name)

        except:
            self._rollback()
            raise
        else:
            self._commit()
Beispiel #13
0
    def remove_figure(self, figure_name: str):
        """Remove figure.

        Parameters
        ----------
        figure_name: str
            Name of figure to remove.
        """
        if figure_name not in self._figures:
            raise IncorrectParamValue(f'Invalid figure_name {figure_name}')

        try:
            # Remove figure
            self._figures.pop(figure_name)

            # Remove bindings
            self._bindings = create_bindings(self._figures)  # Slow but easy

            # Remove restrictions
            restrictions_to_remove = []
            for name, restriction in self._restrictions.items():
                if figure_name in restriction.get_object_names():
                    restrictions_to_remove.append(name)
            for restriction_name in restrictions_to_remove:
                self._restrictions.pop(restriction_name)

            # Remove from system
            for restriction_name in restrictions_to_remove:
                self._system.remove_restriction_equations(restriction_name)
            self._system.remove_figure_symbols(figure_name)

        except:
            self._rollback()
            raise
        else:
            self._commit()
Beispiel #14
0
    def remove_figure_symbols(self, figure_name: str):
        """
        Remove all symbols for given figure.

        Parameters
        ----------
        figure_name: str
            Name of figure.

        Raises
        -------
        IncorrectParamValue: if there is no figure with such name.
        """
        if figure_name not in self._figures_names:
            raise IncorrectParamValue(f'Figure {figure_name} does not exist.')

        symbols_to_delete = [
            name for name in self._symbols.keys()
            if split_full_name(name)[0] == figure_name
        ]

        for symbol_name in symbols_to_delete:
            self._symbols.pop(symbol_name)
        self._update_graph()
Beispiel #15
0
    def add_restriction(self,
                        restriction: Restriction,
                        figures_names: tuple,
                        name: str = None):
        """Add restriction to system.

        Parameters
        ----------
        restriction: Restriction instance
            Restriction to add. Must be object of correct class with correct
            parameters.
        figures_names: tuple
            Names of figures to apply restriction. If figure is only one,
            must be a tuple of one element.
        name: str or None, optional, default None
            Name of restriction. If None or empty, will be generated
            automatically.
        """
        if not isinstance(restriction, Restriction):
            raise IncorrectParamType

        # Define restriction name
        if name is not None:
            if not self._is_valid_user_name(restriction, name):
                raise IncorrectUserName
        else:
            name = self._generate_name(restriction)
        if self._is_name_exists('restriction', name):
            raise IncorrectName(f'Name {name} is already exists.')

        # Check figures names
        for figure_name in figures_names:
            if figure_name not in self._figures:
                raise IncorrectParamValue(f'Invalid figure_name {figure_name}')

        # Check figures types
        types = restriction.object_types
        if len(figures_names) != len(types):
            raise IncorrectParamValue(f'Must be {len(types)} figures.')
        for figure_name, type_ in zip(figures_names, types):
            if not isinstance(self._figures[figure_name], type_):
                raise IncorrectParamValue(
                    f'Given figures must have types {types}')

        # Add to system
        figures_symbols = [
            self._system.get_symbols(figure_name)
            for figure_name in figures_names
        ]
        equations = restriction.get_equations(*figures_symbols)

        current_values = self._get_values()

        try:
            self._system.add_restriction_equations(name, equations)

            # Try solve
            try:
                new_values = self._system.solve(current_values)
            except CannotSolveSystemError as e:
                # Remove from system
                self._system.remove_restriction_equations(name)
                raise e

            # Add
            restriction.set_object_names(list(figures_names))
            self._restrictions[name] = restriction

            # Update values
            self._set_values(new_values)

        except:
            self._rollback()
            raise
        else:
            self._commit()

        return name