From 556dc861744de1affc3311c31b744654e966cef9 Mon Sep 17 00:00:00 2001 From: erick Date: Sun, 25 Oct 2009 01:11:19 +0000 Subject: First implementation of Tutorial.State with tests --- (limited to 'tutorius/tutorial.py') diff --git a/tutorius/tutorial.py b/tutorius/tutorial.py index a9c0cab..a4da092 100644 --- a/tutorius/tutorial.py +++ b/tutorius/tutorial.py @@ -25,7 +25,7 @@ class Tutorial(object): # We will use an adjacency list representation through the # usage of state objects because our graph representation - # is really sparse an mostly linear, for a brief + # is really sparse and mostly linear, for a brief # example of graph programming in python see: # http://www.python.org/doc/essays/graphs self._state_dict = state_dict or \ @@ -167,17 +167,17 @@ class Tutorial(object): pass def get_actions(self, state_name): - """ - @param state_name The name of the state to list actions from - @return A list of actions for state_name - """ + """ + @param state_name The name of the state to list actions from + @return A list of actions for state_name + """ pass def get_events(self, state_name): - """ - @param state_name The name of the state to list actions from - @return A list of events for state_name - """ + """ + @param state_name The name of the state to list actions from + @return A list of events for state_name + """ pass def get_following_states(self, state_name): @@ -201,7 +201,7 @@ class Tutorial(object): transition to. @raise KeyError When there is no state by this name in the FSM """ - pass + pass def _validate_action(self, action): """ @@ -256,8 +256,7 @@ class Tutorial(object): def _generate_unique_state_name(self): name = "State" + str(self._state_name_nb) - self._state_name_nb += 1 - + self._state_name_nb += 1 return name def __str__(self): @@ -278,8 +277,8 @@ class State(object): def __init__(self, name="", action_list=[], transition_list=[]): """ - Initializes the content of the state, like loading the actions - that are required and building the correct tests. + Initializes the content of the state, such as loading the actions + that are required and building the correct transitions. @param action_list The list of actions to execute when entering this state @@ -298,40 +297,54 @@ class State(object): self._transitions = {} for transition in transition_list: self._transitions[self._generate_unique_transition_name(transition)] = transition + + # Initialize internal variables for name generation + self.action_name_nb = 0 + self.transition_name_nb = 0 # Action manipulations def add_action(self, new_action): """ - Adds an action to the state (only if it wasn't added before) + Adds an action to the state - @param new_action The new action to execute when in this state + @param new_action The action to add @return a unique name for this action """ - if new_action not in self._actions: - self._actions.append(new_action) - return True - return False + action_name = self._generate_unique_action_name(new_action) + self._actions[action_name] = new_action + return action_name def delete_action(self, action_name): """ - Delete the action with the name action_name returned when the - action was added or when they are listed + Delete the action with the name action_name @param action_name The name of the action to delete - @return True if the action existed of False if no action had this name + @return The action deleted + @raise NameError if action_name doesn't exist """ - pass + if self._actions.has_key(action_name): + return self._actions.pop(action_name) + else: + raise NameError("Tutorial.State: action '" + action_name + "' is not defined") - def update_action(self, action_name, action): + def update_action(self, action_name, new_action): """ - Update the action with the name action_name with the properties from - action - - @param action_name The name of the action to update - @param action The action whose properties are copied over - @return True if action_name existed and the properties were valid, False otherwise - """ - pass + Replace the action with action_name by new_action + + @param action_name The name of the action to replace + @param new_action The action that will replace the old one + @return The replaced action + @raise NameError if action_name doesn't exist + """ + # TODO: For now let's just replace the action with a new one, + # we should check to see if we need a replace or an update + # semantic for this update method + if self._actions.has_key(action_name): + old_action = self._actions.pop(action_name) + self._actions[action_name] = new_action + return old_action + else: + raise NameError("Tutorial.State: action '" + action_name + "' is not defined") def get_action_dict(self): """ @@ -347,36 +360,55 @@ class State(object): self._actions = {} # Transition manipulations - def add_transition(self, transition): + def add_transition(self, new_transition): """ Adds a transition from this state to another state. The same transition may not be added twice. @param transition The new transition. - @return A unique name for the transition could be added, False otherwise + @return A unique name for the transition + @raise TransitionAlreadyExists if an equivalent transition exists """ - return False + for transition in self._transitions.itervalues(): + if transition == new_transition: + raise TransitionAlreadyExists(str(transition)) - def update_transition(self, transition_name, transition): - """ - Update the transition with the name transition_name with the properties from - transition - - @param transition_name The name of the transition to update - @param transition The transition whose properties are copied over - @return True if transition_name existed and the properties were valid, False otherwise - """ - pass + transition_name = self._generate_unique_transition_name(new_transition) + self._transitions[transition_name] = new_transition + return transition_name + + def update_transition(self, transition_name, new_transition): + """ + Replace the transition with transition_name by new_transition + + @param transition_name The name of the transition to replace + @param new_transition The transition that will replace the old one + @return The replaced transition + @raise NameError if transition_name doesn't exist + """ + # TODO: For now let's just replace the transition with a new one, + # we should check to see if we need a replace or an update + # semantic for this update method + if self._transitions.has_key(transition_name): + old_transition = self._transitions.pop(transition_name) + self._transitions[transition_name] = new_transition + return old_transition + else: + raise NameError("Tutorial.State: transition '" + transition_name + "' is not defined") def delete_transition(self, transition_name): """ Delete the transition with the name transition_name @param transition_name The name of the transition to delete - @return True if transition_name existed, False otherwise + @return The transition deleted + @raise NameError if transition_name doesn't exist """ - pass + if self._transitions.has_key(transition_name): + return self._transitions.pop(transition_name) + else: + raise NameError("Tutorial.State: transition '" + transition_name + "' is not defined") def get_transition_dict(self): """ @@ -392,30 +424,44 @@ class State(object): def _generate_unique_action_name(self, action): """ - Returns a unique name for the action in this state + Returns a unique name for the action in this state, + the actual content of the name should not be relied upon + for correct behavior @param action The action to generate a name for @return A name garanteed to be unique within this state """ - return None + #TODO use the action class name to generate a name + # to make it easier to debug and know what we are + # manipulating + name = "action" + str(self.action_name_nb) + self.action_name_nb += 1 + return name def _generate_unique_transition_name(self, transition): """ - Returns a unique name for the transition in this state + Returns a unique name for the transition in this state, + the actual content of the name should not be relied upon + for correct behavior @param transition The transition to generate a name for @return A name garanteed to be unique within this state """ - return None + #TODO use the event class name from the transition to + # generate a name to make it easier to debug and know + # what we are manipulating + name = "transition" + str(self.transition_name_nb) + self.transition_name_nb += 1 + return name ################## Error Handling and Exceptions ############################## class TransitionAlreadyExists(Exception): - """ - Raised when a duplicate transition is added to a state - """ - pass + """ + Raised when a duplicate transition is added to a state + """ + pass -- cgit v0.9.1