Instruction:
Can you generate a brief explanation for the following Python 3 code
def register_view(self, view):
        # prepare State Type Change ComboBox
        super(StateOverviewController, self).register_view(view)
        self.allowed_state_classes = self.get_allowed_state_classes(self.model.state)

        view['entry_name'].connect('focus-out-event', self.on_focus_out)
        view['entry_name'].connect('key-press-event', self.check_for_enter)
        if self.model.state.name:
            view['entry_name'].set_text(self.model.state.name)
        view['label_id_value'].set_text(self.model.state.state_id)

        l_store = Gtk.ListStore(GObject.TYPE_STRING)
        combo = Gtk.ComboBoxText()
        combo.set_name("state_type_combo")
        combo.set_focus_on_click(False)
        combo.set_model(l_store)
        combo.show_all()
        view['type_viewport'].add(combo)
        view['type_viewport'].show()

        # Prepare label for state_name -> Library states cannot be changed
        if isinstance(self.model, LibraryStateModel):
            l_store.prepend(['LIBRARY'])
            combo.set_sensitive(False)

            self.view['library_path'].set_text(self.model.state.library_path + "/" + self.model.state.library_name)
            self.view['library_path'].set_sensitive(True)
            self.view['library_path'].set_editable(False)
            view['show_content_checkbutton'].set_active(self.model.meta['gui']['show_content'] is True)
            view['show_content_checkbutton'].connect('toggled', self.on_toggle_show_content)
            # self.view['properties_widget'].remove(self.view['show_content_checkbutton'])
        else:
            self.view['properties_widget'].remove(self.view['label_library_path'])
            self.view['properties_widget'].remove(self.view['library_path'])
            self.view['properties_widget'].remove(self.view['label_show_content'])
            self.view['properties_widget'].remove(self.view['show_content_checkbutton'])
            self.view['properties_widget'].resize(2, 5)

            for state_class in self.allowed_state_classes:
                if isinstance(self.model.state, state_class):
                    l_store.prepend([state_class.__name__])
                else:
                    l_store.append([state_class.__name__])

        combo.set_active(0)
        view['type_combobox'] = combo
        view['type_combobox'].connect('changed', self.change_type)

        # Prepare "is start state check button"
        has_no_start_state_state_types = [BarrierConcurrencyState, PreemptiveConcurrencyState]
        if not self.with_is_start_state_check_box or isinstance(self.model.state, DeciderState) or \
                self.model.state.is_root_state or type(self.model.parent.state) in has_no_start_state_state_types:
            view['is_start_state_checkbutton'].destroy()
        else:
            view['is_start_state_checkbutton'].set_active(bool(self.model.is_start))
            view['is_start_state_checkbutton'].connect('toggled', self.on_toggle_is_start_state)

        if isinstance(self.model.state, DeciderState):
            combo.set_sensitive(False)

        # in case the state is inside of a library
        if self.model.state.get_next_upper_library_root_state():
            view['entry_name'].set_editable(False)
            combo.set_sensitive(False)
            view['is_start_state_checkbutton'].set_sensitive(False)
            if isinstance(self.model, LibraryStateModel):
                self.view['show_content_checkbutton'].set_sensitive(False)

Response: Called when the view was registered


Instruction:
How would you explain what the following Python 3 function does
def run(self):
        logger.debug("Starting execution of {0}{1}".format(self, " (backwards)" if self.backward_execution else ""))
        self.setup_run()

        # data to be accessed by the decider state
        child_errors = {}
        final_outcomes_dict = {}
        decider_state = self.states[UNIQUE_DECIDER_STATE_ID]

        try:
            concurrency_history_item = self.setup_forward_or_backward_execution()
            self.start_child_states(concurrency_history_item, decider_state)

            # print("bcs1")

            #######################################################
            # wait for all child threads to finish
            #######################################################
            for history_index, state in enumerate(self.states.values()):
                # skip the decider state
                if state is not decider_state:
                    self.join_state(state, history_index, concurrency_history_item)
                    self.add_state_execution_output_to_scoped_data(state.output_data, state)
                    self.update_scoped_variables_with_output_dictionary(state.output_data, state)
                    # save the errors of the child state executions for the decider state
                    if 'error' in state.output_data:
                        child_errors[state.state_id] = (state.name, state.output_data['error'])
                    final_outcomes_dict[state.state_id] = (state.name, state.final_outcome)

            # print("bcs2")

            #######################################################
            # handle backward execution case
            #######################################################
            if self.backward_execution:
                # print("bcs2.1.")
                return self.finalize_backward_execution()
            else:
                # print("bcs2.2.")
                self.backward_execution = False

            # print("bcs3")

            #######################################################
            # execute decider state
            #######################################################
            decider_state_error = self.run_decider_state(decider_state, child_errors, final_outcomes_dict)

            # print("bcs4")

            #######################################################
            # handle no transition
            #######################################################
            transition = self.get_transition_for_outcome(decider_state, decider_state.final_outcome)
            if transition is None:
                # final outcome is set here
                transition = self.handle_no_transition(decider_state)
            # if the transition is still None, then the child_state was preempted or aborted, in this case return
            decider_state.state_execution_status = StateExecutionStatus.INACTIVE

            # print("bcs5")

            if transition is None:
                self.output_data["error"] = RuntimeError("state aborted")
            else:
                if decider_state_error:
                    self.output_data["error"] = decider_state_error
                self.final_outcome = self.outcomes[transition.to_outcome]

            # print("bcs6")

            return self.finalize_concurrency_state(self.final_outcome)

        except Exception as e:
            logger.error("{0} had an internal error: {1}\n{2}".format(self, str(e), str(traceback.format_exc())))
            self.output_data["error"] = e
            self.state_execution_status = StateExecutionStatus.WAIT_FOR_NEXT_STATE
            return self.finalize(Outcome(-1, "aborted"))

Response: This method starts the main execution of the main thread.


Instruction:
Write a Python 3 script for
running the decider state.

Response:
def run_decider_state(self, decider_state, child_errors, final_outcomes_dict):
        """ Runs the decider state of the barrier concurrency state. The decider state decides on which outcome the
        barrier concurrency is left.

        :param decider_state: the decider state of the barrier concurrency state
        :param child_errors: error of the concurrent branches
        :param final_outcomes_dict: dictionary of all outcomes of the concurrent branches
        :return:
        """
        decider_state.state_execution_status = StateExecutionStatus.ACTIVE
        # forward the decider specific data
        decider_state.child_errors = child_errors
        decider_state.final_outcomes_dict = final_outcomes_dict
        # standard state execution
        decider_state.input_data = self.get_inputs_for_state(decider_state)
        decider_state.output_data = self.create_output_dictionary_for_state(decider_state)
        decider_state.start(self.execution_history, backward_execution=False)
        decider_state.join()
        decider_state_error = None
        if decider_state.final_outcome.outcome_id == -1:
            if 'error' in decider_state.output_data:
                decider_state_error = decider_state.output_data['error']
        # standard output data processing
        self.add_state_execution_output_to_scoped_data(decider_state.output_data, decider_state)
        self.update_scoped_variables_with_output_dictionary(decider_state.output_data, decider_state)
        return decider_state_error


Instruction:
Can you implement a function in Python 3 that
checks validity of a transition of BarrierConcurrencyState.

Response:
def _check_transition_validity(self, check_transition):
        """ Transition of BarrierConcurrencyStates must least fulfill the condition of a ContainerState.
        Start transitions are forbidden in the ConcurrencyState.

        :param check_transition: the transition to check for validity
        :return:
        """
        valid, message = super(BarrierConcurrencyState, self)._check_transition_validity(check_transition)
        if not valid:
            return False, message

        # Only the following transitions are allowed in barrier concurrency states:
        # - Transitions from the decider state to the parent state\n"
        # - Transitions from not-decider states to the decider state\n"
        # - Transitions from not_decider states from aborted/preempted outcomes to the
        #   aborted/preempted outcome of the parent

        from_state_id = check_transition.from_state
        to_state_id = check_transition.to_state
        from_outcome_id = check_transition.from_outcome
        to_outcome_id = check_transition.to_outcome

        if from_state_id == UNIQUE_DECIDER_STATE_ID:
            if to_state_id != self.state_id:
                return False, "Transition from the decider state must go to the parent state"
        else:
            if to_state_id != UNIQUE_DECIDER_STATE_ID:
                if from_outcome_id not in [-2, -1] or to_outcome_id not in [-2, -1]:
                    return False, "Transition from this state must go to the decider state. The only exception are " \
                                  "transition from aborted/preempted to the parent aborted/preempted outcomes"

        return True, message


Instruction:
Make a summary of the following Python 3 code
def add_state(self, state, storage_load=False):
        state_id = super(BarrierConcurrencyState, self).add_state(state)
        if not storage_load and not self.__init_running and not state.state_id == UNIQUE_DECIDER_STATE_ID:
            # the transitions must only be created for the initial add_state call and not during each load procedure
            for o_id, o in list(state.outcomes.items()):
                if not o_id == -1 and not o_id == -2:
                    self.add_transition(state.state_id, o_id, self.states[UNIQUE_DECIDER_STATE_ID].state_id, None)
        return state_id

Response: Override the add_state method to add automatic transitions for the decider_state.


Instruction:
Write a Python 3 function for
overwriting the setter of the container state base class as special handling for the decider state is needed. :param states: the dictionary of new states :raises exceptions.TypeError: if the states parameter is not of type dict

Response:
def states(self, states):
        """ Overwrite the setter of the container state base class as special handling for the decider state is needed.

        :param states: the dictionary of new states
        :raises exceptions.TypeError: if the states parameter is not of type dict
        """
        # First safely remove all existing states (recursively!), as they will be replaced
        state_ids = list(self.states.keys())
        for state_id in state_ids:
            # Do not remove decider state, if teh new list of states doesn't contain an alternative one
            if state_id == UNIQUE_DECIDER_STATE_ID and UNIQUE_DECIDER_STATE_ID not in states:
                continue
            self.remove_state(state_id)
        if states is not None:
            if not isinstance(states, dict):
                raise TypeError("states must be of type dict")
            # Ensure that the decider state is added first, as transition to this states will automatically be
            # created when adding further states
            decider_state = states.pop(UNIQUE_DECIDER_STATE_ID, None)
            if decider_state is not None:
                self.add_state(decider_state)
            for state in states.values():
                self.add_state(state)


