>>> evaluate('2**6')
    64
    >>> evaluate('1 + 2*3**(2 + 2) / (6 + -7)')
    -161.0
    >>> evaluate('5 < 4')
    False
    >>> evaluate('5 < a < 10', a=6)
    True

def evaluate(expr, **variables):
    """
    >>> evaluate('2**6')
    64
    >>> evaluate('1 + 2*3**(2 + 2) / (6 + -7)')
    -161.0
    >>> evaluate('5 < 4')
    False
    >>> evaluate('5 < a < 10', a=6)
    True
    """
    module = ast.parse(expr)  # Module(body=[Expr(value=...)])
    if len(module.body) != 1:
        raise BadExpression(
            "One expression expected, got %d." % len(module.body))

    expression = module.body[0]
    if not isinstance(expression, ast.Expr):
        raise BadExpression(
            "Expression expected, got %s instead."
            % expression.__class__.__name__
        )

    return _eval(expression.value, variables)