# Path: sfc_models/utils.py
# def list_tokens(s):
#     """
#     Return a list of all NAME tokens (which can be variables, or function names) in a string.
# 
#     >>> list_tokens('x = foo + cat()')
#     ['x', 'foo', 'cat']
#     >>> list_tokens('2 + 3')
#     []
# 
#     :param s: str
#     :return: list
#     """
#     result = []
#     if is_python_3:
#         g = tokenize.tokenize(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME:  # find NAME tokens
#                 result.append(tokval)
#     else:  # pragma: no cover   [Do my coverage on Python 3]
#         g = tokenize.generate_tokens(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME:  # find NAME tokens
#                 result.append(tokval)
#     return result
# 
# def get_invalid_variable_names():
#     """
#     Get a list of invalid variable names for use in sfc_model equations.
# 
#     Includes mathematical operators in module 'math'.
# 
#     Cannot use 'k', as that is the discrete time axis step variable.
# 
#     :return: list
#     """
#     internal = ['self', 'None', 'k']
#     kw = keyword.kwlist
#     if is_python_3:
#         built = dir(builtins)
#     else:  # pragma: no cover
#         built = dir(__builtin__)
#     out = internal + kw + built + dir(math)
#     return list(out)
# 
# def get_invalid_tokens():
#     """
#     Get a list of invalid tokens that can be used inside sfc_model equations.
# 
#     :return: list
#     """
#     internal = ['self', 'None']
#     kw = keyword.kwlist
#     if is_python_3:
#         built = dir(builtins)
#     else:  # pragma: no cover
#         built = dir(__builtin__)
#     out = internal + kw + built
#     # Need to add back in some semi-mathematical operations
#     good_tokens = ('float', 'max', 'min', 'sum', 'pow', 'abs', 'round', 'pow')
#     out = (x for x in out if x not in good_tokens)
#     return list(out)
# 
# def replace_token(s, target, replacement):
#     """
#     replace_token
# 
#     Replaces NAME tokens (variables, functions) in a string (assumed to be equivalent to Python code with a new token.)
# 
#     Much safer than string replacement, as it does not hit cases where the target string is a part
#     of a different variable (token).
# 
#     >>> replace_token('m_x =(x - x_1)', 'x', 'b')
#     'm_x =(b -x_1 )'
# 
#     >>> replace_token('Little Bunny Foofoo says foo to you', 'foo', 'hello')
#     'Little Bunny Foofoo says hello to you '
# 
#     Note that the function looks at tokens that could be variables; the contents of strings are not touched.
#     
#     >>> replace_token('a = "a fool and his money"', 'a', 'x')
#     'x ="a fool and his money"'
# 
#     (Note that spacing can be affected, as seen in these examples. Do not rely upon any particular behaviour for
#     spaces.)
# 
#     :param s: str
#     :param target: str
#     :param replacement: str
#     :return: str
#     """
#     result = []
#     if is_python_3:
#         g = tokenize.tokenize(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME and tokval == target:  # replace NAME tokens
#                 result.append((NAME, replacement))
#             else:
#                 result.append((toknum, tokval))
#         return untokenize(result).decode('utf-8')
#     else:  # pragma: no cover   [Do my coverage on Python 3]
#         g = tokenize.generate_tokens(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME and tokval == target:  # replace NAME tokens
#                 result.append((NAME, replacement))
#             else:
#                 result.append((toknum, tokval))
#         return str(untokenize(result).decode('utf-8'))


from sfc_models.utils import list_tokens, get_invalid_variable_names, get_invalid_tokens, replace_token
        for var in self.AllEquations:
            eq = self.AllEquations[var]
            self.Tokens[var] = list_tokens(eq)

    def ValidateInputs(self):
        """
        Are the equations valid? Currently, only looks for reserved words, and built-in names.

        >>> p = EquationParser()
        >>> p.ParseString('yield = .05')
        ''
        >>> p.ValidateInputs()
        Traceback (most recent call last):
        ...
        NameError: Cannot use variable name: yield, as it is reserved.
        Call sfc_models.utils.get_invalid_variable_names() to get full list.

        >>> p = EquationParser()
        >>> p.ParseString('inc = 2 * import')
        ''
        >>> p.ValidateInputs()
        Traceback (most recent call last):
        ...
        NameError: Cannot use token in equation: import, as it is reserved.
        Call sfc_models.utils.get_invalid_tokens() to get full list.


        :return: None
        """
        bad_variables = get_invalid_variable_names()

