Instruction:
How would you explain what the following Python 3 function does
def resize_state_meta(state_m, factor, gaphas_editor=True):
    # print("START RESIZE OF STATE", state_m.get_meta_data_editor(for_gaphas=gaphas_editor), state_m)
    old_rel_pos = state_m.get_meta_data_editor(for_gaphas=gaphas_editor)['rel_pos']
    # print("old_rel_pos state", old_rel_pos, state_m.core_element)
    state_m.set_meta_data_editor('rel_pos', mult_two_vectors(factor, old_rel_pos), from_gaphas=gaphas_editor)
    # print("new_rel_pos state", state_m.get_meta_data_editor(for_gaphas=gaphas_editor), state_m.core_element)

    # print("resize factor", factor,  state_m, state_m.meta)
    old_size = state_m.get_meta_data_editor(for_gaphas=gaphas_editor)['size']
    # print("old_size", old_size, type(old_size))
    state_m.set_meta_data_editor('size', mult_two_vectors(factor, old_size), from_gaphas=gaphas_editor)
    # print("new_size", state_m.get_meta_data_editor(for_gaphas=gaphas_editor)['size'])
    if gaphas_editor:
        old_rel_pos = state_m.get_meta_data_editor(for_gaphas=gaphas_editor)['name']['rel_pos']
        state_m.set_meta_data_editor('name.rel_pos', mult_two_vectors(factor, old_rel_pos), from_gaphas=gaphas_editor)
        old_size = state_m.get_meta_data_editor(for_gaphas=gaphas_editor)['name']['size']
        state_m.set_meta_data_editor('name.size', mult_two_vectors(factor, old_size), from_gaphas=gaphas_editor)

    if isinstance(state_m, LibraryStateModel):
        # print("LIBRARY", state_m)
        if gaphas_editor and state_m.state_copy_initialized:
            if state_m.meta_data_was_scaled:
                resize_state_port_meta(state_m, factor, gaphas_editor)
            else:
                scale_library_ports_meta_data(state_m, gaphas_editor)

        if state_m.state_copy_initialized:
            resize_state_meta(state_m.state_copy, factor, gaphas_editor)
        # print("END LIBRARY RESIZE")
    else:
        # print("resize_state_meta -> resize_state_port_meta")
        resize_state_port_meta(state_m, factor, gaphas_editor)
        if isinstance(state_m, ContainerStateModel):
            _resize_connection_models_list(state_m.transitions[:] + state_m.data_flows[:], factor, gaphas_editor)
            for child_state_m in state_m.states.values():
                resize_state_meta(child_state_m, factor, gaphas_editor)

Response: Resize state meta data recursively what includes also LibraryStateModels meta data and its internal state_copy


Instruction:
Can you tell what is the following Python 3 function doing
def offset_rel_pos_of_models_meta_data_according_parent_state(models_dict):
    old_parent_rel_pos = models_dict['state'].get_meta_data_editor()['rel_pos']
    offset_rel_pos_of_all_models_in_dict(models_dict, pos_offset=old_parent_rel_pos)

    return True

Response: Offset meta data of state elements according the area used indicated by the state meta data.


Instruction:
Can you generate the documentation for the following Python 3 function
def scale_meta_data_according_states(models_dict):
    left, right, top, bottom = get_boundaries_of_elements_in_dict(models_dict=models_dict)

    parent_size = models_dict['state'].parent.get_meta_data_editor()['size']
    _, rel_pos, size = cal_frame_according_boundaries(left, right, top, bottom, parent_size)

    # Set size and position of new container state
    models_dict['state'].set_meta_data_editor('rel_pos', rel_pos)
    models_dict['state'].set_meta_data_editor('size', size)
    offset = mult_two_vectors((-1., -1.), rel_pos)
    offset_rel_pos_of_all_models_in_dict(models_dict, offset)

    return True

Response: Scale meta data according states of group states.


Instruction:
How would you implement a function in Python 3 that
scales meta - data according to state.

Response:
def scale_meta_data_according_state(models_dict, rel_pos=None, as_template=False, fill_up=False):
    # TODO Documentation needed....
    """ Scale elements in dict to fit into dict state key element.

    If elements are already small enough no resize is performed.
    """
    # TODO check about positions of input-data- and output-data- or scoped variable-ports is needed
    # TODO adjustments of data ports positions are not sufficient -> origin state size is maybe needed for that
    # TODO consistency check on boundary and scale parameter for every if else case

    if 'states' in models_dict or 'scoped_variables' in models_dict:
        left, right, top, bottom = get_boundaries_of_elements_in_dict(models_dict=models_dict)
        parent_size = models_dict['state'].get_meta_data_editor()['size']
        margin, old_rel_pos, size = cal_frame_according_boundaries(left, right, top, bottom, parent_size, group=False)
        automatic_mode = True if rel_pos is None else False
        clearance = 0.2 if rel_pos is None else 0.
        rel_pos = (margin, margin) if rel_pos is None else rel_pos
        # rel_pos = (0., 0.) if fill_up else rel_pos
        clearance_scale = 1 + clearance

        assert parent_size[0] > rel_pos[0]
        assert parent_size[1] > rel_pos[1]
        # print("edges:", left, right, top, bottom)
        # print("margin:", margin, "rel_pos:", rel_pos, "old_rel_pos", old_rel_pos, "size:", size)

        parent_width, parent_height = parent_size

        boundary_width, boundary_height = size
        # print("parent width:   {0}, parent_height:   {1}".format(parent_width, parent_height))
        # print("boundary width: {0}, boundary_height: {1}".format(boundary_width, boundary_height))

        # no site scale
        if parent_width - rel_pos[0] > boundary_width * clearance_scale and \
                parent_height - rel_pos[1] > boundary_height * clearance_scale and not fill_up:
            if automatic_mode:
                resize_factor = 1.
                boundary_width_in_parent = boundary_width*resize_factor
                # print(boundary_width, resize_factor, boundary_width*resize_factor, boundary_height*resize_factor + margin*2, parent_height)
                # print("left over width: ", parent_width - boundary_width_in_parent - rel_pos[0] - margin)
                width_pos_offset_to_middle = (parent_width - boundary_width_in_parent - rel_pos[0] - margin)/2.
                rel_pos = add_pos(rel_pos, (width_pos_offset_to_middle, 0.))
                boundary_height_in_parent = boundary_height*resize_factor
                # print("left over height: ", parent_height - boundary_height_in_parent - rel_pos[0] - margin)
                height_pos_offset_to_middle = (parent_height - boundary_height_in_parent - rel_pos[1] - margin)/2.
                rel_pos = add_pos(rel_pos, (0., height_pos_offset_to_middle))
            offset = subtract_pos((0., 0.), subtract_pos(old_rel_pos, rel_pos))
            offset_rel_pos_of_all_models_in_dict(models_dict, offset)
            return 1, 1  # (1, 1), offset, rel_pos
        # smallest site scale
        else:
            # increase of boundary or clearance results into bigger estimated size and finally stronger
            # reduction of original element sizes
            left, right, top, bottom = get_boundaries_of_elements_in_dict(models_dict=models_dict, clearance=clearance)
            parent_size = models_dict['state'].get_meta_data_editor()['size']
            margin, old_rel_pos, size = cal_frame_according_boundaries(left, right, top, bottom, parent_size, group=False)

            rel_pos = (margin, margin) if rel_pos is None else rel_pos
            assert parent_size[0] > rel_pos[0]
            assert parent_size[1] > rel_pos[1]
            # print("edges:", left, right, top, bottom)
            # print("margin:", margin, "rel_pos:", rel_pos, "old_rel_pos", old_rel_pos, "size:", size)

            parent_width, parent_height = parent_size

            boundary_width, boundary_height = size
            if (parent_height - rel_pos[1] - margin)/boundary_height < \
                    (parent_width - rel_pos[0] - margin)/boundary_width:
                # print("#2"*20, 1, "#"*20, rel_pos)
                resize_factor = (parent_height - rel_pos[1] - margin)/boundary_height
                boundary_width_in_parent = boundary_width*resize_factor
                # print(boundary_width, resize_factor, boundary_width*resize_factor)
                # print("left over width: ", parent_width - boundary_width_in_parent - rel_pos[0] - margin)
                width_pos_offset_to_middle = (parent_width - boundary_width_in_parent - rel_pos[0] - margin)/2.
                rel_pos = add_pos(rel_pos, (width_pos_offset_to_middle, 0.))
                # print(resize_factor, rel_pos)
            else:
                # print("#2"*20, 2, "#"*20, rel_pos)
                resize_factor = (parent_width - rel_pos[0] - margin)/boundary_width
                boundary_height_in_parent = boundary_height*resize_factor
                # print(boundary_width, resize_factor, boundary_width*resize_factor)
                # print("left over height: ", parent_height - boundary_height_in_parent - rel_pos[0] - margin)
                height_pos_offset_to_middle = (parent_height - boundary_height_in_parent - rel_pos[1] - margin)/2.
                rel_pos = add_pos(rel_pos, (0., height_pos_offset_to_middle))
                # print(resize_factor, rel_pos)
            frame = {'rel_pos': rel_pos, 'size': mult_two_vectors((resize_factor, resize_factor), size)}
            # print(models_dict['state'].get_meta_data_editor()['rel_pos'], \)
            #     parent_size, models_dict['state'].parent.get_meta_data_editor()['size']
            # print("frame", frame, resize_factor)
            # # rel_pos = mult_two_vectors((1, -1), frame['rel_pos'])
            offset = subtract_pos((0., 0.), old_rel_pos)
            offset_rel_pos_of_all_models_in_dict(models_dict, offset)

            resize_of_all_models_in_dict(models_dict, (resize_factor, resize_factor))

            offset_rel_pos_of_all_models_in_dict(models_dict, frame['rel_pos'])
            # scale_meta_data_according_frame(models_dict, frame)
            return resize_factor, resize_factor  # (resize_factor, resize_factor) , offset, frame['rel_pos']
    else:
        return 1, 1