Instruction:
Can you write a function in Python 3 where it
over-writes the parent class remove state method by checking if the user tries to delete the decider state :param state_id: the id of the state to remove :param recursive: a flag to indicate a recursive disassembling of all substates :param force: a flag to indicate forcefully deletion of all states (important of the decider state in the barrier concurrency state) :param destroy: a flag which indicates if the state should not only be disconnected from the state but also destroyed, including all its state elements :raises exceptions.AttributeError: if the state_id parameter is the decider state

Response:
def remove_state(self, state_id, recursive=True, force=False, destroy=True):
        """ Overwrite the parent class remove state method by checking if the user tries to delete the decider state

        :param state_id: the id of the state to remove
        :param recursive: a flag to indicate a recursive disassembling of all substates
        :param force: a flag to indicate forcefully deletion of all states (important of the decider state in the
                barrier concurrency state)
        :param destroy: a flag which indicates if the state should not only be disconnected from the state but also
                destroyed, including all its state elements
        :raises exceptions.AttributeError: if the state_id parameter is the decider state
        """
        if state_id == UNIQUE_DECIDER_STATE_ID and force is False:
            raise AttributeError("You are not allowed to delete the decider state.")
        else:
            return ContainerState.remove_state(self, state_id, recursive=recursive, force=force, destroy=destroy)


Instruction:
Explain what the following Python 3 code does
def get_outcome_for_state_name(self, name):
        return_value = None
        for state_id, name_outcome_tuple in self.final_outcomes_dict.items():
            if name_outcome_tuple[0] == name:
                return_value = name_outcome_tuple[1]
                break
        return return_value

Response: Returns the final outcome of the child state specified by name.


Instruction:
Can you tell what is the following Python 3 function doing
def get_outcome_for_state_id(self, state_id):
        return_value = None
        for s_id, name_outcome_tuple in self.final_outcomes_dict.items():
            if s_id == state_id:
                return_value = name_outcome_tuple[1]
                break
        return return_value

Response: Returns the final outcome of the child state specified by the state_id.


Instruction:
Implement a Python 3 function for
returning the error message of the child state specified by name.

Response:
def get_errors_for_state_name(self, name):
        """ Returns the error message of the child state specified by name.

        Note: This is utility function that is used by the programmer to make a decision based on the final outcome
        of its child states. A state is not uniquely specified by the name, but as the programmer normally does not want
        to use state-ids in his code this utility function was defined.

        :param name: The name of the state to get the error message for
        :return:
        """
        return_value = None
        for state_id, name_outcome_tuple in self.child_errors.items():
            if name_outcome_tuple[0] == name:
                return_value = name_outcome_tuple[1]
                break
        return return_value


Instruction:
Create a Python 3 function to
add a child controller to the current object.

Response:
def add_controller(self, key, controller):
        """Add child controller

        The passed controller is registered as child of self. The register_actions method of the child controller is
        called, allowing the child controller to register shortcut callbacks.

        :param key: Name of the controller (unique within self), to later access it again
        :param ExtendedController controller: Controller to be added as child
        """
        assert isinstance(controller, ExtendedController)
        controller.parent = self
        self.__child_controllers[key] = controller
        if self.__shortcut_manager is not None and controller not in self.__action_registered_controllers:
            controller.register_actions(self.__shortcut_manager)
            self.__action_registered_controllers.append(controller)


Instruction:
Can you implement a function in Python 3 that
removes the specified child controller and destroys it if it is already there.

Response:
def remove_controller(self, controller):
        """Remove child controller and destroy it

        Removes all references to the child controller and calls destroy() on the controller.

        :param str | ExtendedController controller: Either the child controller object itself or its registered name
        :return: Whether the controller was existing
        :rtype: bool
        """
        # Get name of controller
        if isinstance(controller, ExtendedController):
            # print(self.__class__.__name__, " remove ", controller.__class__.__name__)
            for key, child_controller in self.__child_controllers.items():
                if controller is child_controller:
                    break
            else:
                return False
        else:
            key = controller
        # print(self.__class__.__name__, " remove key ", key, self.__child_controllers.keys())
        if key in self.__child_controllers:
            if self.__shortcut_manager is not None:
                self.__action_registered_controllers.remove(self.__child_controllers[key])
                self.__child_controllers[key].unregister_actions(self.__shortcut_manager)
            self.__child_controllers[key].destroy()
            del self.__child_controllers[key]
            # print("removed", controller.__class__.__name__ if not isinstance(controller, str) else controller)
            return True
        # print("do not remove", controller.__class__.__name__)
        return False


Instruction:
Explain what the following Python 3 code does
def register_actions(self, shortcut_manager):
        assert isinstance(shortcut_manager, ShortcutManager)
        self.__shortcut_manager = shortcut_manager

        for controller in list(self.__child_controllers.values()):
            if controller not in self.__action_registered_controllers:
                try:
                    controller.register_actions(shortcut_manager)
                except Exception as e:
                    logger.error("Error while registering action for {0}: {1}".format(controller.__class__.__name__, e))
                self.__action_registered_controllers.append(controller)

Response: Register callback methods for triggered actions in all child controllers.


Instruction:
Can you tell what is the following Python 3 function doing
def destroy(self):
        self.disconnect_all_signals()
        controller_names = [key for key in self.__child_controllers]
        for controller_name in controller_names:
            self.remove_controller(controller_name)
        self.relieve_all_models()
        if self.parent:
            self.__parent = None
        if self._view_initialized:
            # print(self.__class__.__name__, "destroy view", self.view, self)
            self.view.get_top_widget().destroy()
            self.view = None
            self._Observer__PROP_TO_METHS.clear()  # prop name --> set of observing methods
            self._Observer__METH_TO_PROPS.clear()  # method --> set of observed properties
            self._Observer__PAT_TO_METHS.clear() # like __PROP_TO_METHS but only for pattern names (to optimize search)
            self._Observer__METH_TO_PAT.clear()  # method --> pattern
            self._Observer__PAT_METH_TO_KWARGS.clear()  # (pattern, method) --> info
            self.observe = None
        else:
            logger.warning("The controller {0} seems to be destroyed before the view was fully initialized. {1} "
                           "Check if you maybe do not call {2} or there exist most likely threading problems."
                           "".format(self.__class__.__name__, self.model, ExtendedController.register_view))

Response:
Recursively destroy all Controllers
            and all child Controllers
           .


Instruction:
How would you implement a function in Python 3 that
makes this model observable within the controller

Response:
def observe_model(self, model):
        """Make this model observable within the controller

        The method also keeps track of all observed models, in order to be able to relieve them later on.

        :param gtkmvc3.Model model: The model to be observed
        """
        self.__registered_models.add(model)
        return super(ExtendedController, self).observe_model(model)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def relieve_model(self, model):
        self.__registered_models.remove(model)
        return super(ExtendedController, self).relieve_model(model)

Response: Do no longer observe the model


Instruction:
How would you explain what the following Python 3 function does
def relieve_all_models(self):
        map(self.relieve_model, list(self.__registered_models))
        self.__registered_models.clear()

Response: Relieve all registered models


Instruction:
Can you generate a brief explanation for the following Python 3 code
def check_default_value(self, default_value, data_type=None):
        if data_type is None:
            data_type = self.data_type

        if default_value is not None:
            # If the default value is passed as string, we have to convert it to the data type
            if isinstance(default_value, string_types):
                if len(default_value) > 1 and default_value[0] == '$':
                    return default_value
                if default_value == "None":
                    return None

                default_value = type_helpers.convert_string_value_to_type_value(default_value, data_type)
                if default_value is None:
                    raise AttributeError("Could not convert default value '{0}' to data type '{1}'.".format(
                        default_value, data_type))
            else:
                if not isinstance(default_value, self.data_type):
                    if self._no_type_error_exceptions:
                        logger.warning("Handed default value '{0}' is of type '{1}' but data port data type is {2} {3}."
                                       "".format(default_value, type(default_value), data_type, self))
                    else:
                        raise TypeError("Handed default value '{0}' is of type '{1}' but data port data type is {2}"
                                        "{3} of {4}.".format(default_value, type(default_value), data_type,
                                                             self,
                                                             self.parent.get_path() if self.parent is not None else ""))

        return default_value

Response: Checks whether the passed default value suits to the passed data type.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def open_folder_cmd_line(query, default_path=None):
    user_input = input(query + ': ')
    if len(user_input) == 0:
        user_input = default_path
    if not user_input or not os.path.isdir(user_input):
        return None
    return user_input

Response: Queries the user for a specific folder path to be opened.


Instruction:
Write a Python 3 function that can
query the user for a specific folder path to be created

Response:
def create_folder_cmd_line(query, default_name=None, default_path=None):
    """Queries the user for a path to be created

    :param str query: Query that asks the user for a specific folder path  to be created
    :param str default_name: Default name of the folder to be created
    :param str default_path: Path in which the folder is created if the user doesn't specify a path
    :return: Input path from the user or `default_path` if nothing is specified or None if directory could ne be created
    :rtype: str
    """
    default = None
    if default_name and default_path:
        default = os.path.join(default_path, default_name)
    user_input = input(query + ' [default {}]: '.format(default))
    if len(user_input) == 0:
        user_input = default

    if not user_input:
        return None
    if not os.path.isdir(user_input):
        try:
            os.makedirs(user_input)
        except OSError:
            return None
    return user_input


Instruction:
Create a Python 3 function for
querying the user for a path or file to be saved into the folder or file.