# Path: sfc_models/utils.py
# def list_tokens(s):
#     """
#     Return a list of all NAME tokens (which can be variables, or function names) in a string.
# 
#     >>> list_tokens('x = foo + cat()')
#     ['x', 'foo', 'cat']
#     >>> list_tokens('2 + 3')
#     []
# 
#     :param s: str
#     :return: list
#     """
#     result = []
#     if is_python_3:
#         g = tokenize.tokenize(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME:  # find NAME tokens
#                 result.append(tokval)
#     else:  # pragma: no cover   [Do my coverage on Python 3]
#         g = tokenize.generate_tokens(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME:  # find NAME tokens
#                 result.append(tokval)
#     return result
# 
# def get_invalid_variable_names():
#     """
#     Get a list of invalid variable names for use in sfc_model equations.
# 
#     Includes mathematical operators in module 'math'.
# 
#     Cannot use 'k', as that is the discrete time axis step variable.
# 
#     :return: list
#     """
#     internal = ['self', 'None', 'k']
#     kw = keyword.kwlist
#     if is_python_3:
#         built = dir(builtins)
#     else:  # pragma: no cover
#         built = dir(__builtin__)
#     out = internal + kw + built + dir(math)
#     return list(out)
# 
# def get_invalid_tokens():
#     """
#     Get a list of invalid tokens that can be used inside sfc_model equations.
# 
#     :return: list
#     """
#     internal = ['self', 'None']
#     kw = keyword.kwlist
#     if is_python_3:
#         built = dir(builtins)
#     else:  # pragma: no cover
#         built = dir(__builtin__)
#     out = internal + kw + built
#     # Need to add back in some semi-mathematical operations
#     good_tokens = ('float', 'max', 'min', 'sum', 'pow', 'abs', 'round', 'pow')
#     out = (x for x in out if x not in good_tokens)
#     return list(out)
# 
# def replace_token(s, target, replacement):
#     """
#     replace_token
# 
#     Replaces NAME tokens (variables, functions) in a string (assumed to be equivalent to Python code with a new token.)
# 
#     Much safer than string replacement, as it does not hit cases where the target string is a part
#     of a different variable (token).
# 
#     >>> replace_token('m_x =(x - x_1)', 'x', 'b')
#     'm_x =(b -x_1 )'
# 
#     >>> replace_token('Little Bunny Foofoo says foo to you', 'foo', 'hello')
#     'Little Bunny Foofoo says hello to you '
# 
#     Note that the function looks at tokens that could be variables; the contents of strings are not touched.
#     
#     >>> replace_token('a = "a fool and his money"', 'a', 'x')
#     'x ="a fool and his money"'
# 
#     (Note that spacing can be affected, as seen in these examples. Do not rely upon any particular behaviour for
#     spaces.)
# 
#     :param s: str
#     :param target: str
#     :param replacement: str
#     :return: str
#     """
#     result = []
#     if is_python_3:
#         g = tokenize.tokenize(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME and tokval == target:  # replace NAME tokens
#                 result.append((NAME, replacement))
#             else:
#                 result.append((toknum, tokval))
#         return untokenize(result).decode('utf-8')
#     else:  # pragma: no cover   [Do my coverage on Python 3]
#         g = tokenize.generate_tokens(BytesIO(s.encode('utf-8')).readline)  # tokenize the string
#         for toknum, tokval, _, _, _ in g:
#             if toknum == NAME and tokval == target:  # replace NAME tokens
#                 result.append((NAME, replacement))
#             else:
#                 result.append((toknum, tokval))
#         return str(untokenize(result).decode('utf-8'))


# Path: sfc_models/equation_parser.py
from sfc_models.utils import list_tokens, get_invalid_variable_names, get_invalid_tokens, replace_token

        for var in self.AllEquations:
            eq = self.AllEquations[var]
            self.Tokens[var] = list_tokens(eq)

    def ValidateInputs(self):
        """
        Are the equations valid? Currently, only looks for reserved words, and built-in names.

        >>> p = EquationParser()
        >>> p.ParseString('yield = .05')
        ''
        >>> p.ValidateInputs()
        Traceback (most recent call last):
        ...
        NameError: Cannot use variable name: yield, as it is reserved.
        Call sfc_models.utils.get_invalid_variable_names() to get full list.

        >>> p = EquationParser()
        >>> p.ParseString('inc = 2 * import')
        ''
        >>> p.ValidateInputs()
        Traceback (most recent call last):
        ...
        NameError: Cannot use token in equation: import, as it is reserved.
        Call sfc_models.utils.get_invalid_tokens() to get full list.


        :return: None
        """
        bad_variables = get_invalid_variable_names()

        bad_tokens = get_invalid_tokens()