Instruction:
Explain what the following Python 3 code does
def get_closest_sibling_state(state_m, from_logical_port=None):
    if not state_m.parent:
        logger.warning("A state can not have a closest sibling state if it has not parent as {0}".format(state_m))
        return

    margin = cal_margin(state_m.parent.get_meta_data_editor()['size'])
    pos = state_m.get_meta_data_editor()['rel_pos']
    size = state_m.get_meta_data_editor()['size']  # otherwise measure from reference state itself
    if from_logical_port in ["outcome", "income"]:
        size = (margin, margin)
    if from_logical_port == "outcome":
        outcomes_m = [outcome_m for outcome_m in state_m.outcomes if outcome_m.outcome.outcome_id >= 0]
        free_outcomes_m = [oc_m for oc_m in outcomes_m
                           if not state_m.state.parent.get_transition_for_outcome(state_m.state, oc_m.outcome)]
        if free_outcomes_m:
            outcome_m = free_outcomes_m[0]
        else:
            outcome_m = outcomes_m[0]
        pos = add_pos(pos, outcome_m.get_meta_data_editor()['rel_pos'])
    elif from_logical_port == "income":
        pos = add_pos(pos, state_m.income.get_meta_data_editor()['rel_pos'])

    min_distance = None
    for sibling_state_m in state_m.parent.states.values():
        if sibling_state_m is state_m:
            continue

        sibling_pos = sibling_state_m.get_meta_data_editor()['rel_pos']
        sibling_size = sibling_state_m.get_meta_data_editor()['size']

        distance = geometry.cal_dist_between_2_coord_frame_aligned_boxes(pos, size, sibling_pos, sibling_size)

        if not min_distance or min_distance[0] > distance:
            min_distance = (distance, sibling_state_m)

    return min_distance

Response: Calculate the closest sibling state from optional logical port of handed state model


Instruction:
Write a Python 3 function that can
collect non empty list dict to create arguments for action signal and msg and logger messages

Response:
def get_action_arguments(self, target_state_m):
        """ Collect argument attributes for action signal

        Use non empty list dict to create arguments for action signal msg and logger messages. The action parent model
        can be different then the target state model because logical and data port changes also may influence the
        linkage, see action-module (undo/redo).

        :param rafcon.gui.models.abstract_state.AbstractStateModel target_state_m: State model of target of action
        :return: dict with lists of elements part of the action, action parent model
        """
        non_empty_lists_dict = {key: elems for key, elems in self.model_copies.items() if elems}
        port_attrs = ['input_data_ports', 'output_data_ports', 'scoped_variables', 'outcomes']
        port_is_pasted = any([key in non_empty_lists_dict for key in port_attrs])
        return non_empty_lists_dict, target_state_m.parent if target_state_m.parent and port_is_pasted else target_state_m


Instruction:
Create a Python 3 function to
copy all selected items to the clipboard using smart selection adaptation by default

Response:
def copy(self, selection, smart_selection_adaption=True):
        """ Copy all selected items to the clipboard using smart selection adaptation by default

        :param selection: the current selection
        :param bool smart_selection_adaption: flag to enable smart selection adaptation mode
        :return:
        """
        assert isinstance(selection, Selection)
        self.__create_core_and_model_object_copies(selection, smart_selection_adaption)


Instruction:
Here you have a function in Python 3, explain what it does
def cut(self, selection, smart_selection_adaption=False):

        assert isinstance(selection, Selection)

        import rafcon.gui.helpers.state_machine as gui_helper_state_machine
        if gui_helper_state_machine.is_selection_inside_of_library_state(selected_elements=selection.get_all()):
            logger.warning("Cut is not performed because elements inside of a library state are selected.")
            return
        selection_dict_of_copied_models, parent_m = self.__create_core_and_model_object_copies(
            selection, smart_selection_adaption)

        non_empty_lists_dict, action_parent_m = self.get_action_arguments(parent_m if parent_m else None)

        action_parent_m.action_signal.emit(ActionSignalMsg(action='cut', origin='clipboard',
                                                           action_parent_m=action_parent_m,
                                                           affected_models=[], after=False,
                                                           kwargs={'remove': non_empty_lists_dict}))

        for models in selection_dict_of_copied_models.values():
            gui_helper_state_machine.delete_core_elements_of_models(models, destroy=True,
                                                                    recursive=True, force=False)
        affected_models = [model for models in non_empty_lists_dict.values() for model in models]
        action_parent_m.action_signal.emit(ActionSignalMsg(action='cut', origin='clipboard',
                                                           action_parent_m=action_parent_m,
                                                           affected_models=affected_models, after=True))

Response: Cuts all selected items and copy them to the clipboard using smart selection adaptation by default


Instruction:
How would you explain what the following Python 3 function does
def paste(self, target_state_m, cursor_position=None, limited=None, convert=False):
        self.reset_clipboard_mapping_dicts()
        if not isinstance(target_state_m, StateModel):
            logger.warning("Paste is not performed because target state indication has to be a StateModel not {0}"
                        "".format(target_state_m.__class__.__name__))
            return
        if target_state_m.state.get_next_upper_library_root_state() is not None:
            logger.warning("Paste is not performed because selected target state is inside of a library state.")
            return

        element_m_copy_lists = self.model_copies
        self.prepare_new_copy()  # threaded in future -> important that the copy is prepared here!!!
        # use non empty list dict to create arguments for action signal msg and logger messages
        dict_of_non_empty_lists_of_model_copies, action_parent_m = self.get_action_arguments(target_state_m)
        action_parent_m.action_signal.emit(ActionSignalMsg(action='paste', origin='clipboard',
                                                           action_parent_m=action_parent_m,
                                                           affected_models=[], after=False,
                                                           kwargs={'insert': dict_of_non_empty_lists_of_model_copies,
                                                                   'convert': convert,
                                                                   'limited': limited}))
        self.state_id_mapping_dict[self.copy_parent_state_id] = target_state_m.state.state_id

        # prepare list of lists to copy for limited or converted paste of objects
        target_state_element_attrs = target_state_m.state.state_element_attrs
        if limited and all([state_element_attr in target_state_element_attrs for state_element_attr in limited]):
            if len(limited) == 1 and limited[0] in ['input_data_ports', 'output_data_ports', 'scoped_variables'] and convert:
                combined_list = element_m_copy_lists['input_data_ports'] + element_m_copy_lists['output_data_ports'] + \
                                element_m_copy_lists['scoped_variables']
                for state_element_attr in ['input_data_ports', 'output_data_ports', 'scoped_variables']:
                    element_m_copy_lists[state_element_attr] = combined_list
            state_element_attrs_to_insert = limited
        else:
            state_element_attrs_to_insert = target_state_element_attrs

        # check list order and put transitions and data flows to the end
        for state_element_attr in ['transitions', 'data_flows']:
            if state_element_attr in state_element_attrs_to_insert:
                state_element_attrs_to_insert.remove(state_element_attr)
                state_element_attrs_to_insert.append(state_element_attr)

        def insert_elements_from_model_copies_list(model_list, state_element_name):
            """ Insert/add all core elements of model_list into the target_state_m

            The function returns a list of pairs of models (new and original models) because the target_state_m for
            some insert operations still generates a new model.
            :param list model_list: list of models
            :param str state_element_name: appendix string to "_insert_*" to get the attribute of respective methods in
                                           clipboard-class.
            :return: list of pairs of models (new and original models)
            :rtype: list[tuple]
            """
            new_and_copied_models = []
            for orig_element_m_copy in model_list:
                try:
                    # hold orig_element_m_copy related to newly generated model for debugging reasons
                    # (its doubt that ids are fully correct, meta data is considered to be alright now)
                    insert_function = getattr(self, '_insert_{0}'.format(state_element_name))  # e.g. self._insert_state
                    new_element_m = insert_function(target_state_m, orig_element_m_copy)
                    new_and_copied_models.append((new_element_m, orig_element_m_copy))
                except (ValueError, AttributeError, TypeError) as e:
                    logger.warning("While inserting a {0} a failure was detected, exception: {1}."
                                   "".format(state_element_name, e))
            return new_and_copied_models

        # insert all lists and their elements into target state
        # insert_dict hold lists of pairs of models -> new (maybe generated by parent model) and original copy
        insert_dict = dict()
        for state_element_attr in state_element_attrs_to_insert:
            state_element_name = state_element_attr[:-1]  # e.g. "states" => "state", "outcomes" => "outcome"
            insert_dict[state_element_attr] = \
                insert_elements_from_model_copies_list(element_m_copy_lists[state_element_attr],
                                                       state_element_name)

        # move meta data from original copied model to newly insert models and resize them to fit into target_state_m
        models_dict = {'state': target_state_m}
        for state_element_attr, state_elements in insert_dict.items():
            models_dict[state_element_attr] = {}
            for new_state_element_m, copied_state_element_m in state_elements:
                new_core_element_id = new_state_element_m.core_element.core_element_id
                models_dict[state_element_attr][new_core_element_id] = new_state_element_m

        affected_models = []
        for key, state_elements in insert_dict.items():
            if key == 'state':
                continue
            for new_state_element_m, copied_state_element_m in state_elements:
                affected_models.append(new_state_element_m)

        # commented parts are here for later use to detect empty meta data fields and debug those
        if all([all([not gui_helpers_meta_data.model_has_empty_meta(state_element_m) for state_element_m, _ in elems_list])
                if isinstance(elems_list, list) else gui_helpers_meta_data.model_has_empty_meta(elems_list)
                for elems_list in insert_dict.values()]) or \
                len(dict_of_non_empty_lists_of_model_copies) == 1 and 'states' in dict_of_non_empty_lists_of_model_copies:
            try:
                gui_helpers_meta_data.scale_meta_data_according_state(models_dict)
            except:
                logger.exception("Scale of pasted content {0} cause a problems.".format(models_dict))
        else:
            # TODO this should become a warning in the future or the meta module has to handle the empty data fields
            logger.info("Paste miss meta to scale. {0}".format(affected_models))

        if not affected_models:
            logger.warning("Paste with no effect. No elements pasted from {0}".format(dict_of_non_empty_lists_of_model_copies))
        action_parent_m.action_signal.emit(ActionSignalMsg(action='paste', origin='clipboard',
                                                           action_parent_m=action_parent_m,
                                                           affected_models=affected_models, after=True))
        return insert_dict

Response: Paste objects to target state.


Instruction:
Can you create a Python 3 function that
resets the clipboard so that old elements do not pollute the new selection that is copied into the the clipboard.