Response:
def save_folder_cmd_line(query, default_name=None, default_path=None):
    """Queries the user for a path or file to be saved into

    The folder or file has not to be created already and will not be created by this function. The parent directory
    of folder and file has to exist otherwise the function will return None.

    :param str query: Query that asks the user for a specific folder/file path to be created
    :param str default_name: Default name of the folder to be created
    :param str default_path: Path in which the folder is created if the user doesn't specify a path
    :return: Input path from the user or `default_path` if nothing is specified and None if directory does not exist
    :rtype: str
    """
    default = None
    if default_name and default_path:
        default = os.path.join(default_path, default_name)
    user_input = input(query + ' [default {}]: '.format(default))
    if len(user_input) == 0:
        user_input = default

    if not user_input or not os.path.isdir(os.path.dirname(user_input)):
        return None
    return user_input


Instruction:
Create a Python 3 function to
call when the View was registered

Response:
def register_view(self, view):
        """Called when the View was registered
        """
        super(StateTransitionsListController, self).register_view(view)

        def cell_text(column, cell_renderer, model, iter, data):
            t_id = model.get_value(iter, self.ID_STORAGE_ID)
            in_external = 'external' if model.get_value(iter, self.IS_EXTERNAL_STORAGE_ID) else 'internal'
            # print(t_id, in_external, self.combo[in_external])
            if column.get_title() == 'Source State':
                cell_renderer.set_property("model", self.combo[in_external][t_id]['from_state'])
                cell_renderer.set_property("text-column", 0)
                cell_renderer.set_property("has-entry", False)
            elif column.get_title() == 'Source Outcome':
                cell_renderer.set_property("model", self.combo[in_external][t_id]['from_outcome'])
                cell_renderer.set_property("text-column", 0)
                cell_renderer.set_property("has-entry", False)
            elif column.get_title() == 'Target State':
                cell_renderer.set_property("model", self.combo[in_external][t_id]['to_state'])
                cell_renderer.set_property("text-column", 0)
                cell_renderer.set_property("has-entry", False)
            elif column.get_title() == 'Target Outcome':
                cell_renderer.set_property("model", self.combo[in_external][t_id]['to_outcome'])
                cell_renderer.set_property("text-column", 0)
                cell_renderer.set_property("has-entry", False)
            else:
                logger.warning("Column has no cell_data_func %s %s" % (column.get_name(), column.get_title()))

        view['from_state_col'].set_cell_data_func(view['from_state_combo'], cell_text)
        view['to_state_col'].set_cell_data_func(view['to_state_combo'], cell_text)
        view['from_outcome_col'].set_cell_data_func(view['from_outcome_combo'], cell_text)
        view['to_outcome_col'].set_cell_data_func(view['to_outcome_combo'], cell_text)

        if self.model.state.get_next_upper_library_root_state():
            view['from_state_combo'].set_property("editable", False)
            view['from_outcome_combo'].set_property("editable", False)
            view['to_state_combo'].set_property("editable", False)
            view['to_outcome_combo'].set_property("editable", False)
        else:
            self.connect_signal(view['from_state_combo'], "edited", self.on_combo_changed_from_state)
            self.connect_signal(view['from_outcome_combo'], "edited", self.on_combo_changed_from_outcome)
            self.connect_signal(view['to_state_combo'], "edited", self.on_combo_changed_to_state)
            self.connect_signal(view['to_outcome_combo'], "edited", self.on_combo_changed_to_outcome)

        view.tree_view.connect("grab-focus", self.on_focus)
        self.update(initiator='"register view"')


Instruction:
Here you have a function in Python 3, explain what it does
def remove_core_element(self, model):
        assert model.transition.parent is self.model.state or model.transition.parent is self.model.parent.state
        gui_helper_state_machine.delete_core_element_of_model(model)

Response: Removes respective core element of handed transition model


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_possible_combos_for_transition(trans, model, self_model, is_external=False):
        from_state_combo = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        from_outcome_combo = Gtk.ListStore(GObject.TYPE_STRING)
        to_state_combo = Gtk.ListStore(GObject.TYPE_STRING)
        to_outcome_combo = Gtk.ListStore(GObject.TYPE_STRING)

        trans_dict = model.state.transitions

        # get from state
        if trans is None:
            from_state = None
        elif trans.from_state is not None:
            from_state = model.state.states[trans.from_state]
        else:
            from_state = model.state if is_external else self_model.state

        # collect all free from-outcome-combo and from_state which are still valid -> filter all outcome already in use
        free_from_outcomes_dict = {}
        for state in model.state.states.values():
            from_o_combo = state.outcomes.values()
            # print([o.outcome_id for o in from_o_combo], state_model.state.state_id)
            for transition in trans_dict.values():
                # print(transition, [[o.outcome_id == transition.from_outcome, transition.from_state == state_model.state.state_id] for o in from_o_combo])
                from_o_combo = [o for o in from_o_combo if not (o.outcome_id == transition.from_outcome and
                                                     transition.from_state == state.state_id)]
                # print([o.outcome_id for o in from_o_combo])
            if len(from_o_combo) > 0:
                free_from_outcomes_dict[state.state_id] = from_o_combo
        # check if parent has start_state
        if model.state.start_state_id is None:
            free_from_outcomes_dict[model.state.state_id] = [None]

        # for from-state-combo use all states with free outcomes and from_state
        combined_states = [model.state] if is_external else [self_model.state]
        combined_states.extend(model.state.states.values())
        free_from_states = [state for state in combined_states if state.state_id in free_from_outcomes_dict]

        if trans is None:
            return None, None, None, None, free_from_states, free_from_outcomes_dict

        def append_from_state_combo(possible_state):
            if possible_state.state_id == self_model.state.state_id:
                from_state_combo.append(['self.' + possible_state.state_id, possible_state.state_id])
            elif is_external and from_state.state_id == model.state.state_id:
                from_state_combo.append(['parent.' + possible_state.state_id, possible_state.state_id])
            else:
                from_state_combo.append([possible_state.name + '.' + possible_state.state_id, possible_state.state_id])

        append_from_state_combo(from_state)
        for state in free_from_states:
            if from_state is not state:
                append_from_state_combo(state)

        # for from-outcome-combo collect all combos for actual transition
        # -> actual outcome + free outcomes of actual from_state.state_id
        if trans is not None:
            if trans.from_outcome is None:
                from_outcome_combo.append(["None"])
            else:
                outcome = from_state.outcomes[trans.from_outcome]
                from_outcome_combo.append([outcome.name + "." + str(outcome.outcome_id)])
            for outcome in free_from_outcomes_dict.get(from_state.state_id, []):
                if outcome is None:
                    from_outcome_combo.append(["None"])
                else:
                    from_outcome_combo.append([outcome.name + "." + str(outcome.outcome_id)])

        # get to state
        if trans.to_state == model.state.state_id:
            to_state = model.state if is_external else self_model.state
        else:
            to_state = model.state.states[trans.to_state]

        # for to-state-combo filter from_state -> first actual to_state + other optional states
        def generate_to_state_combo(possible_state):
            if possible_state.state_id == self_model.state.state_id:
                to_state_combo.append(["self." + possible_state.state_id])
            elif is_external and possible_state.state_id == model.state.state_id:
                to_state_combo.append(['parent.' + possible_state.state_id])
            else:
                to_state_combo.append([possible_state.name + '.' + possible_state.state_id])

        to_states = [model.state] if is_external else [self_model.state]
        to_states.extend(model.state.states.values())
        generate_to_state_combo(to_state)
        for state in to_states:
            if not to_state.state_id == state.state_id:
                generate_to_state_combo(state)

        # for to-outcome-combo use parent combos -> first actual outcome + other outcome
        def append_to_outcome_combo(possible_outcome):
            if is_external:
                to_outcome_combo.append(['parent.' + possible_outcome.name + "." + str(possible_outcome.outcome_id)])
            else:
                to_outcome_combo.append(['self.' + possible_outcome.name + "." + str(possible_outcome.outcome_id)])

        if trans.to_outcome is not None:
            append_to_outcome_combo(model.state.outcomes[trans.to_outcome])
        for outcome in model.state.outcomes.values():
            if not (trans.to_outcome == outcome.outcome_id and trans.to_state == model.state.state_id):
                append_to_outcome_combo(outcome)

        return from_state_combo, from_outcome_combo, to_state_combo, to_outcome_combo, free_from_states, free_from_outcomes_dict

Response: This function returns a list of possible combos for a transition and its respective state.


