# Buggy code
def get_substituted_expressions(self, variables=None, include_subexpressions=False):
    """
    Return a list of ``(varname, expr)`` tuples, containing all
    differential equations (and optionally subexpressions) with all the
    subexpression variables substituted with the respective expressions.

    Parameters
    ----------
    variables : dict, optional
        A mapping of variable names to `Variable`/`Function` objects.
    include_subexpressions : bool
        Whether also to return substituted subexpressions. Defaults to
        ``False``.

    Returns
    -------
    expr_tuples : list of (str, `CodeString`)
        A list of ``(varname, expr)`` tuples, where ``expr`` is a
        `CodeString` object with all subexpression variables substituted
        with the respective expression.
    """
    if self._substituted_expressions is None:
        self._substituted_expressions = []
        substitutions = {}
        for eq in self.ordered:
            # Skip parameters
            if eq.expr is None:
                continue

            new_sympy_expr = str_to_sympy(eq.expr.code, variables).xreplace(
                substitutions
            )
            new_str_expr = sympy_to_str(new_sympy_expr)
            expr = Expression(new_str_expr)

            if eq.type == SUBEXPRESSION:
                substitutions.update(
                    {
                        sympy.Symbol(eq.varname, real=True): str_to_sympy(
                            expr.code, variables
                        )
                    }
                )
                self._substituted_expressions.append((eq.varname, expr))
            elif eq.type == DIFFERENTIAL_EQUATION:
                #  a differential equation that we have to check
                self._substituted_expressions.append((eq.varname, expr))
            else:
                raise AssertionError("Unknown equation type %s" % eq.type)

    if include_subexpressions:
        return self._substituted_expressions
    else:
        return [
            (name, expr)
            for name, expr in self._substituted_expressions
            if self[name].type == DIFFERENTIAL_EQUATION
        ]


# Traceback (IndexError)
BrianObjectException: Original error and traceback:
Traceback (most recent call last):
File "miniconda2/envs/brian/lib/python2.7/site-packages/brian2/codegen/runtime/numpy_rt/numpy_rt.py", line 246, in run
exec(self.compiled_code, self.namespace)
File "(string)", line 19, in <module>
File "miniconda2/envs/brian/lib/python2.7/site-packages/brian2/input/timedarray.py", line 230, in unitless_timed_array_func
return values[timestep, i]
IndexError: arrays used as indices must be of integer (or boolean) type

Error encountered with object named "neurongroup".
Object was created here (most recent call only, full details in debug log):
File "<ipython-input-6-321ca0774a4a>", line 18, in <module>
method='euler')

An exception occured during the execution of code object neurongroup_stateupdater_codeobject.
The error was raised in the following line:
_v = (_lio_1 * I(t, 2.0 + i)) + v
IndexError: arrays used as indices must be of integer (or boolean) type
(See above for original error message and traceback.)

# Fixed code
def get_substituted_expressions(self, variables=None, include_subexpressions=False):
    """
    Return a list of ``(varname, expr)`` tuples, containing all
    differential equations (and optionally subexpressions) with all the
    subexpression variables substituted with the respective expressions.

    Parameters
    ----------
    variables : dict, optional
        A mapping of variable names to `Variable`/`Function` objects.
    include_subexpressions : bool
        Whether also to return substituted subexpressions. Defaults to
        ``False``.

    Returns
    -------
    expr_tuples : list of (str, `CodeString`)
        A list of ``(varname, expr)`` tuples, where ``expr`` is a
        `CodeString` object with all subexpression variables substituted
        with the respective expression.
    """
    if self._substituted_expressions is None:
        self._substituted_expressions = []
        substitutions = {}
        for eq in self.ordered:
            # Skip parameters
            if eq.expr is None:
                continue

            new_sympy_expr = str_to_sympy(eq.expr.code, variables).xreplace(
                substitutions
            )
            new_str_expr = sympy_to_str(new_sympy_expr)
            expr = Expression(new_str_expr)

            if eq.type == SUBEXPRESSION:
                if eq.var_type == INTEGER:
                    sympy_var = sympy.Symbol(eq.varname, integer=True)
                else:
                    sympy_var = sympy.Symbol(eq.varname, real=True)
                substitutions.update({sympy_var: str_to_sympy(expr.code, variables)})
                self._substituted_expressions.append((eq.varname, expr))
            elif eq.type == DIFFERENTIAL_EQUATION:
                #  a differential equation that we have to check
                self._substituted_expressions.append((eq.varname, expr))
            else:
                raise AssertionError("Unknown equation type %s" % eq.type)

    if include_subexpressions:
        return self._substituted_expressions
    else:
        return [
            (name, expr)
            for name, expr in self._substituted_expressions
            if self[name].type == DIFFERENTIAL_EQUATION
        ]