Response:
def reset_clipboard(self):
        """ Resets the clipboard, so that old elements do not pollute the new selection that is copied into the
            clipboard.

        :return:
        """
        # reset selections
        for state_element_attr in ContainerState.state_element_attrs:
            self.model_copies[state_element_attr] = []

        # reset parent state_id the copied elements are taken from
        self.copy_parent_state_id = None

        self.reset_clipboard_mapping_dicts()


Instruction:
Write a Python 3 script for
finding and reduce selection to one parent state.

Response:
def do_selection_reduction_to_one_parent(selection):
        """ Find and reduce selection to one parent state.

        :param selection:
        :return: state model which is parent of selection or None if root state
        """

        all_models_selected = selection.get_all()
        # check if all elements selected are on one hierarchy level -> TODO or in future are parts of sibling?!
        # if not take the state with the most siblings as the copy root
        parent_m_count_dict = {}
        for model in all_models_selected:
            parent_m_count_dict[model.parent] = parent_m_count_dict[model.parent] + 1 if model.parent in parent_m_count_dict else 1
        parent_m = None
        current_count_parent = 0
        for possible_parent_m, count in parent_m_count_dict.items():
            parent_m = possible_parent_m if current_count_parent < count else parent_m
        # if root no parent exist and only on model can be selected
        if len(selection.states) == 1 and selection.get_selected_state().state.is_root_state:
            parent_m = None
            # kick all selection except root_state
            if len(all_models_selected) > 1:
                selection.set(selection.get_selected_state())
        if parent_m is not None:
            # check and reduce selection
            for model in all_models_selected:
                if model.parent is not parent_m:
                    selection.remove(model)

        return parent_m


Instruction:
Implement a Python 3 function for
reducing and extend transition and data flow element selection if already enclosed by selection The smart selection adaptation checks and ignores directly data flows and transitions which are selected without selected related origin or targets elements. Additional the linkage (data flows and transitions) if those origins and targets are covered by the selected elements is added to the selection. Thereby the selection it self is manipulated to provide direct feedback to the user. :param selection: :param parent_m: :return:

Response:
def do_smart_selection_adaption(selection, parent_m):
        """ Reduce and extend transition and data flow element selection if already enclosed by selection

         The smart selection adaptation checks and ignores directly data flows and transitions which are selected
         without selected related origin or targets elements. Additional the linkage (data flows and transitions)
         if those origins and targets are covered by the selected elements is added to the selection.
         Thereby the selection it self is manipulated to provide direct feedback to the user.

        :param selection:
        :param parent_m:
        :return:
        """

        def get_ports_related_to_data_flow(data_flow):
            from_port = data_flow.parent.get_data_port(data_flow.from_state, data_flow.from_key)
            to_port = data_flow.parent.get_data_port(data_flow.to_state, data_flow.to_key)
            return from_port, to_port

        def get_states_related_to_transition(transition):
            if transition.from_state == transition.parent.state_id or transition.from_state is None:
                from_state = transition.parent
            else:
                from_state = transition.parent.states[transition.from_state]
            if transition.to_state == transition.parent.state_id:
                to_state = transition.parent
            else:
                to_state = transition.parent.states[transition.to_state]
            if transition.to_outcome in transition.parent.outcomes:
                to_outcome = transition.parent.outcomes[transition.to_outcome]
            else:
                to_outcome = transition.to_outcome
            return from_state, to_state, to_outcome

        # reduce linkage selection by not fully by selection covered linkage
        possible_states = [state_m.state for state_m in selection.states]
        possible_outcomes = [outcome_m.outcome for outcome_m in selection.outcomes]
        for data_flow_m in selection.data_flows:
            from_port, to_port = get_ports_related_to_data_flow(data_flow_m.data_flow)
            if from_port.parent not in possible_states or to_port not in possible_states:
                selection.remove(data_flow_m)
        for transition_m in selection.transitions:
            from_state, to_state, to_oc = get_states_related_to_transition(transition_m.transition)
            if from_state not in possible_states or (to_state not in possible_states and to_oc not in possible_outcomes):
                selection.remove(transition_m)

        # extend linkage selection by fully by selected element enclosed linkage
        if parent_m and isinstance(parent_m.state, ContainerState):
            state_ids = [state.state_id for state in possible_states]
            port_ids = [sv_m.scoped_variable.data_port_id for sv_m in selection.scoped_variables] + \
                [ip_m.data_port.data_port_id for ip_m in selection.input_data_ports] + \
                [op_m.data_port.data_port_id for op_m in selection.output_data_ports]
            ports = [sv_m.scoped_variable for sv_m in selection.scoped_variables] + \
                [ip_m.data_port for ip_m in selection.input_data_ports] + \
                [op_m.data_port for op_m in selection.output_data_ports]
            related_transitions, related_data_flows = \
                parent_m.state.related_linkage_states_and_scoped_variables(state_ids, port_ids)
            # extend by selected states or a port and a state enclosed data flows
            for data_flow in related_data_flows['enclosed']:
                data_flow_m = parent_m.get_data_flow_m(data_flow.data_flow_id)
                if data_flow_m not in selection.data_flows:
                    selection.add(data_flow_m)
            # extend by selected ports enclosed data flows
            for data_flow_id, data_flow in parent_m.state.data_flows.items():
                from_port, to_port = get_ports_related_to_data_flow(data_flow)
                if from_port in ports and to_port in ports:
                    selection.add(parent_m.get_data_flow_m(data_flow_id))
            # extend by selected states enclosed transitions
            for transition in related_transitions['enclosed']:
                transition_m = parent_m.get_transition_m(transition.transition_id)
                if transition_m not in selection.transitions:
                    selection.add(transition_m)
            # extend by selected state and outcome enclosed transitions
            for transition_id, transition in parent_m.state.transitions.items():
                from_state, to_state, to_oc = get_states_related_to_transition(transition)
                if from_state in possible_states and to_oc in possible_outcomes:
                    selection.add(parent_m.get_transition_m(transition_id))


Instruction:
Make a summary of the following Python 3 code
def __create_core_and_model_object_copies(self, selection, smart_selection_adaption):

        all_models_selected = selection.get_all()
        if not all_models_selected:
            logger.warning("Nothing to copy because state machine selection is empty.")
            return

        parent_m = self.do_selection_reduction_to_one_parent(selection)
        self.copy_parent_state_id = parent_m.state.state_id if parent_m else None

        if smart_selection_adaption:
            self.do_smart_selection_adaption(selection, parent_m)

        # store all lists of selection
        selected_models_dict = {}
        for state_element_attr in ContainerState.state_element_attrs:
            selected_models_dict[state_element_attr] = list(getattr(selection, state_element_attr))

        # delete old models
        self.destroy_all_models_in_dict(self.model_copies)
        # copy all selected elements
        self.model_copies = deepcopy(selected_models_dict)

        new_content_of_clipboard = ', '.join(["{0} {1}".format(len(elems), key if len(elems) > 1 else key[:-1])
                                             for key, elems in self.model_copies.items() if elems])
        logger.info("The new content is {0}".format(new_content_of_clipboard.replace('_', ' ')))

        return selected_models_dict, parent_m

Response: Create a dictionary of all models and model objects that are copied and the model objects of the selected elements.


Instruction:
Here you have a function in Python 3, explain what it does
def destroy_all_models_in_dict(target_dict):
        if target_dict:
            for model_list in target_dict.values():
                if isinstance(model_list, (list, tuple)):
                    for model in model_list:
                        model.prepare_destruction()
                        if model._parent:
                            model._parent = None
                else:
                    raise Exception("wrong data in clipboard")

Response: Method runs the prepare destruction method of all models in a dict.


Instruction:
Can you generate the documentation for the following Python 3 function
def destroy(self):
        self.destroy_all_models_in_dict(self.model_copies)
        self.model_copies = None
        self.copy_parent_state_id = None
        self.outcome_id_mapping_dict = None
        self.port_id_mapping_dict = None
        self.state_id_mapping_dict = None

Response: Destroys the clipboard by relieving all model references.


Instruction:
Explain what the following Python 3 code does
def extend_extents(extents, factor=1.1):
    width = extents[2] - extents[0]
    height = extents[3] - extents[1]
    add_width = (factor - 1) * width
    add_height = (factor - 1) * height
    x1 = extents[0] - add_width / 2
    x2 = extents[2] + add_width / 2
    y1 = extents[1] - add_height / 2
    y2 = extents[3] + add_height / 2
    return x1, y1, x2, y2

Response: Extend a bounding box by a given factor


Instruction:
Make a summary of the following Python 3 code
def calc_rel_pos_to_parent(canvas, item, handle):
    from gaphas.item import NW

    if isinstance(item, ConnectionView):
        return item.canvas.get_matrix_i2i(item, item.parent).transform_point(*handle.pos)

    parent = canvas.get_parent(item)
    if parent:
        return item.canvas.get_matrix_i2i(item, parent).transform_point(*handle.pos)
    else:
        return item.canvas.get_matrix_i2c(item).transform_point(*item.handles()[NW].pos)

Response: This method calculates the relative position of the given item s handle to its parent.


Instruction:
Here you have a function in Python 3, explain what it does
def assert_exactly_one_true(bool_list):
    assert isinstance(bool_list, list)
    counter = 0
    for item in bool_list:
        if item:
            counter += 1
    return counter == 1

Response: This method asserts that only one value of the provided list is True.


Instruction:
Given the following Python 3 function, write the documentation
def get_port_for_handle(handle, state):
    from rafcon.gui.mygaphas.items.state import StateView
    if isinstance(state, StateView):
        if state.income.handle == handle:
            return state.income
        else:
            for outcome in state.outcomes:
                if outcome.handle == handle:
                    return outcome
            for input in state.inputs:
                if input.handle == handle:
                    return input
            for output in state.outputs:
                if output.handle == handle:
                    return output
            for scoped in state.scoped_variables:
                if scoped.handle == handle:
                    return scoped

Response: Looks for and returns the PortView to the given handle in the provided state


Instruction:
Here you have a function in Python 3, explain what it does
def create_new_connection(from_port, to_port):
    from rafcon.gui.mygaphas.items.ports import ScopedVariablePortView, LogicPortView, DataPortView

    if isinstance(from_port, LogicPortView) and isinstance(to_port, LogicPortView):
        return add_transition_to_state(from_port, to_port)
    elif isinstance(from_port, (DataPortView, ScopedVariablePortView)) and \
            isinstance(to_port, (DataPortView, ScopedVariablePortView)):
        return add_data_flow_to_state(from_port, to_port)
    # Both ports are not None
    elif from_port and to_port:
        logger.error("Connection of non-compatible ports: {0} and {1}".format(type(from_port), type(to_port)))

    return False