Instruction:
Here you have a function in Python 3, explain what it does
def _update_internal_data_base(self):

        model = self.model

        # print("clean data base")

        ### FOR COMBOS
        # internal transitions
        # - take all internal states
        # - take all not used internal outcomes of this states

        # external transitions
        # - take all external states
        # - take all external outcomes
        # - take all not used own outcomes

        ### LINKING
        # internal  -> transition_id -> from_state = outcome combos
        #           -> ...
        # external -> state -> outcome combos
        self.combo['internal'] = {}
        self.combo['external'] = {}
        self.combo['free_from_states'] = {}
        self.combo['free_from_outcomes_dict'] = {}
        self.combo['free_ext_from_outcomes_dict'] = {}
        self.combo['free_ext_from_outcomes_dict'] = {}

        if isinstance(model, ContainerStateModel):
            # check for internal combos
            for transition_id, transition in model.state.transitions.items():
                self.combo['internal'][transition_id] = {}

                [from_state_combo, from_outcome_combo,
                 to_state_combo, to_outcome_combo,
                 free_from_states, free_from_outcomes_dict] = \
                    self.get_possible_combos_for_transition(transition, self.model, self.model)

                self.combo['internal'][transition_id]['from_state'] = from_state_combo
                self.combo['internal'][transition_id]['from_outcome'] = from_outcome_combo
                self.combo['internal'][transition_id]['to_state'] = to_state_combo
                self.combo['internal'][transition_id]['to_outcome'] = to_outcome_combo

                self.combo['free_from_states'] = free_from_states
                self.combo['free_from_outcomes_dict'] = free_from_outcomes_dict

            if not model.state.transitions:
                [x, y, z, v, free_from_states, free_from_outcomes_dict] = \
                    self.get_possible_combos_for_transition(None, self.model, self.model)
                self.combo['free_from_states'] = free_from_states
                self.combo['free_from_outcomes_dict'] = free_from_outcomes_dict
        # TODO check why the can happen should not be handed always the LibraryStateModel
        if not (self.model.state.is_root_state or self.model.state.is_root_state_of_library):
            # check for external combos
            for transition_id, transition in model.parent.state.transitions.items():
                if transition.from_state == model.state.state_id or transition.to_state == model.state.state_id:
                    self.combo['external'][transition_id] = {}

                    [from_state_combo, from_outcome_combo,
                     to_state_combo, to_outcome_combo,
                     free_from_states, free_from_outcomes_dict] = \
                        self.get_possible_combos_for_transition(transition, self.model.parent, self.model, True)

                    self.combo['external'][transition_id]['from_state'] = from_state_combo
                    self.combo['external'][transition_id]['from_outcome'] = from_outcome_combo
                    self.combo['external'][transition_id]['to_state'] = to_state_combo
                    self.combo['external'][transition_id]['to_outcome'] = to_outcome_combo

                    self.combo['free_ext_from_states'] = free_from_states
                    self.combo['free_ext_from_outcomes_dict'] = free_from_outcomes_dict

            if not model.parent.state.transitions:
                [x, y, z, v, free_from_states, free_from_outcomes_dict] = \
                    self.get_possible_combos_for_transition(None, self.model.parent, self.model, True)
                self.combo['free_ext_from_states'] = free_from_states
                self.combo['free_ext_from_outcomes_dict'] = free_from_outcomes_dict

Response: Updates internal data base based on the current state and model.


Instruction:
Write a Python 3 script for
updating the TreeStore according internal combo knowledge gained by the internal data base function call.

Response:
def _update_tree_store(self):
        """ Updates TreeStore of the Gtk.ListView according internal combo knowledge gained by
        _update_internal_data_base function call.
        """

        self.list_store.clear()
        if self.view_dict['transitions_internal'] and isinstance(self.model, ContainerStateModel) and \
                len(self.model.state.transitions) > 0:
            for transition_id in self.combo['internal'].keys():
                # print("TRANSITION_ID: ", transition_id, self.model.state.transitions)
                t = self.model.state.transitions[transition_id]

                if t.from_state is not None:
                    from_state = self.model.state.states[t.from_state]
                    from_state_label = from_state.name
                    from_outcome_label = from_state.outcomes[t.from_outcome].name
                else:
                    from_state_label = "self (" + self.model.state.name + ")"
                    from_outcome_label = ""

                if t.to_state is None:
                    to_state_label = "self (" + self.model.state.name + ")"
                    to_outcome = None if t.to_outcome is None else self.model.state.outcomes[t.to_outcome]
                    to_outcome_label = "None" if to_outcome is None else to_outcome.name
                else:
                    # print(t.to_state, self.model.states)
                    if t.to_state == self.model.state.state_id:
                        to_state_label = "self (" + self.model.state.name + ")"
                        to_outcome_label = self.model.state.outcomes[t.to_outcome].name
                    else:
                        to_state_label = self.model.state.states[t.to_state].name
                        to_outcome_label = None

                self.list_store.append([transition_id,  # id
                                        from_state_label,  # from-state
                                        from_outcome_label,  # from-outcome
                                        to_state_label,  # to-state
                                        to_outcome_label,  # to-outcome
                                        False,  # is_external
                                        t,
                                        self.model.state,
                                        True,
                                        self.model.get_transition_m(transition_id)])

        if self.view_dict['transitions_external'] and self.model.parent and \
                len(self.model.parent.state.transitions) > 0:
            for transition_id in self.combo['external'].keys():
                # print("TRANSITION_ID: ", transition_id, self.model.parent.state.transitions)
                try:
                    t = self.model.parent.state.transitions[transition_id]
                    # logger.info(str(t))
                    from_state = None
                    if t.from_state is not None:
                        from_state = self.model.parent.states[t.from_state].state

                    if from_state is None:
                        from_state_label = "parent (" + self.model.state.parent.name + ")"
                        from_outcome_label = ""
                    elif from_state.state_id == self.model.state.state_id:
                        from_state_label = "self (" + from_state.name + ")"
                        from_outcome_label = from_state.outcomes[t.from_outcome].name
                    else:
                        from_state_label = from_state.name
                        from_outcome_label = from_state.outcomes[t.from_outcome].name

                    if t.to_state == self.model.parent.state.state_id:
                        to_state_label = 'parent (' + self.model.parent.state.name + ")"
                        to_outcome_label = self.model.parent.state.outcomes[t.to_outcome].name
                    else:
                        if t.to_state == self.model.state.state_id:
                            to_state_label = "self (" + self.model.state.name + ")"
                        else:
                            to_state_label = self.model.parent.state.states[t.to_state].name
                        to_outcome_label = None

                    self.list_store.append([transition_id,  # id
                                            from_state_label,  # from-state
                                            from_outcome_label,  # from-outcome
                                            to_state_label,  # to-state
                                            to_outcome_label,  # to-outcome
                                            True,  # is_external
                                            t,
                                            self.model.state,
                                            True,
                                            self.model.parent.get_transition_m(transition_id)])
                except Exception as e:
                    logger.warning("There was a problem while updating the data-flow widget TreeStore. {0}".format(e))


Instruction:
Explain what the following Python 3 code does
def register_actions(self, shortcut_manager):
        shortcut_manager.add_callback_for_action("delete", self.trans_list_ctrl.remove_action_callback)
        shortcut_manager.add_callback_for_action("add", self.trans_list_ctrl.add_action_callback)

Response: Register callback methods for triggered actions


Instruction:
How would you implement a function in Python 3 that
moves the dirt_lock file to the state machine folder

Response:
def move_dirty_lock_file(dirty_lock_file, sm_path):
    """ Move the dirt_lock file to the sm_path and thereby is not found by auto recovery of backup anymore """
    if dirty_lock_file is not None \
            and not dirty_lock_file == os.path.join(sm_path, dirty_lock_file.split(os.sep)[-1]):
        logger.debug("Move dirty lock from root tmp folder {0} to state machine folder {1}"
                     "".format(dirty_lock_file, os.path.join(sm_path, dirty_lock_file.split(os.sep)[-1])))
        os.rename(dirty_lock_file, os.path.join(sm_path, dirty_lock_file.split(os.sep)[-1]))


Instruction:
Can you generate the documentation for the following Python 3 function
def write_backup_meta_data(self):
        auto_backup_meta_file = os.path.join(self._tmp_storage_path, FILE_NAME_AUTO_BACKUP)
        storage.storage_utils.write_dict_to_json(self.meta, auto_backup_meta_file)

Response: Write the auto backup meta data into the current tmp - storage path


Instruction:
Can you write a function in Python 3 where it
updates the auto backup meta data with the internal recovery information

Response:
def update_last_backup_meta_data(self):
        """Update the auto backup meta data with internal recovery information"""
        self.meta['last_backup']['time'] = get_time_string_for_float(self.last_backup_time)
        self.meta['last_backup']['file_system_path'] = self._tmp_storage_path
        self.meta['last_backup']['marked_dirty'] = self.state_machine_model.state_machine.marked_dirty


Instruction:
How would you explain what the following Python 3 function does
def update_last_sm_origin_meta_data(self):
        # TODO finally maybe remove this when all backup features are integrated into one backup-structure
        # data also used e.g. to backup tabs
        self.meta['last_saved']['time'] = self.state_machine_model.state_machine.last_update
        self.meta['last_saved']['file_system_path'] = self.state_machine_model.state_machine.file_system_path

Response: Update the auto backup meta data with information of the state machine origin


Instruction:
Explain what the following Python 3 code does
def _check_for_dyn_timed_auto_backup(self):
        current_time = time.time()
        self.timer_request_lock.acquire()
        # sm = self.state_machine_model.state_machine
        # TODO check for self._timer_request_time is None to avoid and reset auto-backup in case and fix it better
        if self._timer_request_time is None:
            # logger.warning("timer_request is None")
            return self.timer_request_lock.release()
        if self.timed_temp_storage_interval < current_time - self._timer_request_time:
            # logger.info("{0} Perform timed auto-backup of state-machine {1}.".format(time.time(),
            #                                                                          sm.state_machine_id))
            self.check_for_auto_backup(force=True)
        else:
            duration_to_wait = self.timed_temp_storage_interval - (current_time - self._timer_request_time)
            hard_limit_duration_to_wait = self.force_temp_storage_interval - (current_time - self.last_backup_time)
            hard_limit_active = hard_limit_duration_to_wait < duration_to_wait
            # logger.info('{2} restart_thread {0} time to go {1}, hard limit {3}'.format(sm.state_machine_id,
            #                                                                            duration_to_wait, time.time(),
            #                                                                            hard_limit_active))
            if hard_limit_active:
                self.set_timed_thread(hard_limit_duration_to_wait, self.check_for_auto_backup, True)
            else:
                self.set_timed_thread(duration_to_wait, self._check_for_dyn_timed_auto_backup)
        self.timer_request_lock.release()

Response: This method checks if the state - machine is already backupd and if so restarts the thread if it is not already backupd.


