From f6a12e2989f739576c1d34d4d1b80e7ed4813b86 Mon Sep 17 00:00:00 2001 From: erick Date: Mon, 05 Oct 2009 01:31:14 +0000 Subject: Finished a first pass through the specs, started implementing the Tutorial --- (limited to 'tutorius/tutorial.py') diff --git a/tutorius/tutorial.py b/tutorius/tutorial.py index 16a3c48..d8996f9 100644 --- a/tutorius/tutorial.py +++ b/tutorius/tutorial.py @@ -5,34 +5,163 @@ class Tutorial(object): of a tutorial as a state machine """ - def __init__(self): - pass + _INIT = "INIT" + _END = "END" - def add_state(self, state_name): - pass + def __init__(self, name, state_dict=None): + """ + The constructor for the Tutorial. By default, the tutorial contains + only an initial state and an end state. + The initial state doesn't contain any action or transition. + The end state doesn't contain any action either. + + If state_dict is provided, a valid initial state and an end state + must be provided. + + @param name The name of the tutorial + @param state_dict optional, a valid dictionary of states + """ + self.name = name + + # 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 + # example of graph programming in python see: + # http://www.python.org/doc/essays/graphs + self._state_dict = state_dict or \ + {Tutorial._INIT:State(name=Tutorial._INIT),\ + Tutorial._END:State(name=Tutorial._END)} + + # Minimally check for the presence of an INIT and an END + # state + if not self._state_dict.has_key(Tutorial._INIT): + raise Exception("No INIT state found in state_dict") + + if not self._state_dict.has_key(Tutorial._END): + raise Exception("No END state found in state_dict") + + self.validate() + + # Initialize variables for generating unique names + # TODO: We should take the max number from the + # existing state names + self._state_name_nb = 0 + + + def add_state(self, action_list=[], transition_list=[]): + """ + Add a new state to the state machine. The state is + initialized with the action list and transition list + and a new unique name is returned for this state. + + The action is added using add_action. + + The transitions is added using add_transition. + + @param action_list The list of valid actions for this state + @param transition_list The list of valid transitions + @return string unique name for this state + """ + name = self._generate_unique_state_name() + + for action in action_list: + self._validate_action(action) + + for transition in transition_list: + self._validate_transition(transition) + + state = State(name, action_list, transition_list) + + if self._state_dict.has_key(name): + raise Exception("Name: " + name + " already exists, could not\ + add a new state.") + + self._state_dict[name] = state + + return name + def add_action(self, state_name, action): - pass + """ + Add an action to a specific state. A unique name for this + tutorial is generated to refer precisely to this action + and is returned. + + The action is validated. + + @param state_name The name of the state to add an action to + @param action The action to be added + @return unique name for this action + """ + return "State/Action" def add_transition(self, state_name, transition): - pass + """ + Add a transition to a specific state. A unique name for this + tutorial is generated to refer precisely to this transition + and is returned. - def update_action(self, state_name, action_name, properties): - pass + The transition is validated. - def update_transition(self, state_name, transition_name, properties): - pass + @param state_name The name of the state to add a transition to + @param transition The transition to be added + @return unique name for this action + """ + return "State/Transition" + + def update_action(self, action_name, action): + """ + Update the properties of a specific action with a copy of the + properties of the action passed in. + + The action is validated. - def replace_state(self, state_name, state): - pass + @param action_name The name of the action to update + @param action An action with the properties to copy from + @return action_name if the update was successful, False otherwise + """ + return action_name - def delete_action(self, state_name, action_name): - pass + def update_transition(self, transition_name, transition): + """ + Update the properties of a specific transition with a copy of the + properties of the transition passed in. + + The transition is validated. + + @param transition_name The name of the transition to update + @param transition An transition with the properties to copy from + @return transition_name if the update was successful, False otherwise + """ + return transition_name - def delete_transition(self, state_name, transition_name): - pass + def delete_action(self, action_name): + """ + Delete the action identified by action_name. + + @param action_name The name of the action to be deleted + @return the action that has been deleted + """ + return None + + def delete_transition(self, transition_name): + """ + Delete the transition identified by transition_name. + + @param transition_name The name of the transition to be deleted + @return the transition that has been deleted + """ + return None def delete_state(self, state_name): + """ + Delete the state, delete all the actions and transitions + in this state, update the transitions from the state that + pointed to this one to the next state and remove all the + unreachable states recursively. + + @param state_name The name of the state to remove + """ pass def _validate_action(self, action): @@ -41,7 +170,16 @@ class Tutorial(object): throws an exception otherwise. @param action The action to validate - @throw InvalidAction if the action fails to conform to what we expect + @except InvalidAction if the action fails to conform to what we expect + """ + pass + + def _validate_action_name(self, action_name): + """ + Check if action_name exists. + + @param action_name The name to check + @except UnknownName if the name is not present in the Tutorial """ pass @@ -51,10 +189,41 @@ class Tutorial(object): throws an exception otherwise. @param transition The transition to validate - @throw InvalidTransition if the transition fails to conform to what we expect + @except InvalidTransition if the transition fails to conform to what we expect + """ + pass + + def _validate_transition_name(self, transition_name): + """ + Check if transition_name exists. + + @param transition_name The name to check + @except UnknownName if the name is not present in the Tutorial + """ + pass + + def validate(self): + """ + Validate the state machine for a serie of properties: + 1. No unreachable states + 2. No dead end state (except END) + 3. No branching in the main path + 4. No loop in the main path + 5. ... + + Throw an exception for the first condition that is not met. """ pass + def _generate_unique_state_name(self): + name = "State" + str(self._state_name_nb) + self._state_name_nb += 1 + + return name + + + + class State(object): """ This is a step in a tutorial. The state represents a collection of actions @@ -117,7 +286,7 @@ class State(object): action @param action_name The name of the action to update - @param action The action whose properties will be copied over + @param action The action whose properties are copied over @return True if action_name existed and the properties were valid, False otherwise """ pass @@ -153,7 +322,7 @@ class State(object): transition @param transition_name The name of the transition to update - @param transition The transition whose properties will be copied over + @param transition The transition whose properties are copied over @return True if transition_name existed and the properties were valid, False otherwise """ pass -- cgit v0.9.1