Response: Checks the type of connection and creates a new connection if it is not already added


Instruction:
Here you have a function in Python 3, explain what it does
def add_data_flow_to_state(from_port, to_port):
    from rafcon.gui.mygaphas.items.ports import InputPortView, OutputPortView, ScopedVariablePortView
    from rafcon.gui.models.container_state import ContainerStateModel

    from_state_v = from_port.parent
    to_state_v = to_port.parent

    from_state_m = from_state_v.model
    to_state_m = to_state_v.model

    from_state_id = from_state_m.state.state_id
    to_state_id = to_state_m.state.state_id

    from_port_id = from_port.port_id
    to_port_id = to_port.port_id

    if not isinstance(from_port, (InputPortView, OutputPortView, ScopedVariablePortView)) or \
            not isinstance(from_port, (InputPortView, OutputPortView, ScopedVariablePortView)):
        logger.error("Data flows only exist between data ports (input, output, scope). Given: {0} and {1}".format(type(
            from_port), type(to_port)))
        return False

    responsible_parent_m = None

    # from parent to child
    if isinstance(from_state_m, ContainerStateModel) and \
            check_if_dict_contains_object_reference_in_values(to_state_m.state, from_state_m.state.states):
        responsible_parent_m = from_state_m
    # from child to parent
    elif isinstance(to_state_m, ContainerStateModel) and \
            check_if_dict_contains_object_reference_in_values(from_state_m.state, to_state_m.state.states):
        responsible_parent_m = to_state_m
    # from parent to parent
    elif isinstance(from_state_m, ContainerStateModel) and from_state_m.state is to_state_m.state:
        responsible_parent_m = from_state_m  # == to_state_m
    # from child to child
    elif (not from_state_m.state.is_root_state) and (not to_state_m.state.is_root_state) \
            and from_state_m.state is not to_state_m.state \
            and from_state_m.parent.state.state_id and to_state_m.parent.state.state_id:
        responsible_parent_m = from_state_m.parent

    if not isinstance(responsible_parent_m, ContainerStateModel):
        logger.error("Data flows only exist in container states (e.g. hierarchy states)")
        return False

    try:
        responsible_parent_m.state.add_data_flow(from_state_id, from_port_id, to_state_id, to_port_id)
        return True
    except (ValueError, AttributeError, TypeError) as e:
        logger.error("Data flow couldn't be added: {0}".format(e))
        return False

Response: This method adds a data flow between two state models.


Instruction:
Here you have a function in Python 3, explain what it does
def add_transition_to_state(from_port, to_port):
    from rafcon.gui.mygaphas.items.ports import IncomeView, OutcomeView

    from_state_v = from_port.parent
    to_state_v = to_port.parent

    from_state_m = from_state_v.model
    to_state_m = to_state_v.model

    # Gather necessary information to create transition
    from_state_id = from_state_m.state.state_id
    to_state_id = to_state_m.state.state_id

    responsible_parent_m = None

    # Start transition
    if isinstance(from_port, IncomeView):
        from_state_id = None
        from_outcome_id = None
        responsible_parent_m = from_state_m
        # Transition from parent income to child income
        if isinstance(to_port, IncomeView):
            to_outcome_id = None
        # Transition from parent income to parent outcome
        elif isinstance(to_port, OutcomeView):
            to_outcome_id = to_port.outcome_id
    elif isinstance(from_port, OutcomeView):
        from_outcome_id = from_port.outcome_id
        # Transition from child outcome to child income
        if isinstance(to_port, IncomeView):
            responsible_parent_m = from_state_m.parent
            to_outcome_id = None
        # Transition from child outcome to parent outcome
        elif isinstance(to_port, OutcomeView):
            responsible_parent_m = to_state_m
            to_outcome_id = to_port.outcome_id
    else:
        raise ValueError("Invalid port type")

    from rafcon.gui.models.container_state import ContainerStateModel
    if not responsible_parent_m:
        logger.error("Transitions only exist between incomes and outcomes. Given: {0} and {1}".format(type(
            from_port), type(to_port)))
        return False
    elif not isinstance(responsible_parent_m, ContainerStateModel):
        logger.error("Transitions only exist in container states (e.g. hierarchy states)")
        return False

    try:
        t_id = responsible_parent_m.state.add_transition(from_state_id, from_outcome_id, to_state_id, to_outcome_id)
        if from_state_id == to_state_id:
            gui_helper_meta_data.insert_self_transition_meta_data(responsible_parent_m.states[from_state_id], t_id,
                                                                  combined_action=True)
        return True
    except (ValueError, AttributeError, TypeError) as e:
        logger.error("Transition couldn't be added: {0}".format(e))
        return False

Response: This method adds a transition from one state to another.


Instruction:
Given the following Python 3 function, write the documentation
def get_relative_positions_of_waypoints(transition_v):
    handles_list = transition_v.handles()
    rel_pos_list = []
    for handle in handles_list:
        if handle in transition_v.end_handles(include_waypoints=True):
            continue
        rel_pos = transition_v.canvas.get_matrix_i2i(transition_v, transition_v.parent).transform_point(*handle.pos)
        rel_pos_list.append(rel_pos)
    return rel_pos_list

Response: This method returns all relative positions of waypoints in a transition_v.


Instruction:
Explain what the following Python 3 code does
def update_meta_data_for_transition_waypoints(graphical_editor_view, transition_v, last_waypoint_list, publish=True):

    from rafcon.gui.mygaphas.items.connection import TransitionView
    assert isinstance(transition_v, TransitionView)

    transition_m = transition_v.model
    waypoint_list = get_relative_positions_of_waypoints(transition_v)
    if waypoint_list != last_waypoint_list:
        transition_m.set_meta_data_editor('waypoints', waypoint_list)
        if publish:
            graphical_editor_view.emit('meta_data_changed', transition_m, "waypoints", False)

Response: This method updates the meta data of the transition waypoints if they changed.


Instruction:
Can you tell what is the following Python 3 function doing
def update_meta_data_for_name_view(graphical_editor_view, name_v, publish=True):
    from gaphas.item import NW

    rel_pos = calc_rel_pos_to_parent(graphical_editor_view.editor.canvas, name_v, name_v.handles()[NW])

    state_v = graphical_editor_view.editor.canvas.get_parent(name_v)
    state_v.model.set_meta_data_editor('name.size', (name_v.width, name_v.height))
    state_v.model.set_meta_data_editor('name.rel_pos', rel_pos)

    if publish:
        graphical_editor_view.emit('meta_data_changed', state_v.model, "name_size", False)

Response: This method updates the meta data of a name view.


Instruction:
Given the following Python 3 function, write the documentation
def update_meta_data_for_state_view(graphical_editor_view, state_v, affects_children=False, publish=True):
    from gaphas.item import NW

    # Update all port meta data to match with new position and size of parent
    update_meta_data_for_port(graphical_editor_view, state_v, None)

    if affects_children:
        update_meta_data_for_name_view(graphical_editor_view, state_v.name_view, publish=False)
        for transition_v in state_v.get_transitions():
            update_meta_data_for_transition_waypoints(graphical_editor_view, transition_v, None, publish=False)
        for child_state_v in state_v.child_state_views():
            update_meta_data_for_state_view(graphical_editor_view, child_state_v, True, publish=False)

    rel_pos = calc_rel_pos_to_parent(graphical_editor_view.editor.canvas, state_v, state_v.handles()[NW])

    state_v.model.set_meta_data_editor('size', (state_v.width, state_v.height))
    state_v.model.set_meta_data_editor('rel_pos', rel_pos)

    if publish:
        graphical_editor_view.emit('meta_data_changed', state_v.model, "size", affects_children)

Response: This method updates the meta data of a state view. It updates all ports and transitions and child state views.


Instruction:
How would you code a function in Python 3 to
remove all children and then the StateView itself.

Response:
def remove(self):
        """Remove recursively all children and then the StateView itself
        """
        self.canvas.get_first_view().unselect_item(self)

        for child in self.canvas.get_children(self)[:]:
            child.remove()

        self.remove_income()
        for outcome_v in self.outcomes[:]:
            self.remove_outcome(outcome_v)
        for input_port_v in self.inputs[:]:
            self.remove_input_port(input_port_v)
        for output_port_v in self.outputs[:]:
            self.remove_output_port(output_port_v)
        for scoped_variable_port_v in self.scoped_variables[:]:
            self.remove_scoped_variable(scoped_variable_port_v)

        self.remove_keep_rect_within_constraint_from_parent()
        for constraint in self._constraints[:]:
            self.canvas.solver.remove_constraint(constraint)
            self._constraints.remove(constraint)
        self.canvas.remove(self)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def set_enable_flag_keep_rect_within_constraints(self, enable):
        for child_state_v in self.child_state_views():
            self.keep_rect_constraints[child_state_v].enable = enable
            child_state_v.keep_rect_constraints[child_state_v._name_view].enable = enable

Response: Enable or disable the KeepRectangleWithinConstraint for all child states.


Instruction:
Write a Python 3 function for
checking if the state is a library with the show_content flag set

Response:
def show_content(self, with_content=False):
        """Checks if the state is a library with the `show_content` flag set

        :param with_content: If this parameter is `True`, the method return only True if the library represents a
          ContainerState
        :return: Whether the content of a library state is shown
        """
        if isinstance(self.model, LibraryStateModel) and self.model.show_content():
            return not with_content or isinstance(self.model.state_copy, ContainerStateModel)
        return False


Instruction:
Explain what the following Python 3 code does
def _calculate_port_pos_on_line(self, port_num, side_length, port_width=None):
        if port_width is None:
            port_width = 2 * self.border_width
        border_size = self.border_width
        pos = 0.5 * border_size + port_num * port_width
        outermost_pos = max(side_length / 2., side_length - 0.5 * border_size - port_width)
        pos = min(pos, outermost_pos)
        return pos

Response: Calculate the position of a port on a line.


Instruction:
Given the following Python 3 function, write the documentation
def write_dict_to_yaml(dictionary, path, **kwargs):
    with open(path, 'w') as f:
        yaml.dump(dictionary, f, indent=4, **kwargs)

Response: Writes a dictionary to a yaml file