Instruction:
Explain what the following Python 3 code does
def check_for_auto_backup(self, force=False):
        if not self.timed_temp_storage_enabled:
            return

        sm = self.state_machine_model.state_machine
        current_time = time.time()

        if not self.only_fix_interval and not self.marked_dirty:
            # logger.info("adjust last_backup_time " + str(sm.state_machine_id))
            self.last_backup_time = current_time         # used as 'last-modification-not-backup-ed' time

        is_not_timed_or_reached_time_to_force = \
            current_time - self.last_backup_time > self.force_temp_storage_interval or self.only_fix_interval

        if (sm.marked_dirty and is_not_timed_or_reached_time_to_force) or force:
            if not self.only_fix_interval or self.marked_dirty:
                thread = threading.Thread(target=self.perform_temp_storage)
                thread.start()
                # self.last_backup_time = current_time  # used as 'last-backup' time
            if self.only_fix_interval:
                self.set_timed_thread(self.force_temp_storage_interval, self.check_for_auto_backup)
        else:
            if not self.only_fix_interval:
                self.timer_request_lock.acquire()
                if self._timer_request_time is None:
                    # logger.info('{0} start_thread {1}'.format(current_time, sm.state_machine_id))
                    self._timer_request_time = current_time
                    self.set_timed_thread(self.timed_temp_storage_interval, self._check_for_dyn_timed_auto_backup)
                else:
                    # logger.info('{0} update_thread {1}'.format(current_time, sm.state_machine_id))
                    self._timer_request_time = current_time
                self.timer_request_lock.release()
            else:
                self.set_timed_thread(self.force_temp_storage_interval, self.check_for_auto_backup)

Response:
Private method to check for possible auto backup of the state - machine according duration till
       .


Instruction:
Make a summary of the following Python 3 code
def on_drag_data_get(self, widget, context, data, info, time):
        import rafcon.gui.helpers.state_machine as gui_helper_state_machine
        state = self._get_state()
        gui_helper_state_machine.add_state_by_drag_and_drop(state, data)

Response: dragged state is inserted and its state_id sent to the receiver


Instruction:
Make a summary of the following Python 3 code
def on_mouse_click(self, widget, event):
        import rafcon.gui.helpers.state_machine as gui_helper_state_machine
        if self.view.get_path_at_pos(int(event.x), int(event.y)) is not None \
                and len(self.view.get_selected_items()) > 0:
            return gui_helper_state_machine.insert_state_into_selected_state(self._get_state(), False)

Response: state insertion on mouse click


Instruction:
Here you have a function in Python 3, explain what it does
def _get_state(self):

        selected = self.view.get_selected_items()
        if not selected:
            return
        shorthand, state_class = self.view.states[selected[0][0]]
        return state_class()

Response: get state instance which was clicked on


Instruction:
Create a Python 3 function for
returning a string that contains all elements of a notification info - dictionary of gtkmvc3 or Signal and all levels of calls defined by kwargs.

Response:
def get_nice_info_dict_string(self, info, level='\t', overview=None):
        """ Inserts all elements of a notification info-dictionary of gtkmvc3 or a Signal into one string and indicates
        levels of calls defined by 'kwargs'. Additionally, the elements get structured into a dict that holds all levels
        of the general notification key-value pairs in faster accessible lists. The dictionary has the element 'type'
        and the general elements {'model': [], 'prop_name': [], 'instance': [], 'method_name': [], 'args': [],
        'kwargs': []}) plus specific elements according the type. Type is always one of the following list
        ['before', 'after', 'signal'].
        """
        def get_nice_meta_signal_msg_tuple_string(meta_signal_msg_tuple, level, overview):
            meta_signal_dict = {}
            # origin
            s = "\n{0}origin={1}".format(level + "\t", meta_signal_msg_tuple.origin)
            meta_signal_dict['origin'] = meta_signal_msg_tuple.origin
            # change
            s += "\n{0}change={1}".format(level + "\t", meta_signal_msg_tuple.change)
            meta_signal_dict['change'] = meta_signal_msg_tuple.change
            # affects_children
            s += "\n{0}affects_children={1}".format(level + "\t", meta_signal_msg_tuple.affects_children)
            meta_signal_dict['affects_children'] = meta_signal_msg_tuple.affects_children
            overview['signal'].append(meta_signal_dict)

            # notification (tuple)
            notification_dict = {}
            meta_signal_dict['notification'] = notification_dict
            if meta_signal_msg_tuple.notification is None:
                s += "\n{0}notification={1}".format(level + "\t", meta_signal_msg_tuple.notification)
            else:
                s += "\n{0}notification=Notification(".format(level + "\t")
                # model
                notification_dict['model'] = meta_signal_msg_tuple.notification.model
                s += "\n{0}model={1}".format(level + "\t\t", meta_signal_msg_tuple.notification.model)
                # prop_name
                notification_dict['prop_name'] = meta_signal_msg_tuple.notification.prop_name
                s += "\n{0}prop_name={1}".format(level + "\t\t", meta_signal_msg_tuple.notification.prop_name)
                # info
                notification_dict['info'] = meta_signal_msg_tuple.notification.info
                overview['kwargs'].append(meta_signal_msg_tuple.notification.info)
                s += "\n{0}info=\n{1}{0}\n".format(level + "\t\t",
                                               self.get_nice_info_dict_string(meta_signal_msg_tuple.notification.info,
                                                                              level+'\t\t\t',
                                                                              overview))
            return s

        def get_nice_action_signal_msg_tuple_string(meta_signal_msg_tuple, level, overview):
            meta_signal_dict = {}
            # after
            s = "\n{0}after={1}".format(level + "\t", meta_signal_msg_tuple.after)
            meta_signal_dict['after'] = meta_signal_msg_tuple.after
            # action
            s += "\n{0}action={1}".format(level + "\t", meta_signal_msg_tuple.action)
            meta_signal_dict['action'] = meta_signal_msg_tuple.action
            # origin
            s += "\n{0}origin={1}".format(level + "\t", meta_signal_msg_tuple.origin)
            meta_signal_dict['origin'] = meta_signal_msg_tuple.origin
            # origin
            s += "\n{0}action_parent_m={1}".format(level + "\t", meta_signal_msg_tuple.action_parent_m)
            meta_signal_dict['action_parent_m'] = meta_signal_msg_tuple.origin
            # change
            s += "\n{0}affected_models={1}".format(level + "\t", meta_signal_msg_tuple.affected_models)
            meta_signal_dict['affected_models'] = meta_signal_msg_tuple.affected_models
            if meta_signal_msg_tuple.after:
                s += "\n{0}result={1}".format(level + "\t", meta_signal_msg_tuple.result)
                meta_signal_dict['result'] = meta_signal_msg_tuple.result

            return s

        overview_was_none = False
        if overview is None:
            overview_was_none = True
            overview = dict({'model': [], 'prop_name': [], 'instance': [], 'method_name': [], 'args': [], 'kwargs': []})
            overview['others'] = []
            overview['info'] = []
            if 'before' in info:
                overview['type'] = 'before'
            elif 'after' in info:
                overview['type'] = 'after'
                overview['result'] = []
            else:  # 'signal' in info:
                overview['type'] = 'signal'
                overview['signal'] = []

        if ('after' in info or 'before' in info or 'signal' in info) and 'model' in info:
            if 'before' in info:
                s = "{0}'before': {1}".format(level, info['before'])
            elif 'after' in info:
                s = "{0}'after': {1}".format(level, info['after'])
            else:
                s = "{0}'signal': {1}".format(level, info['signal'])
        else:
            return str(info)
        overview['info'].append(info)
        # model
        s += "\n{0}'model': {1}".format(level, info['model'])
        overview['model'].append(info['model'])
        # prop_name
        s += "\n{0}'prop_name': {1}".format(level, info['prop_name'])
        overview['prop_name'].append(info['prop_name'])
        if not overview['type'] == 'signal':
            # instance
            s += "\n{0}'instance': {1}".format(level, info['instance'])
            overview['instance'].append(info['instance'])
            # method_name
            s += "\n{0}'method_name': {1}".format(level, info['method_name'])
            overview['method_name'].append(info['method_name'])
            # args
            s += "\n{0}'args': {1}".format(level, info['args'])
            overview['args'].append(info['args'])

            overview['kwargs'].append(info['kwargs'])
            if overview['type'] == 'after':
                overview['result'].append(info['result'])
            # kwargs
            s += "\n{0}'kwargs': {1}".format(level, self.get_nice_info_dict_string(info['kwargs'],
                                                                                level + "\t",
                                                                                overview))
            if overview['type'] == 'after':
                s += "\n{0}'result': {1}".format(level, info['result'])
            # additional elements not created by gtkmvc3 or common function calls
            overview['others'].append({})
            for key, value in info.items():
                if key in ['before', 'after', 'model', 'prop_name', 'instance', 'method_name', 'args', 'kwargs', 'result']:
                    pass
                else:
                    s += "\n{0}'{2}': {1}".format(level, info[key], key)
                    overview['others'][len(overview['others'])-1][key] = info[key]
        else:
            overview['kwargs'].append({})
            # print(info)
            # print(info['arg'])
            if isinstance(info['arg'], MetaSignalMsg):
                overview['signal'].append(info['arg'])
                s += "\n{0}'arg': MetaSignalMsg({1}".format(level,
                                                            get_nice_meta_signal_msg_tuple_string(info['arg'],
                                                                                level,
                                                                                overview))
            elif isinstance(info['arg'], ActionSignalMsg):
                overview['instance'].append(info['arg'].action_parent_m.core_element)
                overview['method_name'].append(info['arg'].action)
                overview['signal'].append(info['arg'])
                overview['kwargs'].append(info['arg'].kwargs)
                # TODO check again this stuff
                args = [info['arg'].action_parent_m.core_element, ]
                args.extend(info['arg'].kwargs.values())
                overview['args'].append(args)
                s += "\n{0}'arg': ActionSignalMsg({1}".format(level,
                                                              get_nice_action_signal_msg_tuple_string(info['arg'],
                                                                                level,
                                                                                overview))
            else:
                raise str(info)

        if overview_was_none:
            return s, overview
        else:
            return s


Instruction:
How would you explain what the following Python 3 function does
def register_view(self, view):
        super(StateOutcomesListController, self).register_view(view)
        if isinstance(view, StateOutcomesTreeView):
            self.connect_signal(view['to_state_combo'], "edited", self.on_to_state_edited)
            self.connect_signal(view['to_outcome_combo'], "edited", self.on_to_outcome_edited)

        if isinstance(self.model.state, LibraryState) or self.model.state.get_next_upper_library_root_state():
            view['id_cell'].set_property('editable', False)
            view['name_cell'].set_property('editable', False)

        self._apply_value_on_edited_and_focus_out(view['name_cell'], self.apply_new_outcome_name)

        self.update(initiator='"register view"')

