Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerick <erick@sugar-dev-erick.(none)>2009-10-28 02:03:51 (GMT)
committer erick <erick@sugar-dev-erick.(none)>2009-10-28 02:03:51 (GMT)
commit60109dea12383f8ea2f6d4251952ccc3859feec5 (patch)
tree8beb977d49c402fe71803dec9639c5bb0ae905f1
parentf356520259cff7006465aa09ad050b1cd591d496 (diff)
TutorialADT: First pass for modifications following Simon review, still has some changes to do
-rw-r--r--tests/tutorialtests.py108
-rw-r--r--tutorius/tutorial.py160
2 files changed, 150 insertions, 118 deletions
diff --git a/tests/tutorialtests.py b/tests/tutorialtests.py
index 3be3415..c1f591f 100644
--- a/tests/tutorialtests.py
+++ b/tests/tutorialtests.py
@@ -1,5 +1,5 @@
# Copyright (C) 2009, Tutorius.org
-# Copyright (C) 2009, Michael Janelle-Montcalm <michael.jmontcalm@gmail.com>
+# Copyright (C) 2009, Erick Lavoie <erick.lavoie@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,21 +15,16 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
-Core Tests
-
-This module contains all the tests that pertain to the usage of the Tutorius
-Core. This means that the Event Filters, the Finite State Machine and all the
-related elements and interfaces are tested here.
+Tutorial Tests
+"""
-Usage of actions and event filters is tested, but not the concrete actions
-and event filters. Those are in their separate test module
+# TODO: Add tests for 47, 52, 55, 109, 132, 175, 209, 229, 233, 271, 274, 292, 295, 318, 337, 375, 394, 411, 428, 446, 480, 491, 624, 637, 698
-"""
+# TODO: Use doc strings for test names that are too long
+# TODO: Use helper functions for common checks
import unittest
-import copy
-import logging
from sugar.tutorius.tutorial import *
# The following tests are organized around 4 classes:
@@ -162,36 +157,27 @@ class StateTest(unittest.TestCase):
######################### Error cases ###################################
#### Action
def test_update_unknown_action(self):
- name_error = None
try:
self.state.update_action("unknown_name", "action")
- except NameError, e:
- name_error = e
-
- assert name_error
-
+ assert False
+ except LookupError:
+ pass
def test_delete_unknown_action(self):
- name_error = None
try:
self.state.delete_action("unknown_name")
- except NameError, e:
- name_error = e
-
- assert name_error
+ assert False
+ except LookupError:
+ pass
#### Transition
def test_add_existing_transition(self):
self.state.add_transition("transition")
- transition_exists_error = None
try:
self.state.add_transition("transition")
- except TransitionAlreadyExists, e:
- transition_exists_error = e
-
- assert transition_exists_error
-
-
+ assert False
+ except TransitionAlreadyExists:
+ pass
class TutorialTest(unittest.TestCase):
"""Test tutorial functionality"""
@@ -207,20 +193,20 @@ class TutorialTest(unittest.TestCase):
#### Tutorial
def test_default_initial_value_in_tutorial(self):
assert len(self.tutorial.get_state_dict()) == 2
- assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial._INIT,Tutorial._END])
+ assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END])
assert len(self.tutorial.get_action_dict()) == 0
assert len(self.tutorial.get_transition_dict()) == 1
- assert self.tutorial.get_previous_states_dict(Tutorial._INIT) == {}
- assert self.tutorial.get_following_states_dict(Tutorial._INIT).keys() == [Tutorial._END]
- assert self.tutorial.get_previous_states_dict(Tutorial._END).keys() == [Tutorial._INIT]
- assert self.tutorial.get_following_states_dict(Tutorial._END) == {}
+ assert self.tutorial.get_previous_states_dict(Tutorial.INIT) == {}
+ assert self.tutorial.get_following_states_dict(Tutorial.INIT).keys() == [Tutorial.END]
+ assert self.tutorial.get_previous_states_dict(Tutorial.END).keys() == [Tutorial.INIT]
+ assert self.tutorial.get_following_states_dict(Tutorial.END) == {}
#### State
def test_add_default_state(self):
state_name = self.tutorial.add_state()
assert state_name
assert len(self.tutorial.get_state_dict()) == 3
- assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial._INIT,Tutorial._END, state_name])
+ assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END, state_name])
assert len(self.tutorial.get_action_dict()) == 0
assert len(self.tutorial.get_transition_dict()) == 1
@@ -228,15 +214,15 @@ class TutorialTest(unittest.TestCase):
state_name = self.tutorial.add_state(action_list=["action1"])
assert state_name
assert len(self.tutorial.get_state_dict()) == 3
- assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial._INIT,Tutorial._END, state_name])
+ assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END, state_name])
assert len(self.tutorial.get_action_dict()) == 1
assert len(self.tutorial.get_transition_dict()) == 1
def test_add_state_with_transition(self):
- state_name = self.tutorial.add_state(transition_list=[("event1",Tutorial._END)])
+ state_name = self.tutorial.add_state(transition_list=[("event1",Tutorial.END)])
assert state_name
assert len(self.tutorial.get_state_dict()) == 3
- assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial._INIT,Tutorial._END, state_name])
+ assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END, state_name])
assert len(self.tutorial.get_action_dict()) == 0
assert len(self.tutorial.get_transition_dict()) == 2
@@ -250,28 +236,28 @@ class TutorialTest(unittest.TestCase):
state_name1 = self.tutorial.add_state()
self.tutorial.delete_state(state_name1)
assert len(self.tutorial.get_state_dict()) == 2
- assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial._INIT,Tutorial._END])
+ assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END])
assert len(self.tutorial.get_action_dict()) == 0
assert len(self.tutorial.get_transition_dict()) == 1
- assert self.tutorial.get_previous_states_dict(Tutorial._INIT) == {}
- assert self.tutorial.get_following_states_dict(Tutorial._INIT).keys() == [Tutorial._END]
- assert self.tutorial.get_previous_states_dict(Tutorial._END).keys() == [Tutorial._INIT]
- assert self.tutorial.get_following_states_dict(Tutorial._END) == {}
+ assert self.tutorial.get_previous_states_dict(Tutorial.INIT) == {}
+ assert self.tutorial.get_following_states_dict(Tutorial.INIT).keys() == [Tutorial.END]
+ assert self.tutorial.get_previous_states_dict(Tutorial.END).keys() == [Tutorial.INIT]
+ assert self.tutorial.get_following_states_dict(Tutorial.END) == {}
def test_delete_linked_state(self):
state_name1 = self.tutorial.add_state()
- self.tutorial.update_transition(Tutorial._INITIAL_TRANSITION_NAME, \
- (Tutorial._AUTOMATIC_TRANSITION_EVENT, state_name1))
- transition_name1 = self.tutorial.add_transition(state_name1,("event1", Tutorial._END))
+ self.tutorial.update_transition(Tutorial.INITIAL_TRANSITION_NAME, \
+ (Tutorial.AUTOMATIC_TRANSITION_EVENT, state_name1))
+ transition_name1 = self.tutorial.add_transition(state_name1,("event1", Tutorial.END))
self.tutorial.delete_state(state_name1)
assert len(self.tutorial.get_state_dict()) == 2
- assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial._INIT,Tutorial._END])
+ assert set(self.tutorial.get_state_dict().keys()) == set([Tutorial.INIT,Tutorial.END])
assert len(self.tutorial.get_action_dict()) == 0
assert len(self.tutorial.get_transition_dict()) == 1
- assert self.tutorial.get_previous_states_dict(Tutorial._INIT) == {}
- assert self.tutorial.get_following_states_dict(Tutorial._INIT).keys() == [Tutorial._END]
- assert self.tutorial.get_previous_states_dict(Tutorial._END).keys() == [Tutorial._INIT]
- assert self.tutorial.get_following_states_dict(Tutorial._END) == {}
+ assert self.tutorial.get_previous_states_dict(Tutorial.INIT) == {}
+ assert self.tutorial.get_following_states_dict(Tutorial.INIT).keys() == [Tutorial.END]
+ assert self.tutorial.get_previous_states_dict(Tutorial.END).keys() == [Tutorial.INIT]
+ assert self.tutorial.get_following_states_dict(Tutorial.END) == {}
#### Action
def test_add_dummy_action(self):
@@ -357,30 +343,30 @@ class TutorialTest(unittest.TestCase):
#### Action
def test_update_unknown_action(self):
- name_error = None
+ lookup_error = None
try:
self.tutorial.update_action("unknown_name", "action")
- except NameError, e:
- name_error = e
+ except LookupError, e:
+ lookup_error = e
- assert name_error
+ assert lookup_error
def test_delete_unknown_action(self):
- name_error = None
+ lookup_error = None
try:
self.tutorial.delete_action("unknown_name")
- except NameError, e:
- name_error = e
+ except LookupError, e:
+ lookup_error = e
- assert name_error
+ assert lookup_error
#### Transition
def test_add_existing_transition(self):
- self.tutorial.add_transition(Tutorial._INIT,("event","transition"))
+ self.tutorial.add_transition(Tutorial.INIT,("event","transition"))
transition_exists_error = None
try:
- self.tutorial.add_transition(Tutorial._INIT,("event","transition"))
+ self.tutorial.add_transition(Tutorial.INIT,("event","transition"))
except TransitionAlreadyExists, e:
transition_exists_error = e
diff --git a/tutorius/tutorial.py b/tutorius/tutorial.py
index 8970d4f..6a6e089 100644
--- a/tutorius/tutorial.py
+++ b/tutorius/tutorial.py
@@ -1,3 +1,21 @@
+# Copyright (C) 2009, Tutorius.org
+# Copyright (C) 2009, Erick Lavoie <erick.lavoie@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#TODO: On update, only properties should be passed as arguments for State.update and Tutorial.update
class Tutorial(object):
""" This class replaces the previous Tutorial class and
@@ -5,19 +23,21 @@ class Tutorial(object):
of a tutorial as a state machine
"""
- _INIT = "INIT"
- _END = "END"
- _INITIAL_TRANSITION_NAME = _INIT + "/transition0"
- _AUTOMATIC_TRANSITION_EVENT = "automatic"
+ INIT = "INIT"
+ END = "END"
+ INITIAL_TRANSITION_NAME = INIT + "/transition0"
+ AUTOMATIC_TRANSITION_EVENT = "automatic"
+
+ _NAME_SEPARATOR = "/"
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 but it contains
- a single automatic transition <Tutorial._INITIAL_TRANSITION_NAME>
- between the initial state <Tutorial._INIT> and the end state
- <Tutorial._END>.
+ a single automatic transition <Tutorial.INITIAL_TRANSITION_NAME>
+ between the initial state <Tutorial.INIT> and the end state
+ <Tutorial.END>.
The end state doesn't contain any action nor transition.
@@ -38,20 +58,20 @@ class Tutorial(object):
# http://www.python.org/doc/essays/graphs
if not state_dict:
self._state_dict = \
- {Tutorial._INIT:State(name=Tutorial._INIT),\
- Tutorial._END:State(name=Tutorial._END)}
+ {Tutorial.INIT:State(name=Tutorial.INIT),\
+ Tutorial.END:State(name=Tutorial.END)}
- self.add_transition(Tutorial._INIT, \
- (Tutorial._AUTOMATIC_TRANSITION_EVENT, Tutorial._END))
+ self.add_transition(Tutorial.INIT, \
+ (Tutorial.AUTOMATIC_TRANSITION_EVENT, Tutorial.END))
else:
raise NotImplementedError("Tutorial: Initilization from a dictionary is not supported yet")
# Minimally check for the presence of an INIT and an END
# state
- if not self._state_dict.has_key(Tutorial._INIT):
+ 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):
+ if not self._state_dict.has_key(Tutorial.END):
raise Exception("No END state found in state_dict")
# TODO: Validate once validation is working
@@ -103,10 +123,10 @@ class Tutorial(object):
@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
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
"""
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + state_name +\
+ raise LookupError("Tutorial: state <" + state_name +\
"> is not defined")
self._validate_action(action)
@@ -125,11 +145,11 @@ class Tutorial(object):
@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
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
@raise TransitionAlreadyExists
"""
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + state_name +\
+ raise LookupError("Tutorial: state <" + state_name +\
"> is not defined")
self._validate_transition(transition)
@@ -146,12 +166,12 @@ class Tutorial(object):
@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
+ @raise LookupError if action_name doesn't exist
"""
- state_name = action_name[:action_name.find("/")]
+ state_name = action_name[:action_name.find(Tutorial._NAME_SEPARATOR)]
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: action <" + action_name +\
+ raise LookupError("Tutorial: action <" + action_name +\
"> is not defined")
self._validate_action(new_action)
@@ -167,12 +187,12 @@ class Tutorial(object):
@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
+ @raise LookupError if transition_name doesn't exist
"""
- state_name = transition_name[:transition_name.find("/")]
+ state_name = transition_name[:transition_name.find(Tutorial._NAME_SEPARATOR)]
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: transition <" + transition_name +\
+ raise LookupError("Tutorial: transition <" + transition_name +\
"> is not defined")
self._validate_transition(new_transition)
@@ -185,12 +205,12 @@ class Tutorial(object):
@param action_name The name of the action to be deleted
@return the action that has been deleted
- @raise NameError if transition_name doesn't exist
+ @raise LookupError if transition_name doesn't exist
"""
- state_name = action_name[:action_name.find("/")]
+ state_name = action_name[:action_name.find(Tutorial._NAME_SEPARATOR)]
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: action <" + action_name +\
+ raise LookupError("Tutorial: action <" + action_name +\
"> is not defined")
return self._state_dict[state_name].delete_action(action_name)
@@ -201,12 +221,12 @@ class Tutorial(object):
@param transition_name The name of the transition to be deleted
@return the transition that has been deleted
- @raise NameError if transition_name doesn't exist
+ @raise LookupError if transition_name doesn't exist
"""
- state_name = transition_name[:transition_name.find("/")]
+ state_name = transition_name[:transition_name.find(Tutorial._NAME_SEPARATOR)]
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: transition <" + transition_name +\
+ raise LookupError("Tutorial: transition <" + transition_name +\
"> is not defined")
return self._state_dict[state_name].delete_transition(transition_name)
@@ -223,14 +243,13 @@ class Tutorial(object):
@param state_name The name of the state to remove
@return The deleted state
@raise StateDeletionError when trying to delete the INIT or the END state
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
"""
- if state_name == Tutorial._INIT or state_name == Tutorial._END:
+ if state_name == Tutorial.INIT or state_name == Tutorial.END:
raise StateDeletionError("<" + state_name + "> cannot be deleted")
-
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + transition_name +\
+ raise LookupError("Tutorial: state <" + transition_name +\
"> is not defined")
next_states = set(self.get_following_states_dict(state_name).values())
@@ -259,16 +278,18 @@ class Tutorial(object):
def get_action_dict(self, state_name=None):
"""
- Returns a dictionary of all actions for a specific state.
+ Returns a reference to the dictionary of all actions for a specific
+ state.
If no state_name is provided, returns an action dictionary
containing actions for all states.
@param state_name The name of the state to list actions from
- @return A dictionary of actions with action_name as key and action as value for state_name
- @raise NameError if state_name doesn't exist
+ @return A dictionary of actions with action_name as key and action
+ as value for state_name
+ @raise LookupError if state_name doesn't exist
"""
if state_name and not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + state_name +\
+ raise LookupError("Tutorial: state <" + state_name +\
"> is not defined")
elif state_name:
return self._state_dict.get_action_dict()
@@ -286,10 +307,10 @@ class Tutorial(object):
@param state_name The name of the state to list actions from
@return A dictionary of transitions with transition_name as key and transition as value for state_name
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
"""
if state_name and not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + state_name +\
+ raise LookupError("Tutorial: state <" + state_name +\
"> is not defined")
elif state_name:
return self._state_dict.get_transition_dict()
@@ -302,7 +323,10 @@ class Tutorial(object):
def get_state_dict(self):
"""
- @return A dictionary of all the states in the tutorial with state_name as key and state as value
+ Returns a reference to the internal state dictionary used by
+ the Tutorial.
+
+ @return A reference to the dictionary of all the states in the tutorial with state_name as key and state as value
"""
return self._state_dict
@@ -312,10 +336,10 @@ class Tutorial(object):
a specific state.
@param state_name The name of the state
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
"""
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + state_name +\
+ raise LookupError("Tutorial: state <" + state_name +\
"> is not defined")
following_states_dict = {}
@@ -331,10 +355,10 @@ class Tutorial(object):
specific state.
@param state_name The name of the state
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
"""
if not self._state_dict.has_key(state_name):
- raise NameError("Tutorial: state <" + state_name +\
+ raise LookupError("Tutorial: state <" + state_name +\
"> is not defined")
@@ -370,7 +394,7 @@ class Tutorial(object):
@param action_list The list of valid actions for this state
@param event_list The list of events that will be converted to transitions to state_name
@return unique name for this state
- @raise NameError if state_name doesn't exist
+ @raise LookupError if state_name doesn't exist
"""
raise NotImplementedError
@@ -521,11 +545,11 @@ class State(object):
self._actions = {}
for action in action_list:
- self._actions[self._generate_unique_action_name(action)] = action
+ self.add_action(action)
self._transitions = {}
for transition in transition_list:
- self._transitions[self._generate_unique_transition_name(transition)] = transition
+ self.add_transition(transition)
# Action manipulations
@@ -546,12 +570,12 @@ class State(object):
@param action_name The name of the action to delete
@return The action deleted
- @raise NameError if action_name doesn't exist
+ @raise LookupError if action_name doesn't exist
"""
if self._actions.has_key(action_name):
return self._actions.pop(action_name)
else:
- raise NameError("Tutorial.State: action <" + action_name + "> is not defined")
+ raise LookupError("Tutorial.State: action <" + action_name + "> is not defined")
def update_action(self, action_name, new_action):
"""
@@ -560,7 +584,7 @@ class State(object):
@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
+ @raise LookupError 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
@@ -570,10 +594,12 @@ class State(object):
self._actions[action_name] = new_action
return old_action
else:
- raise NameError("Tutorial.State: action <" + action_name + "> is not defined")
+ raise LookupError("Tutorial.State: action <" + action_name + "> is not defined")
def get_action_dict(self):
"""
+ Return the reference to the internal action dictionary.
+
@return A dictionary of actions that the state will execute
"""
return self._actions
@@ -611,7 +637,7 @@ class State(object):
@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
+ @raise LookupError 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
@@ -621,7 +647,7 @@ class State(object):
self._transitions[transition_name] = new_transition
return old_transition
else:
- raise NameError("Tutorial.State: transition <" + transition_name + "> is not defined")
+ raise LookupError("Tutorial.State: transition <" + transition_name + "> is not defined")
def delete_transition(self, transition_name):
"""
@@ -629,15 +655,17 @@ class State(object):
@param transition_name The name of the transition to delete
@return The transition deleted
- @raise NameError if transition_name doesn't exist
+ @raise LookupError if transition_name doesn't exist
"""
if self._transitions.has_key(transition_name):
return self._transitions.pop(transition_name)
else:
- raise NameError("Tutorial.State: transition <" + transition_name + "> is not defined")
+ raise LookupError("Tutorial.State: transition <" + transition_name + "> is not defined")
def get_transition_dict(self):
"""
+ Return the reference to the internal transition dictionary.
+
@return The dictionary of transitions associated with this state.
"""
return self._transitions
@@ -660,7 +688,7 @@ class State(object):
#TODO use the action class name to generate a name
# to make it easier to debug and know what we are
# manipulating
- name = self.name + "/" + "action" + str(self.action_name_nb)
+ name = self.name + Tutorial._NAME_SEPARATOR + "action" + str(self.action_name_nb)
self.action_name_nb += 1
return name
@@ -676,10 +704,28 @@ class State(object):
#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 = self.name + "/" + "transition" + str(self.transition_name_nb)
+ name = self.name + Tutorial._NAME_SEPARATOR + "transition" + str(self.transition_name_nb)
self.transition_name_nb += 1
return name
+ def __eq__(self, otherState):
+ """
+ Compare current state to otherState.
+
+ Two states are considered equal if and only if:
+ -every action in this state has a matching action in the
+ other state with the same properties and values
+ -every event filters in this state has a matching filter in the
+ other state having the same properties and values
+ -both states have the same name.
+
+
+ @param otherState The state that will be compared to this one
+ @return True if the states are the same, False otherwise
+` """
+ raise NotImplemented
+
+
################## Error Handling and Exceptions ##############################