Instruction:
Here you have a function in Python 3, explain what it does
def load_dict_from_yaml(path):
    f = file(path, 'r')
    dictionary = yaml.load(f)
    f.close()
    return dictionary

Response: Loads a dictionary from a yaml file


Instruction:
How would you explain what the following Python 3 function does
def write_dict_to_json(dictionary, path, **kwargs):
    result_string = json.dumps(dictionary, cls=JSONObjectEncoder,
                               indent=4, check_circular=False, sort_keys=True, **kwargs)
    with open(path, 'w') as f:
        # We cannot write directly to the file, as otherwise the 'encode' method wouldn't be called
        f.write(result_string)

Response: Writes a dictionary to a json file.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def load_objects_from_json(path, as_dict=False):
    f = open(path, 'r')
    if as_dict:
        result = json.load(f)
    else:
        result = json.load(f, cls=JSONObjectDecoder, substitute_modules=substitute_modules)
    f.close()
    return result

Response: Loads a dictionary from a json file.


Instruction:
Given the following Python 3 function, write the documentation
def solve_for(self, var=None):
        if not self.enable:
            return

        margin = self.margin_method()

        def parent_width():
            return self.parent_se[0].value - self.parent_nw[0].value

        def parent_height():
            return self.parent_se[1].value - self.parent_nw[1].value

        def child_width():
            child_width = self.child_se[0].value - self.child_nw[0].value
            if child_width > parent_width() - 2 * margin:
                child_width = parent_width() - 2 * margin
            return max(self.child.min_width, child_width)

        def child_height():
            child_height = self.child_se[1].value - self.child_nw[1].value
            if child_height > parent_height() - 2 * margin:
                child_height = parent_height() - 2 * margin
            return max(self.child.min_height, child_height)

        updated = False
        # Left edge (west)
        if self.parent_nw[0].value > self.child_nw[0].value - margin + EPSILON:
            width = child_width()
            _update(self.child_nw[0], self.parent_nw[0].value + margin)
            _update(self.child_se[0], self.child_nw[0].value + width)
            updated = True
        # Right edge (east)
        elif self.parent_se[0].value < self.child_se[0].value + margin - EPSILON:
            width = child_width()
            _update(self.child_se[0], self.parent_se[0].value - margin)
            _update(self.child_nw[0], self.child_se[0].value - width)
            updated = True
        # Upper edge (north)
        if self.parent_nw[1].value > self.child_nw[1].value - margin + EPSILON:
            height = child_height()
            _update(self.child_nw[1], self.parent_nw[1].value + margin)
            _update(self.child_se[1], self.child_nw[1].value + height)
            updated = True
        # Lower edge (south)
        elif self.parent_se[1].value < self.child_se[1].value + margin - EPSILON:
            height = child_height()
            _update(self.child_se[1], self.parent_se[1].value - margin)
            _update(self.child_nw[1], self.child_se[1].value - height)
            updated = True

        from rafcon.gui.mygaphas.items.state import StateView
        if updated and isinstance(self.child, StateView):
            self.child.update_minimum_size_of_children()

Response: Solve the child for a specific variable.


Instruction:
Given the following Python 3 function, write the documentation
def solve_for(self, var=None):
        margin = self.margin_method()
        if self.parent_nw[0].value > self.child[0].value - margin:
            _update(self.child[0], self.parent_nw[0].value + margin)
        # Right edge (east)
        if self.parent_se[0].value < self.child[0].value + margin:
            _update(self.child[0], self.parent_se[0].value - margin)
        # Upper edge (north)
        if self.parent_nw[1].value > self.child[1].value - margin:
            _update(self.child[1], self.parent_nw[1].value + margin)
        # Lower edge (south)
        if self.parent_se[1].value < self.child[1].value + margin:
            _update(self.child[1], self.parent_se[1].value - margin)

Response: Solve for the child of the log entry.


Instruction:
How would you code a function in Python 3 to
update the initial position of the port.

Response:
def update_port_side(self):
        """Updates the initial position of the port

        The port side is ignored but calculated from the port position. Then the port position is limited to the four
        side lines of the state.
        """
        from rafcon.utils.geometry import point_left_of_line

        p = (self._initial_pos.x, self._initial_pos.y)
        nw_x, nw_y, se_x, se_y = self.get_adjusted_border_positions()
        if point_left_of_line(p, (nw_x, nw_y), (se_x, se_y)):  # upper right triangle of state
            if point_left_of_line(p, (nw_x, se_y), (se_x, nw_y)):  # upper quarter triangle of state
                self._port.side = SnappedSide.TOP
                self.limit_pos(p[0], se_x, nw_x)
            else:  # right quarter triangle of state
                self._port.side = SnappedSide.RIGHT
                self.limit_pos(p[1], se_y, nw_y)
        else:  # lower left triangle of state
            if point_left_of_line(p, (nw_x, se_y), (se_x, nw_y)):  # left quarter triangle of state
                self._port.side = SnappedSide.LEFT
                self.limit_pos(p[1], se_y, nw_y)
            else:  # lower quarter triangle of state
                self._port.side = SnappedSide.BOTTOM
                self.limit_pos(p[0], se_x, nw_x)

        self.set_nearest_border()


Instruction:
Write a Python 3 function for
solving the port movement and keep it aligned with the binding rect.

Response:
def _solve(self):
        """
        Calculates the correct position of the port and keeps it aligned with the binding rect
        """

        # As the size of the containing state may has changed we need to update the distance to the border
        self.update_distance_to_border()
        px, py = self._point
        nw_x, nw_y, se_x, se_y = self.get_adjusted_border_positions()

        # If the port is located in one of the corners it is possible to move in two directions
        if ((self._initial_pos.x == nw_x and self._initial_pos.y == nw_y) or
                (self._initial_pos.x == se_x and self._initial_pos.y == nw_y) or
                (self._initial_pos.x == se_x and self._initial_pos.y == se_y) or
                (self._initial_pos.x == nw_x and self._initial_pos.y == se_y)):
            self.limit_pos(px, se_x, nw_x)
            self.limit_pos(py, se_y, nw_y)
        # If port movement starts at LEFT position, keep X position at place and move Y
        elif self._initial_pos.x == nw_x:
            _update(px, nw_x)
            self.limit_pos(py, se_y, nw_y)
            self._port.side = SnappedSide.LEFT
        # If port movement starts at TOP position, keep Y position at place and move X
        elif self._initial_pos.y == nw_y:
            _update(py, nw_y)
            self.limit_pos(px, se_x, nw_x)
            self._port.side = SnappedSide.TOP
        # If port movement starts at RIGHT position, keep X position at place and move Y
        elif self._initial_pos.x == se_x:
            _update(px, se_x)
            self.limit_pos(py, se_y, nw_y)
            self._port.side = SnappedSide.RIGHT
        # If port movement starts at BOTTOM position, keep Y position at place and move X
        elif self._initial_pos.y == se_y:
            _update(py, se_y)
            self.limit_pos(px, se_x, nw_x)
            self._port.side = SnappedSide.BOTTOM
        # If containing state has been resized, snap ports accordingly to border
        else:
            self.set_nearest_border()

        # Update initial position for next reference
        _update(self._initial_pos.x, deepcopy(px.value))
        _update(self._initial_pos.y, deepcopy(py.value))


Instruction:
How would you implement a function in Python 3 that
limits the position p to stay inside containing state

Response:
def limit_pos(p, se_pos, nw_pos):
        """
        Limits position p to stay inside containing state
        :param p: Position to limit
        :param se_pos: Bottom/Right boundary
        :param nw_pos: Top/Left boundary
        :return:
        """
        if p > se_pos:
            _update(p, se_pos)
        elif p < nw_pos:
            _update(p, nw_pos)


Instruction:
Can you tell what is the following Python 3 function doing
def get_adjusted_border_positions(self):
        nw_x, nw_y = self._rect[0]
        se_x, se_y = self._rect[1]

        nw_x += self._distance_to_border
        nw_y += self._distance_to_border
        se_x -= self._distance_to_border
        se_y -= self._distance_to_border

        return nw_x, nw_y, se_x, se_y

Response: Calculates the positions to limit the port movement to


Instruction:
Create a Python 3 function to
snap the port to the correct side upon state size change

Response:
def set_nearest_border(self):
        """Snaps the port to the correct side upon state size change
        """
        px, py = self._point
        nw_x, nw_y, se_x, se_y = self.get_adjusted_border_positions()

        if self._port.side == SnappedSide.RIGHT:
            _update(px, se_x)
        elif self._port.side == SnappedSide.BOTTOM:
            _update(py, se_y)
        elif self._port.side == SnappedSide.LEFT:
            _update(px, nw_x)
        elif self._port.side == SnappedSide.TOP:
            _update(py, nw_y)


Instruction:
Can you tell what is the following Python 3 function doing
def remove_obsolete_folders(states, path):
    elements_in_folder = os.listdir(path)
    # find all state folder elements in system path
    state_folders_in_file_system = []
    for folder_name in elements_in_folder:
        if os.path.exists(os.path.join(path, folder_name, FILE_NAME_CORE_DATA)) or \
                os.path.exists(os.path.join(path, folder_name, FILE_NAME_CORE_DATA_OLD)):
            state_folders_in_file_system.append(folder_name)

    # remove elements used by existing states and storage format
    for state in states:
        storage_folder_for_state = get_storage_id_for_state(state)
        if storage_folder_for_state in state_folders_in_file_system:
            state_folders_in_file_system.remove(storage_folder_for_state)

    # remove the remaining state folders
    for folder_name in state_folders_in_file_system:
        shutil.rmtree(os.path.join(path, folder_name))

Response: Removes obsolete state machine folders


Instruction:
Can you tell what is the following Python 3 function doing
def clean_path_from_deprecated_naming(base_path):
    def warning_logger_message(insert_string):
        not_allowed_characters = "'" + "', '".join(REPLACED_CHARACTERS_FOR_NO_OS_LIMITATION.keys()) + "'"
        logger.warning("Deprecated {2} in {0}. Please avoid to use the following characters {1}."
                       "".format(base_path, not_allowed_characters, insert_string))
    from rafcon.core.singleton import library_manager
    if library_manager.is_os_path_within_library_root_paths(base_path):
        library_path, library_name = library_manager.get_library_path_and_name_for_os_path(base_path)
        clean_library_path = clean_path(library_path)
        clean_library_name = clean_path(library_name)
        if library_name != clean_library_name or library_path != clean_library_path:
            warning_logger_message("library path")
        library_root_key = library_manager._get_library_root_key_for_os_path(base_path)
        library_root_path = library_manager._library_root_paths[library_root_key]
        clean_base_path = os.path.join(library_root_path, clean_library_path, clean_library_name)
    else:
        path_elements = base_path.split(os.path.sep)
        state_machine_folder_name = base_path.split(os.path.sep)[-1]
        path_elements[-1] = clean_path(state_machine_folder_name)
        if not state_machine_folder_name == path_elements[-1]:
            warning_logger_message("state machine folder name")
        clean_base_path = os.path.sep.join(path_elements)
    return clean_base_path

