Example #1
0
 def visit_Num(self, n):
     try:
         d = self.context.constants[type(n.n)]
         return d[n.n][self.dialect]
     except KeyError:
         pass
     return str(math2.int_or_float(n.n))
Example #2
0
    def add(self, expr):
        ''' add expr
        :return: bool True if it has been added
        '''

        if expr is None:
            return False
        try:
            k = expr()  # the key is the numeric value of expr
        except (TypeError, ValueError):
            return False

        if not math2.is_number(k):
            return False

        if type(k) is complex:
            return False

        if self.int:
            # limit to integers... but maybe we're extremely close
            k = math2.int_or_float(k)
            if not isinstance(k, int): return False

        if k < 0:
            return self.add(-expr)

        if self.max is not None and k > self.max:
            return False

        if k in self:
            if self.improve and expr.complexity() >= self[k].complexity():
                return False

        self[k] = expr
        return True
Example #3
0
File: expr.py Project: goulu/Goulib
 def visit_Num(self, n):
     try:
         d = self.context.constants[type(n.n)]
         return d[n.n][self.dialect]
     except KeyError:
         pass
     return str(math2.int_or_float(n.n))
Example #4
0
def div(a, b):
    res = math2.int_or_float(a / b)
    a2 = res * b
    if a == a2:
        return res
    # the division has rounded something, like (a+eps)/a =1
    # numpy.nextafter(res,res+math2.sign(a)*math2.sign(b))
    return res + math2.eps * math2.sign(a * b)
Example #5
0
def friedman(num):
    for e in gen(num):
        try:
            n = math2.int_or_float(e())  # cope with potential rounding problems
            if n == num and str(e) != str(num):  # concat is too easy ...
                yield (num, e)
        except GeneratorExit:  # https://stackoverflow.com/a/41115661/1395973
            return
        except:
            pass
Example #6
0
def friedman(num):
    for e in gen(num):
        try:
            # cope with potential rounding problems
            n = math2.int_or_float(e())
            if n == num and str(e) != str(num):  # concat is too easy ...
                yield (num, e)
        except GeneratorExit:  # https://stackoverflow.com/a/41115661/1395973
            return
        except:
            pass
Example #7
0
    def eval(self, node):
        '''safe eval of ast node : only functions and _operators listed above can be used

        :param node: ast.AST to evaluate
        :param ctx: dict of varname : value to substitute in node
        :return: number or expression string
        '''
        if isinstance(node, ast.Num):  # <number>
            return node.n
        elif isinstance(node, ast.Name):
            return self.variables.get(node.id, node.id)  # return value or var
        elif isinstance(node, ast.Attribute):
            return getattr(self.variables, [node.value.id], node.attr)
        elif isinstance(node, ast.Tuple):
            return tuple(self.eval(e) for e in node.elts)
        elif isinstance(node, ast.Call):
            params = [self.eval(arg) for arg in node.args]
            if node.func.id not in self.functions:
                raise NameError('%s function not allowed' % node.func.id)
            f = self.functions[node.func.id][0]
            res = f(*params)
            # try to correct small error
            return math2.int_or_float(res, 0, 1e-12)
        elif isinstance(node, ast.BinOp):  # <left> <operator> <right>
            op = self.operators[type(node.op)]
            left = self.eval(node.left)
            right = self.eval(node.right)
            if math2.is_number(left) and math2.is_number(right):
                res = op[0](left, right)
                # no correction here !
                return res
            else:
                return "%s%s%s" % (left, op[_dialect_python], right)
        elif isinstance(node, ast.UnaryOp):  # <operator> <operand> e.g., -1
            right = self.eval(node.operand)
            return self.operators[type(node.op)][0](right)
        elif isinstance(node, ast.Compare):
            left = self.eval(node.left)
            for op, right in zip(node.ops, node.comparators):
                # TODO: find what to do when multiple items in list
                return self.operators[type(op)][0](left, self.eval(right))
        elif isinstance(node, ast.NameConstant):
            return node.value
        else:
            logging.warning(ast.dump(node, False, False))
            return self.eval(node.body)  # last chance
Example #8
0
File: expr.py Project: goulu/Goulib
    def eval(self, node):
        '''safe eval of ast node : only functions and _operators listed above can be used

        :param node: ast.AST to evaluate
        :param ctx: dict of varname : value to substitute in node
        :return: number or expression string
        '''
        if isinstance(node, ast.Num):  # <number>
            return node.n
        elif isinstance(node, ast.Name):
            return self.variables.get(node.id, node.id)  # return value or var
        elif isinstance(node, ast.Attribute):
            return getattr(self[node.value.id], node.attr)
        elif isinstance(node, ast.Tuple):
            return tuple(self.eval(e) for e in node.elts)
        elif isinstance(node, ast.Call):
            params = [self.eval(arg) for arg in node.args]
            if not node.func.id in self.functions:
                raise NameError('%s function not allowed' % node.func.id)
            f = self.functions[node.func.id][0]
            res = f(*params)
            return math2.int_or_float(res, 0, 1e-12)  # try to correct small error
        elif isinstance(node, ast.BinOp):  # <left> <operator> <right>
            op = self.operators[type(node.op)]
            left = self.eval(node.left)
            right = self.eval(node.right)
            if math2.is_number(left) and math2.is_number(right):
                res = op[0](left, right)
                # no correction here !
                return res
            else:
                return "%s%s%s" % (left, op[_dialect_python], right)
        elif isinstance(node, ast.UnaryOp):  # <operator> <operand> e.g., -1
            right = self.eval(node.operand)
            return self.operators[type(node.op)][0](right)
        elif isinstance(node, ast.Compare):
            left = self.eval(node.left)
            for op, right in zip(node.ops, node.comparators):
                # TODO: find what to do when multiple items in list
                return self.operators[type(op)][0](left, self.eval(right))
        elif isinstance(node, ast.NameConstant):
            return node.value
        else:
            logging.warning(ast.dump(node, False, False))
            return self.eval(node.body)  # last chance
Example #9
0
    def add(self, expr):
        ''' add expr
        :return: bool True if it has been added
        '''

        if expr is None:
            return False
        try:
            k = expr()  # the key is the numeric value of expr
        except (TypeError, ValueError):
            return False

        if not math2.is_number(k):
            return False

        if type(k) is complex:
            return False

        if self.int:
            # limit to integers... but maybe we're extremely close
            k = math2.int_or_float(k)
            if not isinstance(k, int):
                return False

        if k < 0:
            return self.add(-expr)

        if self.max is not None and k > self.max:
            return False

        if k in self:
            if self.improve and expr.complexity() >= self[k].complexity():
                return False

        self[k] = expr
        return True
Example #10
0
def div(a, b):
    res = math2.int_or_float(a / b)
    a2 = res * b
    if a == a2: return res
    # the division has rounded something, like (a+eps)/a =1
    return res + math2.eps * math2.sign(a * b)  # numpy.nextafter(res,res+math2.sign(a)*math2.sign(b))