Response: Called when the view was registered


Instruction:
Can you write a function in Python 3 where it
applies the newly entered outcome name it is was changed

Response:
def apply_new_outcome_name(self, path, new_name):
        """Apply the newly entered outcome name it is was changed

        :param str path: The path string of the renderer
        :param str new_name: Newly entered outcome name
        """
        # Don't do anything if outcome name didn't change
        if new_name == self.list_store[path][self.NAME_STORAGE_ID]:
            return

        outcome = self.list_store[path][self.CORE_STORAGE_ID]
        try:
            outcome.name = new_name
            logger.debug("Outcome name changed to '{0}'".format(outcome.name))
        except (ValueError, TypeError) as e:
            logger.warning("The name of the outcome could not be changed: {0}".format(e))
        self.list_store[path][self.NAME_STORAGE_ID] = outcome.name


Instruction:
Here you have a function in Python 3, explain what it does
def on_to_state_edited(self, renderer, path, new_state_identifier):
        def do_self_transition_check(t_id, new_state_identifier):
            # add self transition meta data
            if 'self' in new_state_identifier.split('.'):
                insert_self_transition_meta_data(self.model, t_id, 'outcomes_widget', combined_action=True)

        outcome_id = self.list_store[path][self.ID_STORAGE_ID]
        if outcome_id in self.dict_to_other_state or outcome_id in self.dict_to_other_outcome:
            transition_parent_state = self.model.parent.state
            if outcome_id in self.dict_to_other_state:
                t_id = self.dict_to_other_state[outcome_id][2]
            else:
                t_id = self.dict_to_other_outcome[outcome_id][2]
            if new_state_identifier is not None:
                to_state_id = new_state_identifier.split('.')[1]
                if not transition_parent_state.transitions[t_id].to_state == to_state_id:
                    try:
                        transition_parent_state.transitions[t_id].modify_target(to_state=to_state_id)
                        do_self_transition_check(t_id, new_state_identifier)
                    except ValueError as e:
                        logger.warning("The target of transition couldn't be modified: {0}".format(e))
            else:
                try:
                    transition_parent_state.remove_transition(t_id)
                except AttributeError as e:
                    logger.warning("The transition couldn't be removed: {0}".format(e))
        else:  # there is no transition till now
            if new_state_identifier is not None and not self.model.state.is_root_state:
                transition_parent_state = self.model.parent.state
                to_state_id = new_state_identifier.split('.')[1]
                try:
                    t_id = transition_parent_state.add_transition(from_state_id=self.model.state.state_id,
                                                                  from_outcome=outcome_id,
                                                                  to_state_id=to_state_id,
                                                                  to_outcome=None, transition_id=None)
                    do_self_transition_check(t_id, new_state_identifier)
                except (ValueError, TypeError) as e:
                    logger.warning("The transition couldn't be added: {0}".format(e))
                    return
            else:
                logger.debug("outcome-editor got None in to_state-combo-change no transition is added")

Response: Connects the outcome with a transition to the newly set state


Instruction:
Implement a function in Python 3 to
connect the outcome with a transition to the newly set outcome

Response:
def on_to_outcome_edited(self, renderer, path, new_outcome_identifier):
        """Connects the outcome with a transition to the newly set outcome

        :param Gtk.CellRendererText renderer: The cell renderer that was edited
        :param str path: The path string of the renderer
        :param str new_outcome_identifier: An identifier for the new outcome that was selected
        """
        if self.model.parent is None:
            return
        outcome_id = self.list_store[path][self.ID_STORAGE_ID]
        transition_parent_state = self.model.parent.state
        if outcome_id in self.dict_to_other_state or outcome_id in self.dict_to_other_outcome:
            if outcome_id in self.dict_to_other_state:
                t_id = self.dict_to_other_state[outcome_id][2]
            else:
                t_id = self.dict_to_other_outcome[outcome_id][2]
            if new_outcome_identifier is not None:
                new_to_outcome_id = int(new_outcome_identifier.split('.')[2])
                if not transition_parent_state.transitions[t_id].to_outcome == new_to_outcome_id:
                    to_state_id = self.model.parent.state.state_id
                    try:
                        transition_parent_state.transitions[t_id].modify_target(to_state=to_state_id,
                                                                                to_outcome=new_to_outcome_id)
                    except ValueError as e:
                        logger.warning("The target of transition couldn't be modified: {0}".format(e))
            else:

                transition_parent_state.remove_transition(t_id)
        else:  # there is no transition till now
            if new_outcome_identifier is not None:
                to_outcome = int(new_outcome_identifier.split('.')[2])

                try:
                    self.model.parent.state.add_transition(from_state_id=self.model.state.state_id,
                                                           from_outcome=outcome_id,
                                                           to_state_id=self.model.parent.state.state_id,
                                                           to_outcome=to_outcome, transition_id=None)
                except (ValueError, TypeError) as e:
                    logger.warning("The transition couldn't be added: {0}".format(e))
            else:
                logger.debug("outcome-editor got None in to_outcome-combo-change no transition is added")


Instruction:
How would you code a function in Python 3 to
remove respective core element of handed outcome model

Response:
def remove_core_element(self, model):
        """Remove respective core element of handed outcome model

        :param OutcomeModel model: Outcome model which core element should be removed
        :return:
        """
        assert model.outcome.parent is self.model.state
        gui_helper_state_machine.delete_core_element_of_model(model)


Instruction:
Given the following Python 3 function, write the documentation
def register_view(self, view):
        super(StateOutcomesEditorController, self).register_view(view)
        if isinstance(view, StateOutcomesEditorView):
            self.connect_signal(view['add_button'], "clicked", self.oc_list_ctrl.on_add)
            self.connect_signal(view['remove_button'], "clicked", self.oc_list_ctrl.on_remove)

            if isinstance(self.model.state, LibraryState) or self.model.state.get_next_upper_library_root_state():
                view['add_button'].set_sensitive(False)
                view['remove_button'].set_sensitive(False)

Response: Called when the view was registered


Instruction:
How would you code a function in Python 3 to
find tab with label tab_label in list of notebook s and set it to the current page.

Response:
def bring_tab_to_the_top(self, tab_label):
        """Find tab with label tab_label in list of notebook's and set it to the current page.

        :param tab_label: String containing the label of the tab to be focused
        """
        page = self.page_dict[tab_label]
        for notebook in self.notebook_names:
            page_num = self[notebook].page_num(page)
            if not page_num == -1:
                self[notebook].set_current_page(page_num)
                break


Instruction:
Explain what the following Python 3 code does
def compare_variables(tree_model, iter1, iter2, user_data=None):
        path1 = tree_model.get_path(iter1)[0]
        path2 = tree_model.get_path(iter2)[0]
        # get key of first variable
        name1 = tree_model[path1][0]
        # get key of second variable
        name2 = tree_model[path2][0]
        name1_as_bits = ' '.join(format(ord(x), 'b') for x in name1)
        name2_as_bits = ' '.join(format(ord(x), 'b') for x in name2)
        if name1_as_bits == name2_as_bits:
            return 0
        elif name1_as_bits > name2_as_bits:
            return 1
        else:
            return -1

Response: Triggered upon updating the list of global variables alphabetically.


Instruction:
Given the following Python 3 function, write the documentation
def has_dirty_state_machine(self):
        for sm in self.state_machines.values():
            if sm.marked_dirty:
                return True
        return False

Response: Checks if one of the state machines contains the marked_dirty flag set to True.


Instruction:
Can you implement a function in Python 3 that
resets all marked_dirty flags of all state machines to false.

Response:
def reset_dirty_flags(self):
        """Set all marked_dirty flags of the state machine to false."""
        for sm_id, sm in self.state_machines.items():
            sm.marked_dirty = False


Instruction:
Can you create a Python 3 function that
adds a state machine to the list of managed state machines.

Response:
def add_state_machine(self, state_machine):
        """Add a state machine to the list of managed state machines. If there is no active state machine set yet,
            then set as active state machine.

        :param state_machine: State Machine Object
        :raises exceptions.AttributeError: if the passed state machine was already added of is of a wrong type
        """
        if not isinstance(state_machine, StateMachine):
            raise AttributeError("State machine must be of type StateMachine")
        if state_machine.file_system_path is not None:
            if self.is_state_machine_open(state_machine.file_system_path):
                raise AttributeError("The state machine is already open {0}".format(state_machine.file_system_path))
        logger.debug("Add new state machine with id {0}".format(state_machine.state_machine_id))
        self._state_machines[state_machine.state_machine_id] = state_machine
        return state_machine.state_machine_id


Instruction:
Create a Python 3 function to
remove the state machine with the specified id from the list of registered state machines.

Response:
def remove_state_machine(self, state_machine_id):
        """Remove the state machine for a specified state machine id from the list of registered state machines.

        :param state_machine_id: the id of the state machine to be removed
        """
        import rafcon.core.singleton as core_singletons
        removed_state_machine = None
        if state_machine_id in self._state_machines:
            logger.debug("Remove state machine with id {0}".format(state_machine_id))
            removed_state_machine = self._state_machines.pop(state_machine_id)
        else:
            logger.error("There is no state_machine with state_machine_id: %s" % state_machine_id)
            return removed_state_machine

        # destroy execution history
        removed_state_machine.destroy_execution_histories()
        return removed_state_machine


Instruction:
Make a summary of the following Python 3 code
def get_active_state_machine(self):
        if self._active_state_machine_id in self._state_machines:
            return self._state_machines[self._active_state_machine_id]
        else:
            return None

Response: Return a reference to the active state - machine


Instruction:
How would you implement a function in Python 3 that
returns a reference to the state machine with the given file system path if open