Response: Checks if the base path includes deprecated characters and returns corrected version


Instruction:
Given the following Python 3 function, write the documentation
def clean_path(base_path):
    path_elements = base_path.split(os.path.sep)
    reduced_path_elements = [clean_path_element(elem, max_length=255) for elem in path_elements]
    if not all(path_elements[i] == elem for i, elem in enumerate(reduced_path_elements)):
        # logger.info("State machine storage path is reduced")
        base_path = os.path.sep.join(reduced_path_elements)
    return base_path

Response: This function cleans a file system path in terms of removing all not allowed characters of each path element.


Instruction:
Here you have a function in Python 3, explain what it does
def save_state_machine_to_path(state_machine, base_path, delete_old_state_machine=False, as_copy=False):
    # warns the user in the logger when using deprecated names
    clean_path_from_deprecated_naming(base_path)

    state_machine.acquire_modification_lock()
    try:
        root_state = state_machine.root_state

        # clean old path first
        if delete_old_state_machine:
            if os.path.exists(base_path):
                shutil.rmtree(base_path)

        # Ensure that path is existing
        if not os.path.exists(base_path):
            os.makedirs(base_path)

        old_update_time = state_machine.last_update
        state_machine.last_update = storage_utils.get_current_time_string()
        state_machine_dict = state_machine.to_dict()
        storage_utils.write_dict_to_json(state_machine_dict, os.path.join(base_path, STATEMACHINE_FILE))

        # set the file_system_path of the state machine
        if not as_copy:
            state_machine.file_system_path = copy.copy(base_path)
        else:
            state_machine.last_update = old_update_time

        # add root state recursively
        remove_obsolete_folders([root_state], base_path)
        save_state_recursively(root_state, base_path, "", as_copy)

        if state_machine.marked_dirty and not as_copy:
            state_machine.marked_dirty = False
        logger.debug("State machine with id {0} was saved at {1}".format(state_machine.state_machine_id, base_path))
    except Exception:
        raise
    finally:
        state_machine.release_modification_lock()

Response: Saves a state machine to a file system.


Instruction:
Here you have a function in Python 3, explain what it does
def save_script_file_for_state_and_source_path(state, state_path_full, as_copy=False):
    from rafcon.core.states.execution_state import ExecutionState
    if isinstance(state, ExecutionState):
        source_script_file = os.path.join(state.script.path, state.script.filename)
        destination_script_file = os.path.join(state_path_full, SCRIPT_FILE)

        try:
            write_file(destination_script_file, state.script_text)
        except Exception:
            logger.exception("Storing of script file failed: {0} -> {1}".format(state.get_path(),
                                                                                destination_script_file))
            raise

        if not source_script_file == destination_script_file and not as_copy:
            state.script.filename = SCRIPT_FILE
            state.script.path = state_path_full

Response: Saves the script file for a state and the source path.


Instruction:
Create a Python 3 function to
save the semantic data for the state to a separate json file.

Response:
def save_semantic_data_for_state(state, state_path_full):
    """Saves the semantic data in a separate json file.

    :param state: The state of which the script file should be saved
    :param str state_path_full: The path to the file system storage location of the state
    """

    destination_script_file = os.path.join(state_path_full, SEMANTIC_DATA_FILE)

    try:
        storage_utils.write_dict_to_json(state.semantic_data, destination_script_file)
    except IOError:
        logger.exception("Storing of semantic data for state {0} failed! Destination path: {1}".
                         format(state.get_path(), destination_script_file))
        raise


Instruction:
Can you tell what is the following Python 3 function doing
def save_state_recursively(state, base_path, parent_path, as_copy=False):
    from rafcon.core.states.execution_state import ExecutionState
    from rafcon.core.states.container_state import ContainerState

    state_path = os.path.join(parent_path, get_storage_id_for_state(state))
    state_path_full = os.path.join(base_path, state_path)
    if not os.path.exists(state_path_full):
        os.makedirs(state_path_full)

    storage_utils.write_dict_to_json(state, os.path.join(state_path_full, FILE_NAME_CORE_DATA))
    if not as_copy:
        state.file_system_path = state_path_full

    if isinstance(state, ExecutionState):
        save_script_file_for_state_and_source_path(state, state_path_full, as_copy)

    save_semantic_data_for_state(state, state_path_full)

    # create yaml files for all children
    if isinstance(state, ContainerState):
        remove_obsolete_folders(state.states.values(), os.path.join(base_path, state_path))
        for state in state.states.values():
            save_state_recursively(state, base_path, state_path, as_copy)

Response: Recursively saves a state to a json file


Instruction:
Can you tell what is the following Python 3 function doing
def load_state_machine_from_path(base_path, state_machine_id=None):
    logger.debug("Loading state machine from path {0}...".format(base_path))

    state_machine_file_path = os.path.join(base_path, STATEMACHINE_FILE)
    state_machine_file_path_old = os.path.join(base_path, STATEMACHINE_FILE_OLD)

    # was the root state specified as state machine base_path to load from?
    if not os.path.exists(state_machine_file_path) and not os.path.exists(state_machine_file_path_old):

        # catch the case that a state machine root file is handed
        if os.path.exists(base_path) and os.path.isfile(base_path):
            base_path = os.path.dirname(base_path)
            state_machine_file_path = os.path.join(base_path, STATEMACHINE_FILE)
            state_machine_file_path_old = os.path.join(base_path, STATEMACHINE_FILE_OLD)

        if not os.path.exists(state_machine_file_path) and not os.path.exists(state_machine_file_path_old):
            raise ValueError("Provided path doesn't contain a valid state machine: {0}".format(base_path))

    state_machine_dict = storage_utils.load_objects_from_json(state_machine_file_path)
    if 'used_rafcon_version' in state_machine_dict:
        previously_used_rafcon_version = StrictVersion(state_machine_dict['used_rafcon_version']).version
        active_rafcon_version = StrictVersion(rafcon.__version__).version

        rafcon_newer_than_sm_version = "You are trying to load a state machine that was stored with an older " \
                                       "version of RAFCON ({0}) than the one you are using ({1}).".format(
                                        state_machine_dict['used_rafcon_version'], rafcon.__version__)
        rafcon_older_than_sm_version = "You are trying to load a state machine that was stored with an newer " \
                                       "version of RAFCON ({0}) than the one you are using ({1}).".format(
                                        state_machine_dict['used_rafcon_version'], rafcon.__version__)
        note_about_possible_incompatibility = "The state machine will be loaded with no guarantee of success."

        if active_rafcon_version[0] > previously_used_rafcon_version[0]:
            # this is the default case
            # for a list of breaking changes please see: doc/breaking_changes.rst
            # logger.warning(rafcon_newer_than_sm_version)
            # logger.warning(note_about_possible_incompatibility)
            pass
        if active_rafcon_version[0] == previously_used_rafcon_version[0]:
            if active_rafcon_version[1] > previously_used_rafcon_version[1]:
                # this is the default case
                # for a list of breaking changes please see: doc/breaking_changes.rst
                # logger.info(rafcon_newer_than_sm_version)
                # logger.info(note_about_possible_incompatibility)
                pass
            elif active_rafcon_version[1] == previously_used_rafcon_version[1]:
                # Major and minor version of RAFCON and the state machine match
                # It should be safe to load the state machine, as the patch level does not change the format
                pass
            else:
                logger.warning(rafcon_older_than_sm_version)
                logger.warning(note_about_possible_incompatibility)
        else:
            logger.warning(rafcon_older_than_sm_version)
            logger.warning(note_about_possible_incompatibility)

    state_machine = StateMachine.from_dict(state_machine_dict, state_machine_id)
    if "root_state_storage_id" not in state_machine_dict:
        root_state_storage_id = state_machine_dict['root_state_id']
        state_machine.supports_saving_state_names = False
    else:
        root_state_storage_id = state_machine_dict['root_state_storage_id']

    root_state_path = os.path.join(base_path, root_state_storage_id)
    state_machine.file_system_path = base_path
    dirty_states = []
    state_machine.root_state = load_state_recursively(parent=state_machine, state_path=root_state_path,
                                                      dirty_states=dirty_states)
    if len(dirty_states) > 0:
        state_machine.marked_dirty = True
    else:
        state_machine.marked_dirty = False

    hierarchy_level = 0
    number_of_states, hierarchy_level = state_machine.root_state.get_states_statistics(hierarchy_level)
    logger.debug("Loaded state machine ({1}) has {0} states. (Max hierarchy level {2})".format(
        number_of_states, base_path, hierarchy_level))
    logger.debug("Loaded state machine ({1}) has {0} transitions.".format(
        state_machine.root_state.get_number_of_transitions(), base_path))

    return state_machine

