def get_chain_as_string(self,
                            num_states,
                            seed=None,
                            random_seed_weighted=False,
                            delimiter=None):
        '''
        Call the get_chain method, then concatenate it to a string. This will only work if the 
        source material is also made of strings.

        @param num_states Number of states to be included in the chain.
        @type int

        @param seed The state with which to seed the state. If None is passed to this parameter, a 
                    state will be selected randomly.
        @type seed state

        @param random_seed_weighted If set to True, a random position in the source is chosen and a 
                                    a state is chosen from among those at this position. This only 
                                    applies if seed is None. [Default: False]
        @type random_seed_weighted bool

        @param delimiter Break if the chain encounters anything in this list. (Not implemented)
        @type delimiter (str, list, set, tuple)
        
        @return Returns a chain of states as a string.

        @throws TypeError Thrown if the source is not made up of strings or characters.
        @throws ValueError Thrown if num_states is not a positive integer.
        @throws InvalidMarkovStateError Thrown if seed is not a valid state.
        '''
        chain = self.get_chain(num_states=num_states,
                               seed=seed,
                               random_seed_weighted=random_seed_weighted)

        out_chain = ''
        for state in chain:
            input_validation.valid_string_type(state, throw_error=True)

            out_chain += state

        return out_chain
    def get_chain_as_string(self, num_states, 
                            seed=None, random_seed_weighted=False, 
                            delimiter=None):
        '''
        Call the get_chain method, then concatenate it to a string. This will only work if the 
        source material is also made of strings.

        @param num_states Number of states to be included in the chain.
        @type int

        @param seed The state with which to seed the state. If None is passed to this parameter, a 
                    state will be selected randomly.
        @type seed state

        @param random_seed_weighted If set to True, a random position in the source is chosen and a 
                                    a state is chosen from among those at this position. This only 
                                    applies if seed is None. [Default: False]
        @type random_seed_weighted bool

        @param delimiter Break if the chain encounters anything in this list. (Not implemented)
        @type delimiter (str, list, set, tuple)
        
        @return Returns a chain of states as a string.

        @throws TypeError Thrown if the source is not made up of strings or characters.
        @throws ValueError Thrown if num_states is not a positive integer.
        @throws InvalidMarkovStateError Thrown if seed is not a valid state.
        '''
        chain = self.get_chain(num_states=num_states, 
                               seed=seed, 
                               random_seed_weighted=random_seed_weighted)

        out_chain = ''
        for state in chain:
            input_validation.valid_string_type(state, throw_error=True)

            out_chain += state

        return out_chain
	def _parse_setting(self, setting_value):
		'''
		Some string settings include local variables. This method replaces them.
		The possible variables are:

		$base_dir		The path to the install directory.
		$pref_dir 		The path to the preferences directory
		$source_dir 	The path to the sources directory

		@param setting_value The value of the setting.
		@type setting_value any
		
		@return Returns the parsed value of the setting. If this is not a string, the raw value is
				returned.
		'''

		if not valid_string_type(setting_value, throw_error=False):
			return setting_value

		for key in self._settings_replacements.keys():
			setting_value = setting_value.replace(key, self._settings_replacements[key])

		return setting_value
    def _parse_setting(self, setting_value):
        '''
		Some string settings include local variables. This method replaces them.
		The possible variables are:

		$base_dir		The path to the install directory.
		$pref_dir 		The path to the preferences directory
		$source_dir 	The path to the sources directory

		@param setting_value The value of the setting.
		@type setting_value any
		
		@return Returns the parsed value of the setting. If this is not a string, the raw value is
				returned.
		'''

        if not valid_string_type(setting_value, throw_error=False):
            return setting_value

        for key in self._settings_replacements.keys():
            setting_value = setting_value.replace(
                key, self._settings_replacements[key])

        return setting_value
    def __init__(self,
                 name,
                 source=None,
                 min_state_length=1,
                 max_state_length=1,
                 delimiter=None):
        '''
        The constructor for the class.
        
        @param name The name of the database. This will be used for file saving, so special 
                    characters are not allowed.
        @type name str

        @param source An ordered list of states to be used in the Markov chain.
        @type source (str, unicode, list, tuple, dict)
        
        @param min_state_length The minimum number of consecutive entries in the source which can 
                                be considered a single state.
        @type min_state_length int
        
        @param max_state_length The maximum number of consecutive entries in the source that can
                                 be considered a single state.
        @type max_state_length int

        @param delimiter Delimiter marks the end of a given state (space for words, . for sentences,
                          etc.) If None then no delimiter is used. The delimiter will be included in
                          the states.
        @type delimiter state 

        @throws TypeError Thrown if an invalid type is passed to one of the arguments.
        @throws ValueError Thrown if an invalid value is passed to one of the arguments.
        '''

        # Validate the inputs
        input_validation.valid_string_type(name, throw_error=True)

        if re.match('^[\w_ -]+$', name) is None:
            raise ValueError('"name" can only contain alphanumeric characters, spaces, dashes '+\
                             ' and underscores.')

        if min_state_length < 1:
            raise ValueError('min_state_length must be a positive integer.')

        if max_state_length < 1:
            raise ValueError('max_state_length must be a positive integer.')

        # Basic values
        self._source = None
        self._source_by_state = [
        ]  # States beginning at each position in the source.
        self._state_index = []
        self._state_delimited = []
        self._state_positions = []
        self._state_occurances = []
        self._included_states = 0
        self._valid_source = False
        self._db_generated = False
        self._rng = random.SystemRandom()
        self._saved_loc = None

        # Construct the object
        self.name = name
        if source is not None:
            self._add_source(source)

        self._delimiter = delimiter

        self.min_state_length = min_state_length
        self.max_state_length = max_state_length
        self._rng = random.SystemRandom()
    def load(self, file_path=None):
        '''
        Load a saved database from file.

        @param file_path The path of the file to load. If None, this will be generated from the 
                         default save location and the name passed to the constructor.
        @type file_path str

        @throws TypeError Raised when argument inputs are of the wrong type.
        @throws ValueError Raised when an invalid path is passed to file_path
        '''
        if file_path is None:
            if os.path.exists(self._saved_loc):
                # For recalling a previous state.
                file_path = self._saved_loc
            else:
                base_fname = os.path.join(SettingsReader().getValue(\
                    SettingsHelper.markov_source_loc_key), self.name)

                decompressed_file_exists = os.path.exists(base_fname +
                                                          _markov_ext)
                compressed_file_exists = os.path.exists(base_fname + _m_zip)

                if decompressed_file_exists and compressed_file_exists:
                    # Find out which one's newer.
                    if os.path.getmtime(base_fname+_markov_ext) >= \
                       os.path.getmtime(base_fname+_m_zip):
                        fext = _markov_ext
                    else:
                        fext = _m_zip
                elif decompressed_file_exists:
                    fext = _markov_ext
                else:
                    fext = _m_zip

                file_path = os.path.join(SettingsReader().getValue(\
                                     SettingsHelper.markov_source_loc_key), self.name+fext)

        # Raise an error if this is an invalid string type.
        input_validation.valid_string_type(file_path, throw_error=True)

        if not os.path.exists(file_path):
            raise ValueError('Path is not valid.')

        # Load the JSON file.
        with open(file_path, 'r') as mdb_file:
            if file_path.endswith(_m_zip):  # Compressed
                ddata = zlib.decompress(mdb_file.read())
                markov_dict = json.loads(ddata)
            else:
                markov_dict = json.load(mdb_file)
        try:
            self.name = markov_dict['name']
            self._valid_source = markov_dict['valid_source']
            if self._valid_source:
                self._add_source(markov_dict['source'])

            self._db_generated = markov_dict['db_generated']

            if self._db_generated:
                self._source_by_state = markov_dict['source_by_state']
                self._state_index = markov_dict['state_index']
                self._state_occurances = markov_dict['state_occurances']
                self._included_states = markov_dict['included_states']
                self._state_delimited = markov_dict['state_delimited']

        except KeyError as ke:
            raise InvalidMarkovDatabaseFile('Error reading Markov file key ' +
                                            ke.args[0],
                                            ke=ke)

        self._saved_loc = file_path
    def __init__(self, name, source=None, min_state_length=1, max_state_length=1,
                       delimiter=None):
        '''
        The constructor for the class.
        
        @param name The name of the database. This will be used for file saving, so special 
                    characters are not allowed.
        @type name str

        @param source An ordered list of states to be used in the Markov chain.
        @type source (str, unicode, list, tuple, dict)
        
        @param min_state_length The minimum number of consecutive entries in the source which can 
                                be considered a single state.
        @type min_state_length int
        
        @param max_state_length The maximum number of consecutive entries in the source that can
                                 be considered a single state.
        @type max_state_length int

        @param delimiter Delimiter marks the end of a given state (space for words, . for sentences,
                          etc.) If None then no delimiter is used. The delimiter will be included in
                          the states.
        @type delimiter state 

        @throws TypeError Thrown if an invalid type is passed to one of the arguments.
        @throws ValueError Thrown if an invalid value is passed to one of the arguments.
        '''
        
        # Validate the inputs
        input_validation.valid_string_type(name, throw_error=True)

        if re.match('^[\w_ -]+$', name) is None:
            raise ValueError('"name" can only contain alphanumeric characters, spaces, dashes '+\
                             ' and underscores.')

        if min_state_length < 1:
            raise ValueError('min_state_length must be a positive integer.')

        if max_state_length < 1:
            raise ValueError('max_state_length must be a positive integer.')
        
        # Basic values
        self._source = None
        self._source_by_state = []           # States beginning at each position in the source.
        self._state_index = []
        self._state_delimited = []
        self._state_positions = []
        self._state_occurances = []
        self._included_states = 0
        self._valid_source = False
        self._db_generated = False
        self._rng = random.SystemRandom()
        self._saved_loc = None
        
        # Construct the object
        self.name = name
        if source is not None:
            self._add_source(source)

        self._delimiter = delimiter

        self.min_state_length=min_state_length
        self.max_state_length=max_state_length
        self._rng = random.SystemRandom()
    def load(self, file_path=None):
        '''
        Load a saved database from file.

        @param file_path The path of the file to load. If None, this will be generated from the 
                         default save location and the name passed to the constructor.
        @type file_path str

        @throws TypeError Raised when argument inputs are of the wrong type.
        @throws ValueError Raised when an invalid path is passed to file_path
        '''
        if file_path is None:
            if os.path.exists(self._saved_loc):
                # For recalling a previous state.
                file_path = self._saved_loc
            else:
                base_fname = os.path.join(SettingsReader().getValue(\
                    SettingsHelper.markov_source_loc_key), self.name)
                
                decompressed_file_exists = os.path.exists(base_fname+_markov_ext)
                compressed_file_exists = os.path.exists(base_fname+_m_zip)

                if decompressed_file_exists and compressed_file_exists:
                    # Find out which one's newer.
                    if os.path.getmtime(base_fname+_markov_ext) >= \
                       os.path.getmtime(base_fname+_m_zip):
                        fext = _markov_ext
                    else:
                        fext = _m_zip
                elif decompressed_file_exists:
                    fext = _markov_ext
                else:
                    fext = _m_zip
                
                file_path = os.path.join(SettingsReader().getValue(\
                                     SettingsHelper.markov_source_loc_key), self.name+fext)

        # Raise an error if this is an invalid string type.
        input_validation.valid_string_type(file_path, throw_error=True) 

        if not os.path.exists(file_path):
            raise ValueError('Path is not valid.')

        # Load the JSON file.
        with open(file_path, 'r') as mdb_file:
            if file_path.endswith(_m_zip):  # Compressed
                ddata = zlib.decompress(mdb_file.read())
                markov_dict = json.loads(ddata)
            else:
                markov_dict = json.load(mdb_file)
        try:
            self.name = markov_dict['name']
            self._valid_source = markov_dict['valid_source']
            if self._valid_source:
                self._add_source(markov_dict['source'])
    
            self._db_generated = markov_dict['db_generated']

            if self._db_generated:
                self._source_by_state = markov_dict['source_by_state']
                self._state_index = markov_dict['state_index']
                self._state_occurances = markov_dict['state_occurances']
                self._included_states = markov_dict['included_states']
                self._state_delimited = markov_dict['state_delimited']

        except KeyError as ke:
            raise InvalidMarkovDatabaseFile('Error reading Markov file key '+ke.args[0], ke=ke)

        self._saved_loc = file_path