Response:
def get_open_state_machine_of_file_system_path(self, file_system_path):
        """Return a reference to the state machine with respective path if open
        """
        for sm in self.state_machines.values():
            if sm.file_system_path == file_system_path:
                return sm


Instruction:
Can you tell what is the following Python 3 function doing
def reset_title(self, title, notebook_identifier):
        current_title = self.get_top_widget().get_title()
        upper_title = current_title.split('/')[0].strip()
        lower_title = current_title.split('/')[1].strip()
        if notebook_identifier == 'upper':
            new_title = title + ' / ' + lower_title
        else:
            new_title = upper_title + ' / ' + title
        self['headerbar'].props.title = new_title

Response: Triggered whenever a notebook tab is switched in the left bar.


Instruction:
Can you write a function in Python 3 where it
checks if the expected_future_models list contains still a specific model

Response:
def negative_check_for_model_in_expected_future_models(target_state_m, model, msg, delete=True, with_logger=None):
    """ Checks if the expected future models list/set includes still a specific model

    Return False if the handed model is still in and also creates a warning message as feedback.

    :param StateModel target_state_m: The state model which expected_future_models attribute should be checked
    :param Model model: Model to check for.
    :param str msg: Message for the logger if a model is still in.
    :param bool delete: Flag to delete respective model from list/set.
    :param with_logger: A optional logger to use in case of logging messages
    :rtype: bool
    :return: True if empty and False if still model in set/list
    """
    if with_logger is None:
        with_logger = logger
    # check that the model in the list expected_future_model was used
    if model in target_state_m.expected_future_models:
        with_logger.warning("{0} -> still in is: {1} Please inform the developer how to reproduce this."
                            "".format(msg, model))
        if delete:
            # TODO think about to destroy this models
            target_state_m.expected_future_models.remove(model)
        return False
    return True


Instruction:
Implement a Python 3 function for
checking if the list of expected future models is empty.

Response:
def check_expected_future_model_list_is_empty(target_state_m, msg, delete=True, with_logger=None):
    """ Checks if the expected future models list/set is empty

    Return False if there are still elements in and also creates a warning message as feedback.

    :param StateModel target_state_m: The state model which expected_future_models attribute should be checked
    :param str msg: Message for the logger if a model is still in.
    :param bool delete: Flag to delete respective model from list/set.
    :param with_logger: A optional logger to use in case of logging messages
    :rtype: bool
    :return: True if empty and False if still model in set/list
    """
    if with_logger is None:
        with_logger = logger
    # check that the model in the list expected_future_model was used
    if target_state_m.expected_future_models:
        with_logger.warning("{0} -> still in are: {1} Please inform the developer how to reproduce this."
                            "".format(msg, target_state_m.expected_future_models))
        if delete:
            # TODO think about to destroy this models
            target_state_m.expected_future_models.clear()
        return False
    return True


Instruction:
Given the following Python 3 function, write the documentation
def update_models_recursively(state_m, expected=True):

    assert isinstance(state_m, AbstractStateModel)

    if isinstance(state_m, LibraryStateModel):
        if not state_m.state_copy_initialized:
            if not expected:
                logger.warning("State {0} generates unexpected missing state copy models.".format(state_m))
            state_m.recursive_generate_models(load_meta_data=False)
            import rafcon.gui.helpers.meta_data as gui_helper_meta_data
            gui_helper_meta_data.scale_library_content(state_m)

    if isinstance(state_m, ContainerStateModel):
        for child_state_m in state_m.states.values():
            update_models_recursively(child_state_m, expected)

Response:
Recursively creates all
    and all
Models


Instruction:
Write a Python 3 script to
add a state to a container state

Response:
def add_state(container_state_m, state_type):
    """Add a state to a container state

    Adds a state of type state_type to the given container_state

    :param rafcon.gui.models.container_state.ContainerState container_state_m: A model of a container state to add
      the new state to
    :param rafcon.core.enums.StateType state_type: The type of state that should be added
    :return: True if successful, False else
    """
    if container_state_m is None:
        logger.error("Cannot add a state without a parent.")
        return False

    if not isinstance(container_state_m, StateModel) or \
            (isinstance(container_state_m, StateModel) and not isinstance(container_state_m, ContainerStateModel)):
        logger.error("Parent state must be a container, for example a Hierarchy State." + str(container_state_m))
        return False

    state_class = state_type_to_state_class_dict.get(state_type, None)

    if state_class is None:
        logger.error("Cannot create state of type {0}".format(state_type))
        return False

    new_state = state_class()
    from rafcon.gui.models.abstract_state import get_state_model_class_for_state
    new_state_m = get_state_model_class_for_state(new_state)(new_state)
    gui_helper_meta_data.put_default_meta_on_state_m(new_state_m, container_state_m)
    container_state_m.expected_future_models.add(new_state_m)
    container_state_m.state.add_state(new_state)
    return True


Instruction:
Make a summary of the following Python 3 code
def create_new_state_from_state_with_type(source_state, target_state_class):

    current_state_is_container = isinstance(source_state, ContainerState)
    new_state_is_container = issubclass(target_state_class, ContainerState)

    if current_state_is_container and new_state_is_container:  # TRANSFORM from CONTAINER- TO CONTAINER-STATE

        # by default all transitions are left out if the new and original state are container states
        # -> because switch from Barrier, Preemptive or Hierarchy has always different rules
        state_transitions = {}
        state_start_state_id = None
        logger.info("Type change from %s to %s" % (type(source_state).__name__, target_state_class.__name__))

        # decider state is removed because it is unique for BarrierConcurrencyState
        if isinstance(source_state, BarrierConcurrencyState):
            source_state.remove_state(UNIQUE_DECIDER_STATE_ID, force=True)
            assert UNIQUE_DECIDER_STATE_ID not in source_state.states

        # separate state-elements from source state
        data_flows = dict(source_state.data_flows)
        source_state.data_flows = {}
        input_data_ports = dict(source_state.input_data_ports)
        output_data_ports = dict(source_state.output_data_ports)
        scoped_variables = dict(source_state.scoped_variables)
        income = source_state.income
        outcomes = dict(source_state.outcomes)
        source_state.input_data_ports = {}
        source_state.output_data_ports = {}
        source_state.scoped_variables = {}
        source_state.transitions = {}  # before remove of outcomes related transitions should be gone
        source_state.income = Income()
        source_state.outcomes = {}
        states = dict(source_state.states)
        # TODO check why next line can not be performed
        # source_state.states = {}

        new_state = target_state_class(name=source_state.name, state_id=source_state.state_id,
                                       input_data_ports=input_data_ports,
                                       output_data_ports=output_data_ports,
                                       scoped_variables=scoped_variables,
                                       income=income,
                                       outcomes=outcomes,
                                       transitions=state_transitions,
                                       data_flows=data_flows,
                                       states=states,
                                       start_state_id=state_start_state_id)

    else:  # TRANSFORM from EXECUTION- TO CONTAINER-STATE or FROM CONTAINER- TO EXECUTION-STATE

        # in case the new state is an execution state remove of child states (for observable notifications)
        if current_state_is_container and issubclass(target_state_class, ExecutionState):
            if isinstance(source_state, BarrierConcurrencyState):
                source_state.remove_state(UNIQUE_DECIDER_STATE_ID, force=True)
                assert UNIQUE_DECIDER_STATE_ID not in source_state.states
            for state_id in list(source_state.states.keys()):
                source_state.remove_state(state_id)

        # separate state-elements from source state
        input_data_ports = dict(source_state.input_data_ports)
        output_data_ports = dict(source_state.output_data_ports)
        income = source_state.income
        outcomes = dict(source_state.outcomes)
        source_state.input_data_ports = {}
        source_state.output_data_ports = {}
        source_state.income = Income()
        source_state.outcomes = {}

        new_state = target_state_class(name=source_state.name, state_id=source_state.state_id,
                                       input_data_ports=input_data_ports,
                                       output_data_ports=output_data_ports,
                                       income=income, outcomes=outcomes)

    if source_state.description is not None and len(source_state.description) > 0:
        new_state.description = source_state.description
    new_state.semantic_data = Vividict(source_state.semantic_data)
    return new_state

Response: This function duplicates a state with a new type and returns a new state that is a new type.


Instruction:
Can you tell what is the following Python 3 function doing
def extract_child_models_of_state(state_m, new_state_class):
    # check if root state and which type of state
    assert isinstance(state_m, StateModel)
    assert issubclass(new_state_class, State)
    orig_state = state_m.state  # only here to get the input parameter of the Core-function

    current_state_is_container = isinstance(orig_state, ContainerState)
    new_state_is_container = issubclass(new_state_class, ContainerState)

    # define which model references to hold for new state
    required_model_properties = ['input_data_ports', 'output_data_ports', 'outcomes', 'income']
    obsolete_model_properties = []
    if current_state_is_container and new_state_is_container:  # hold some additional references
        # transition are removed when changing the state type, thus do not copy them
        required_model_properties.extend(['states', 'data_flows', 'scoped_variables'])
        obsolete_model_properties.append('transitions')
    elif current_state_is_container:
        obsolete_model_properties.extend(['states', 'transitions', 'data_flows', 'scoped_variables'])

    def get_element_list(state_m, prop_name):
        if prop_name == 'income':
            return [state_m.income]
        wrapper = getattr(state_m, prop_name)
        # ._obj is needed as gaphas wraps observable lists and dicts into a gaphas.support.ObsWrapper
        list_or_dict = wrapper._obj
        if isinstance(list_or_dict, list):
            return list_or_dict[:]  # copy list
        return list(list_or_dict.values())  # dict

    required_child_models = {}
    for prop_name in required_model_properties:
        required_child_models[prop_name] = get_element_list(state_m, prop_name)
    obsolete_child_models = {}
    for prop_name in obsolete_model_properties:
        obsolete_child_models[prop_name] = get_element_list(state_m, prop_name)

    # Special handling of BarrierState, which includes the DeciderState that always becomes obsolete
    if isinstance(state_m, ContainerStateModel):
        decider_state_m = state_m.states.get(UNIQUE_DECIDER_STATE_ID, None)
        if decider_state_m:
            if new_state_is_container:
                required_child_models['states'].remove(decider_state_m)
                obsolete_child_models['states'] = [decider_state_m]

    return required_child_models, obsolete_child_models