Response: Loads a state machine from the given path.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def load_state_recursively(parent, state_path=None, dirty_states=[]):
    from rafcon.core.states.execution_state import ExecutionState
    from rafcon.core.states.container_state import ContainerState
    from rafcon.core.states.hierarchy_state import HierarchyState

    path_core_data = os.path.join(state_path, FILE_NAME_CORE_DATA)

    logger.debug("Load state recursively: {0}".format(str(state_path)))

    # TODO: Should be removed with next minor release
    if not os.path.exists(path_core_data):
        path_core_data = os.path.join(state_path, FILE_NAME_CORE_DATA_OLD)

    try:
        state_info = load_data_file(path_core_data)
    except ValueError as e:
        logger.exception("Error while loading state data: {0}".format(e))
        return
    except LibraryNotFoundException as e:
        logger.error("Library could not be loaded: {0}\n"
                     "Skipping library and continuing loading the state machine".format(e))
        state_info = storage_utils.load_objects_from_json(path_core_data, as_dict=True)
        state_id = state_info["state_id"]
        dummy_state = HierarchyState(LIBRARY_NOT_FOUND_DUMMY_STATE_NAME, state_id=state_id)
        # set parent of dummy state
        if isinstance(parent, ContainerState):
            parent.add_state(dummy_state, storage_load=True)
        else:
            dummy_state.parent = parent
        return dummy_state

    # Transitions and data flows are not added when loading a state, as also states are not added.
    # We have to wait until the child states are loaded, before adding transitions and data flows, as otherwise the
    # validity checks for transitions and data flows would fail
    if not isinstance(state_info, tuple):
        state = state_info
    else:
        state = state_info[0]
        transitions = state_info[1]
        data_flows = state_info[2]

    # set parent of state
    if parent is not None and isinstance(parent, ContainerState):
        parent.add_state(state, storage_load=True)
    else:
        state.parent = parent

    # read script file if an execution state
    if isinstance(state, ExecutionState):
        script_text = read_file(state_path, state.script.filename)
        state.script_text = script_text

    # load semantic data
    try:
        semantic_data = load_data_file(os.path.join(state_path, SEMANTIC_DATA_FILE))
        state.semantic_data = semantic_data
    except Exception as e:
        # semantic data file does not have to be there
        pass

    one_of_my_child_states_not_found = False

    # load child states
    for p in os.listdir(state_path):
        child_state_path = os.path.join(state_path, p)
        if os.path.isdir(child_state_path):
            child_state = load_state_recursively(state, child_state_path, dirty_states)
            if child_state.name is LIBRARY_NOT_FOUND_DUMMY_STATE_NAME:
                one_of_my_child_states_not_found = True

    if one_of_my_child_states_not_found:
        # omit adding transitions and data flows in this case
        pass
    else:
        # Now we can add transitions and data flows, as all child states were added
        if isinstance(state_info, tuple):
            state.transitions = transitions
            state.data_flows = data_flows

    state.file_system_path = state_path

    if state.marked_dirty:
        dirty_states.append(state)

    return state

Response: Recursively loads the state of a state machine.


Instruction:
Can you generate the documentation for the following Python 3 function
def load_data_file(path_of_file):
    if os.path.exists(path_of_file):
        return storage_utils.load_objects_from_json(path_of_file)
    raise ValueError("Data file not found: {0}".format(path_of_file))

Response: Loads the content of a file by using json. load.


Instruction:
Can you generate the documentation for the following Python 3 function
def limit_text_max_length(text, max_length, separator='_'):
    if max_length is not None:
        if isinstance(text, string_types) and len(text) > max_length:
            max_length = int(max_length)
            half_length = float(max_length - 1) / 2
            return text[:int(math.ceil(half_length))] + separator + text[-int(math.floor(half_length)):]
    return text

Response: Limit the length of a string to a maximum length.


Instruction:
Make a summary of the following Python 3 code
def clean_path_element(text, max_length=None, separator='_'):
    elements_to_replace = REPLACED_CHARACTERS_FOR_NO_OS_LIMITATION
    for elem, replace_with in elements_to_replace.items():
        text = text.replace(elem, replace_with)
    if max_length is not None:
        text = limit_text_max_length(text, max_length, separator)
    return text

Response: Replace characters that conflict with a free OS choice when in a file system path.


Instruction:
How would you code a function in Python 3 to
limit the text to be a path element.

Response:
def limit_text_to_be_path_element(text, max_length=None, separator='_'):
    """ Replace characters that are not in the valid character set of RAFCON.

    :param text: the string to be cleaned
    :param max_length: the maximum length of the output string
    :param separator: the separator used for rafcon.core.storage.storage.limit_text_max_length
    :return:
    """
    # TODO: Should there not only be one method i.e. either this one or "clean_path_element"
    elements_to_replace = {' ': '_', '*': '_'}
    for elem, replace_with in elements_to_replace.items():
        text = text.replace(elem, replace_with)
    text = re.sub('[^a-zA-Z0-9-_]', '', text)
    if max_length is not None:
        text = limit_text_max_length(text, max_length, separator)
    return text


Instruction:
Can you generate the documentation for the following Python 3 function
def get_storage_id_for_state(state):
    if global_config.get_config_value('STORAGE_PATH_WITH_STATE_NAME'):
        max_length = global_config.get_config_value('MAX_LENGTH_FOR_STATE_NAME_IN_STORAGE_PATH')

        max_length_of_state_name_in_folder_name = 255 - len(ID_NAME_DELIMITER + state.state_id)
        # TODO: should we allow "None" in config file?
        if max_length is None or max_length == "None" or max_length > max_length_of_state_name_in_folder_name:
            if max_length_of_state_name_in_folder_name < len(state.name):
                logger.info("The storage folder name is forced to be maximal 255 characters in length.")
            max_length = max_length_of_state_name_in_folder_name

        return limit_text_to_be_path_element(state.name, max_length) + ID_NAME_DELIMITER + state.state_id
    else:
        return state.state_id

Response: Calculates the storage id for a state


Instruction:
Can you generate a brief explanation for the following Python 3 code
def pane_position_check(self):
        text_buffer = self.get_buffer()

        # not needed if the right side bar is un-docked
        from rafcon.gui.singleton import main_window_controller

        if main_window_controller is None or main_window_controller.view is None:
            return
        from rafcon.gui.runtime_config import global_runtime_config
        if global_runtime_config.get_config_value('RIGHT_BAR_WINDOW_UNDOCKED'):
            return

        # move the pane left if the cursor is to far right and the pane position is less then 440 from its max position
        button_container_min_width = self.button_container_min_width
        width_of_all = button_container_min_width + self.tab_width
        text_view_width = button_container_min_width - self.line_numbers_width
        min_line_string_length = float(button_container_min_width)/float(self.source_view_character_size)

        current_pane_pos = main_window_controller.view['right_h_pane'].get_property('position')
        max_position = main_window_controller.view['right_h_pane'].get_property('max_position')
        pane_rel_pos = main_window_controller.view['right_h_pane'].get_property('max_position') - current_pane_pos
        if pane_rel_pos >= width_of_all + self.line_numbers_width:
            pass
        else:
            cursor_line_offset = text_buffer.get_iter_at_offset(text_buffer.props.cursor_position).get_line_offset()
            needed_rel_pos = text_view_width/min_line_string_length*cursor_line_offset \
                             + self.tab_width + self.line_numbers_width
            needed_rel_pos = min(width_of_all, needed_rel_pos)
            if pane_rel_pos >= needed_rel_pos:
                pass
            else:
                main_window_controller.view['right_h_pane'].set_property('position', max_position - needed_rel_pos)
                spacer_width = int(width_of_all + self.line_numbers_width - needed_rel_pos)
                self.spacer_frame.set_size_request(width=spacer_width, height=-1)

Response: Updates the right bar pane position if needed


Instruction:
Explain what the following Python 3 code does
def push_call_history_item(self, state, call_type, state_for_scoped_data, input_data=None):
        last_history_item = self.get_last_history_item()
        from rafcon.core.states.library_state import LibraryState  # delayed imported on purpose
        if isinstance(state_for_scoped_data, LibraryState):
            state_for_scoped_data = state_for_scoped_data.state_copy
        return_item = CallItem(state, last_history_item, call_type, state_for_scoped_data, input_data,
                               state.run_id)
        return self._push_item(last_history_item, return_item)

Response: Adds a new call - history - item to the list of items that can be executed by the state machine.


Instruction:
Given the following Python 3 function, write the documentation
def push_return_history_item(self, state, call_type, state_for_scoped_data, output_data=None):
        last_history_item = self.get_last_history_item()
        from rafcon.core.states.library_state import LibraryState  # delayed imported on purpose
        if isinstance(state_for_scoped_data, LibraryState):
            state_for_scoped_data = state_for_scoped_data.state_copy
        return_item = ReturnItem(state, last_history_item, call_type, state_for_scoped_data, output_data,
                                 state.run_id)
        return self._push_item(last_history_item, return_item)

Response: Adds a new return - history - item to the list of return - history items


Instruction:
Can you generate the documentation for the following Python 3 function
def push_concurrency_history_item(self, state, number_concurrent_threads):
        last_history_item = self.get_last_history_item()
        return_item = ConcurrencyItem(state, self.get_last_history_item(),
                                      number_concurrent_threads, state.run_id,
                                      self.execution_history_storage)
        return self._push_item(last_history_item, return_item)

Response: Adds a new concurrency - history - item to the list of concurrency - history items that are currently in the execution history.


Instruction:
Given the following Python 3 function, write the documentation
def update_hash_from_dict(obj_hash, object_):
        if isinstance(object_, Hashable):
            object_.update_hash(obj_hash)
        elif isinstance(object_, (list, set, tuple)):
            if isinstance(object_, set):  # A set is not ordered
                object_ = sorted(object_)
            for element in object_:
                Hashable.update_hash_from_dict(obj_hash, element)
        elif isinstance(object_, dict):
            for key in sorted(object_.keys()):  # A dict is not ordered
                Hashable.update_hash_from_dict(obj_hash, key)
                Hashable.update_hash_from_dict(obj_hash, object_[key])
        else:
            obj_hash.update(Hashable.get_object_hash_string(object_))

Response: Updates an existing hash object with another Hashable list set tuple dict or stringifyable object.


Instruction:
Implement a function in Python 3 to
create a hash with the immutable data fields of the object

Response:
def mutable_hash(self, obj_hash=None):
        """Creates a hash with the (im)mutable data fields of the object

        Example:
            >>> my_obj = type("MyDerivedClass", (Hashable,), { "update_hash": lambda self, h: h.update("RAFCON") })()
            >>> my_obj_hash = my_obj.mutable_hash()
            >>> print('Hash: ' + my_obj_hash.hexdigest())
            Hash: c8b2e32dcb31c5282e4b9dbc6a9975b65bf59cd80a7cee66d195e320484df5c6

        :param obj_hash: The hash object (see Python hashlib)
        :return: The updated hash object
        """
        if obj_hash is None:
            obj_hash = hashlib.sha256()
        self.update_hash(obj_hash)
        return obj_hash