Response: This function extracts the child models of the given state model into a dict.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def create_state_model_for_state(new_state, meta, state_element_models):
    from rafcon.gui.models.abstract_state import get_state_model_class_for_state
    state_m_class = get_state_model_class_for_state(new_state)
    new_state_m = state_m_class(new_state, meta=meta, load_meta_data=False, expected_future_models=state_element_models)
    error_msg = "New state has not re-used all handed expected future models."
    check_expected_future_model_list_is_empty(new_state_m, msg=error_msg)

    return new_state_m

Response: Create a new state model with the defined properties


Instruction:
Can you generate the documentation for the following Python 3 function
def prepare_state_m_for_insert_as(state_m_to_insert, previous_state_size):
    # TODO check how much code is duplicated or could be reused for library fit functionality meta data helper
    # TODO DO REFACTORING !!! and move maybe the hole method to meta data and rename it
    if isinstance(state_m_to_insert, AbstractStateModel) and \
            not gui_helper_meta_data.model_has_empty_meta(state_m_to_insert):

        if isinstance(state_m_to_insert, ContainerStateModel):
            # print("TARGET1", state_m_to_insert.state.state_element_attrs)
            models_dict = {'state': state_m_to_insert}

            for state_element_key in state_m_to_insert.state.state_element_attrs:
                state_element_list = getattr(state_m_to_insert, state_element_key)
                # Some models are hold in a gtkmvc3.support.wrappers.ObsListWrapper, not a list
                if hasattr(state_element_list, 'keys'):
                    state_element_list = state_element_list.values()
                models_dict[state_element_key] = {elem.core_element.core_element_id: elem for elem in state_element_list}

            resize_factor = gui_helper_meta_data.scale_meta_data_according_state(models_dict, as_template=True)
            gui_helper_meta_data.resize_income_of_state_m(state_m_to_insert, resize_factor)

        elif isinstance(state_m_to_insert, StateModel):
            # print("TARGET2", state_m_to_insert.state.state_element_attrs)

            if previous_state_size:
                current_size = state_m_to_insert.get_meta_data_editor()['size']
                factor = gui_helper_meta_data.divide_two_vectors(current_size, previous_state_size)
                state_m_to_insert.set_meta_data_editor('size', previous_state_size)
                factor = (min(*factor), min(*factor))
                gui_helper_meta_data.resize_state_meta(state_m_to_insert, factor)
            else:
                logger.debug("For insert as template of {0} no resize of state meta data is performed because "
                             "the meta data has empty fields.".format(state_m_to_insert))

        # library state is not resize because its ports became resized indirectly -> see was resized flag
        elif not isinstance(state_m_to_insert, LibraryStateModel):
            raise TypeError("For insert as template of {0} no resize of state meta data is performed because "
                            "state model type is not ContainerStateModel or StateModel".format(state_m_to_insert))
    else:
        logger.info("For insert as template of {0} no resize of state meta data is performed because the meta data has "
                    "empty fields.".format(state_m_to_insert))

Response: Prepares and scales the meta data to fit into actual size of the state.


Instruction:
Explain what the following Python 3 code does
def insert_state_as(target_state_m, state, as_template):

    if not isinstance(target_state_m, ContainerStateModel) or \
            not isinstance(target_state_m.state, ContainerState):
        logger.error("States can only be inserted in container states")
        return False

    state_m = get_state_model_class_for_state(state)(state)
    if not as_template:
        gui_helper_meta_data.put_default_meta_on_state_m(state_m, target_state_m)

    # If inserted as template, we have to extract the state_copy and respective model
    else:
        assert isinstance(state, LibraryState)
        old_lib_state_m = state_m
        state_m = state_m.state_copy

        previous_state_size = state_m.get_meta_data_editor()['size']
        gui_helper_meta_data.put_default_meta_on_state_m(state_m, target_state_m)
        # TODO check if the not as template case maybe has to be run with the prepare call
        prepare_state_m_for_insert_as(state_m, previous_state_size)

        old_lib_state_m.prepare_destruction(recursive=False)

    # explicit secure that there is no state_id conflict within target state child states
    while state_m.state.state_id in target_state_m.state.states:
        state_m.state.change_state_id()

    target_state_m.expected_future_models.add(state_m)
    target_state_m.state.add_state(state_m.state)

    # secure possible missing models to be generated
    update_models_recursively(state_m, expected=False)

Response: Add a state into a target state


Instruction:
Write a Python 3 function for
substituting the target state with the new state.

Response:
def substitute_state(target_state_m, state_m_to_insert, as_template=False):
    """ Substitutes the target state

    Both, the state to be replaced (the target state) and the state to be inserted (the new state) are passed via
    parameters.
    The new state adapts the size and position of the target state.
    State elements of the new state are resized but kepp their proportion.

    :param rafcon.gui.models.container_state.AbstractStateModel target_state_m: State Model of state to be substituted
    :param rafcon.gui.models.container_state.StateModel state_m_to_insert: State Model of state to be inserted
    :return:
    """
    # print("substitute_state")

    state_to_insert = state_m_to_insert.state
    action_parent_m = target_state_m.parent
    old_state_m = target_state_m
    old_state = old_state_m.state
    state_id = old_state.state_id

    # BEFORE MODEL
    tmp_meta_data = {'transitions': {}, 'data_flows': {}, 'state': None}
    old_state_m = action_parent_m.states[state_id]
    # print("EMIT-BEFORE ON OLD_STATE ", state_id)
    old_state_m.action_signal.emit(ActionSignalMsg(action='substitute_state', origin='model',
                                                   action_parent_m=action_parent_m,
                                                   affected_models=[old_state_m, ], after=False,
                                                   kwargs={'state_id': state_id, 'state': state_to_insert}))
    related_transitions, related_data_flows = action_parent_m.state.related_linkage_state(state_id)
    tmp_meta_data['state'] = old_state_m.meta
    # print("old state meta", old_state_m.meta)
    for t in related_transitions['external']['ingoing'] + related_transitions['external']['outgoing']:
        tmp_meta_data['transitions'][t.transition_id] = action_parent_m.get_transition_m(t.transition_id).meta
    for df in related_data_flows['external']['ingoing'] + related_data_flows['external']['outgoing']:
        tmp_meta_data['data_flows'][df.data_flow_id] = action_parent_m.get_data_flow_m(df.data_flow_id).meta
    action_parent_m.substitute_state.__func__.tmp_meta_data_storage = tmp_meta_data
    action_parent_m.substitute_state.__func__.old_state_m = old_state_m

    # put old state size and rel_pos onto new state
    previous_state_size = state_m_to_insert.get_meta_data_editor()['size']
    state_m_to_insert.set_meta_data_editor('size', old_state_m.get_meta_data_editor()['size'])
    state_m_to_insert.set_meta_data_editor('rel_pos', old_state_m.get_meta_data_editor()['rel_pos'])
    # scale the meta data according new size
    prepare_state_m_for_insert_as(state_m_to_insert, previous_state_size)

    # CORE
    new_state = e = None
    # print("state to insert", state_to_insert)
    try:
        # if as_template:  # TODO remove this work around if the models are loaded correctly
        #     # the following enforce the creation of a new model (in needed depth) and transfer of meta data
        #     import rafcon.gui.action
        #     meta_dict = rafcon.gui.action.get_state_element_meta(state_m_to_insert)
        #     new_state = action_parent_m.state.substitute_state(state_id, state_to_insert)
        #     sm_m = action_parent_m.get_state_machine_m()
        #     rafcon.gui.action.insert_state_meta_data(meta_dict, sm_m.get_state_model_by_path(new_state.get_path()))
        # else:
        action_parent_m.expected_future_models.add(state_m_to_insert)
        new_state = action_parent_m.state.substitute_state(state_id, state_to_insert)
        # assert new_state.state_id is state_id
        assert new_state is state_to_insert
    except Exception as e:
        logger.exception("State substitution failed")

    if new_state:
        # AFTER MODEL
        # print("AFTER MODEL", new_state)
        new_state_m = action_parent_m.states[new_state.state_id]
        update_models_recursively(state_m=new_state_m)
        tmp_meta_data = action_parent_m.substitute_state.__func__.tmp_meta_data_storage
        old_state_m = action_parent_m.substitute_state.__func__.old_state_m
        changed_models = []
        new_state_m.meta = tmp_meta_data['state']
        changed_models.append(new_state_m)
        for t_id, t_meta in tmp_meta_data['transitions'].items():
            if action_parent_m.get_transition_m(t_id) is not None:
                action_parent_m.get_transition_m(t_id).meta = t_meta
                changed_models.append(action_parent_m.get_transition_m(t_id))
            elif t_id in action_parent_m.state.substitute_state.__func__.re_create_io_going_t_ids:
                logger.warning("Transition model with id {0} to set meta data could not be found.".format(t_id))
        for df_id, df_meta in tmp_meta_data['data_flows'].items():
            if action_parent_m.get_data_flow_m(df_id) is not None:
                action_parent_m.get_data_flow_m(df_id).meta = df_meta
                changed_models.append(action_parent_m.get_data_flow_m(df_id))
            elif df_id in action_parent_m.state.substitute_state.__func__.re_create_io_going_df_ids:
                logger.warning("Data flow model with id {0} to set meta data could not be found.".format(df_id))

        msg = ActionSignalMsg(action='substitute_state', origin='model', action_parent_m=action_parent_m,
                              affected_models=changed_models, after=True, result=e)
        # print("EMIT-AFTER OLDSTATE", msg)
        old_state_m.action_signal.emit(msg)

    del action_parent_m.substitute_state.__func__.tmp_meta_data_storage
    del action_parent_m.substitute_state.__func__.old_state_m