Instruction:
Explain what the following Python 3 code does
def emit(self, record):
        try:
            # Shorten the source name of the record (remove rafcon.)
            if sys.version_info >= (2, 7):
                record.__setattr__("name", record.name.replace("rafcon.", ""))
            msg = self.format(record)
            fs = "%s"
            try:
                ufs = u'%s'
                try:
                    entry = ufs % msg
                except UnicodeEncodeError:
                    entry = fs % msg
            except UnicodeError:
                entry = fs % msg

            for logging_view in self._logging_views.values():
                logging_view.print_message(entry, record.levelno)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)

Response: Logs a new record to all logging views.


Instruction:
Write a Python 3 function for
returning the meta data editor for the specified editor.

Response:
def get_meta_data_editor(self, for_gaphas=True):
        """Returns the editor for the specified editor

        This method should be used instead of accessing the meta data of an editor directly. It return the meta data
        of the editor available (with priority to the one specified by `for_gaphas`) and converts it if needed.

        :param bool for_gaphas: True (default) if the meta data is required for gaphas, False if for OpenGL
        :return: Meta data for the editor
        :rtype: Vividict
        """
        meta_gaphas = self.meta['gui']['editor_gaphas']
        meta_opengl = self.meta['gui']['editor_opengl']
        assert isinstance(meta_gaphas, Vividict) and isinstance(meta_opengl, Vividict)

        # Use meta data of editor with more keys (typically one of the editors has zero keys)
        # TODO check if the magic length condition in the next line can be improved (consistent behavior getter/setter?)
        parental_conversion_from_opengl = self._parent and self._parent().temp['conversion_from_opengl']
        from_gaphas = len(meta_gaphas) > len(meta_opengl) or (len(meta_gaphas) == len(meta_opengl) and for_gaphas and
                                                              not parental_conversion_from_opengl)
        # Convert meta data if meta data target and origin differ
        if from_gaphas and not for_gaphas:
            self.meta['gui']['editor_opengl'] = self._meta_data_editor_gaphas2opengl(meta_gaphas)
        elif not from_gaphas and for_gaphas:
            self.meta['gui']['editor_gaphas'] = self._meta_data_editor_opengl2gaphas(meta_opengl)

        # only keep meta data for one editor
        del self.meta['gui']['editor_opengl' if for_gaphas else 'editor_gaphas']
        return self.meta['gui']['editor_gaphas'] if for_gaphas else self.meta['gui']['editor_opengl']


Instruction:
Explain what the following Python 3 code does
def set_meta_data_editor(self, key, meta_data, from_gaphas=True):
        self.do_convert_meta_data_if_no_data(from_gaphas)
        meta_gui = self.meta['gui']
        meta_gui = meta_gui['editor_gaphas'] if from_gaphas else meta_gui['editor_opengl']

        key_path = key.split('.')
        for key in key_path:
            if isinstance(meta_gui, list):
                meta_gui[int(key)] = meta_data
                break
            if key == key_path[-1]:
                meta_gui[key] = meta_data
            else:
                meta_gui = meta_gui[key]

        return self.get_meta_data_editor(for_gaphas=from_gaphas)

Response: Sets the meta data for a specific key of the desired editor.


Instruction:
Explain what the following Python 3 code does
def meta_data_hash(self, obj_hash=None):
        if obj_hash is None:
            obj_hash = hashlib.sha256()
        self.update_meta_data_hash(obj_hash)
        return obj_hash

Response: Creates a hash with the meta data of the model


Instruction:
Write a Python 3 function that can
prepare the model for destruction.

Response:
def prepare_destruction(self):
        """Prepares the model for destruction

        """
        self._Observer__PROP_TO_METHS.clear()
        self._Observer__METH_TO_PROPS.clear()
        self._Observer__PAT_TO_METHS.clear()
        self._Observer__METH_TO_PAT.clear()
        self._Observer__PAT_METH_TO_KWARGS.clear()


Instruction:
Make a summary of the following Python 3 code
def get_col_rgba(color, transparency=None, opacity=None):
    r, g, b = color.red, color.green, color.blue
    # Convert from 0-6535 to 0-1
    r /= 65535.
    g /= 65535.
    b /= 65535.

    if transparency is not None or opacity is None:
        transparency = 0 if transparency is None else transparency  # default value
        if transparency < 0 or transparency > 1:
            raise ValueError("Transparency must be between 0 and 1")
        alpha = 1 - transparency
    else:
        if opacity < 0 or opacity > 1:
            raise ValueError("Opacity must be between 0 and 1")
        alpha = opacity

    return r, g, b, alpha

Response:
This class converts a Gdk. Color into its r g b parts and adds an alpha according to needs
AppsApps.


Instruction:
Make a summary of the following Python 3 code
def get_side_length_of_resize_handle(view, item):
    from rafcon.gui.mygaphas.items.state import StateView, NameView
    if isinstance(item, StateView):
        return item.border_width * view.get_zoom_factor() / 1.5
    elif isinstance(item, NameView):
        return item.parent.border_width * view.get_zoom_factor() / 2.5
    return 0

Response: Calculate the side length of a resize handle


Instruction:
Can you create a Python 3 function that
draws label of scoped variable This method draws the label of a scoped variable connected to a data port. This is represented by drawing a bigger label where the top part is filled and the bottom part isn't. :param context: Draw Context :param Gdk.Color color: Color to draw the label in (border and background fill color) :param name_size: Size of the name labels (scoped variable and port name) combined :param handle_pos: Position of port which label is connected to :param port_side: Side on which the label should be drawn :param port_side_size: Size of port (to have a relative size) :param draw_connection_to_port: Whether there should be a line connecting the label to the port :return: Rotation Angle (to rotate names accordingly), X-Position of name labels start point, Y-Position of name labels start point

Response:
def draw_connected_scoped_label(context, color, name_size, handle_pos, port_side, port_side_size,
                                draw_connection_to_port=False):
    """Draw label of scoped variable

    This method draws the label of a scoped variable connected to a data port. This is represented by drawing a bigger
    label where the top part is filled and the bottom part isn't.

    :param context: Draw Context
    :param Gdk.Color color: Color to draw the label in (border and background fill color)
    :param name_size: Size of the name labels (scoped variable and port name) combined
    :param handle_pos: Position of port which label is connected to
    :param port_side: Side on which the label should be drawn
    :param port_side_size: Size of port (to have a relative size)
    :param draw_connection_to_port: Whether there should be a line connecting the label to the port
    :return: Rotation Angle (to rotate names accordingly), X-Position of name labels start point, Y-Position of name
             labels start point
    """
    c = context.cairo
    c.set_line_width(port_side_size * .03)

    c.set_source_rgb(*color.to_floats())

    rot_angle = .0
    move_x = 0.
    move_y = 0.

    if port_side is SnappedSide.RIGHT:
        move_x = handle_pos.x + 2 * port_side_size
        move_y = handle_pos.y - name_size[1] / 2.

        c.move_to(move_x + name_size[0], move_y + name_size[1] / 2.)
        c.line_to(move_x + name_size[0], move_y)
        c.line_to(move_x, move_y)
        c.line_to(handle_pos.x + port_side_size, handle_pos.y)
        c.fill_preserve()
        c.stroke()
        if draw_connection_to_port:
            c.line_to(handle_pos.x + port_side_size / 2., handle_pos.y)
            c.line_to(handle_pos.x + port_side_size, handle_pos.y)
        else:
            c.move_to(handle_pos.x + port_side_size, handle_pos.y)
        c.line_to(move_x, move_y + name_size[1])
        c.line_to(move_x + name_size[0], move_y + name_size[1])
        c.line_to(move_x + name_size[0], move_y + name_size[1] / 2.)
    elif port_side is SnappedSide.BOTTOM:
        move_x = handle_pos.x + name_size[1] / 2.
        move_y = handle_pos.y + 2 * port_side_size
        rot_angle = pi / 2.

        c.move_to(move_x - name_size[1] / 2., move_y + name_size[0])
        c.line_to(move_x, move_y + name_size[0])
        c.line_to(move_x, move_y)
        c.line_to(handle_pos.x, move_y - port_side_size)
        c.fill_preserve()
        c.stroke()
        if draw_connection_to_port:
            c.line_to(handle_pos.x, handle_pos.y + port_side_size / 2.)
            c.line_to(handle_pos.x, move_y - port_side_size)
        else:
            c.move_to(handle_pos.x, move_y - port_side_size)
        c.line_to(move_x - name_size[1], move_y)
        c.line_to(move_x - name_size[1], move_y + name_size[0])
        c.line_to(move_x - name_size[1] / 2., move_y + name_size[0])
    elif port_side is SnappedSide.LEFT:
        move_x = handle_pos.x - 2 * port_side_size - name_size[0]
        move_y = handle_pos.y - name_size[1] / 2.

        c.move_to(move_x, move_y + name_size[1] / 2.)
        c.line_to(move_x, move_y)
        c.line_to(move_x + name_size[0], move_y)
        c.line_to(handle_pos.x - port_side_size, move_y + name_size[1] / 2.)
        c.fill_preserve()
        c.stroke()
        if draw_connection_to_port:
            c.line_to(handle_pos.x - port_side_size / 2., handle_pos.y)
            c.line_to(handle_pos.x - port_side_size, handle_pos.y)
        else:
            c.move_to(handle_pos.x - port_side_size, move_y + name_size[1] / 2.)
        c.line_to(move_x + name_size[0], move_y + name_size[1])
        c.line_to(move_x, move_y + name_size[1])
        c.line_to(move_x, move_y + name_size[1] / 2.)
    elif port_side is SnappedSide.TOP:
        move_x = handle_pos.x - name_size[1] / 2.
        move_y = handle_pos.y - 2 * port_side_size
        rot_angle = -pi / 2.

        c.move_to(move_x + name_size[1] / 2., move_y - name_size[0])
        c.line_to(move_x, move_y - name_size[0])
        c.line_to(move_x, move_y)
        c.line_to(handle_pos.x, move_y + port_side_size)
        c.fill_preserve()
        c.stroke()
        if draw_connection_to_port:
            c.line_to(handle_pos.x, handle_pos.y - port_side_size / 2.)
            c.line_to(handle_pos.x, move_y + port_side_size)
        else:
            c.move_to(handle_pos.x, move_y + port_side_size)
        c.line_to(move_x + name_size[1], move_y)
        c.line_to(move_x + name_size[1], move_y - name_size[0])
        c.line_to(move_x + name_size[1] / 2., move_y - name_size[0])
    c.stroke()

    return rot_angle, move_x, move_y