From 1176b6f6082aaffddf4b37b3d9602ce41cc7a6e8 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Sun, 21 Jan 2018 18:16:08 +0300 Subject: [PATCH] Basic evaluation for trees --- mapytex/calculus/core/evaluate.py | 46 +++++++++++++++++++++++++++++++ mapytex/calculus/core/operator.py | 32 +++++++++++++++++---- mapytex/calculus/core/tree.py | 14 +++++++++- 3 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 mapytex/calculus/core/evaluate.py diff --git a/mapytex/calculus/core/evaluate.py b/mapytex/calculus/core/evaluate.py new file mode 100644 index 0000000..3e2f75a --- /dev/null +++ b/mapytex/calculus/core/evaluate.py @@ -0,0 +1,46 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Evaluating a binary tree +""" + +from .operator import OPERATORS + +def compute(node, left_v, right_v): + """ + Computing a node + + :example: + + >>> compute("+", 1, 2) + 3 + >>> compute("-", 1, 2) + -1 + >>> compute("-", None, 2) + -2 + + """ + op = OPERATORS[node] + lv = left_v + rv = right_v + if lv is None: + return op["_operate"](rv)() + + try: + return op["operate"](lv)(rv) + except NotImplemented: + return op["roperate"](rv)(lv) + + + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/mapytex/calculus/core/operator.py b/mapytex/calculus/core/operator.py index 34781fa..21ce8d8 100644 --- a/mapytex/calculus/core/operator.py +++ b/mapytex/calculus/core/operator.py @@ -6,13 +6,33 @@ # # Distributed under terms of the MIT license. - OPERATORS = { - "+": {"priority":0}, - "-": {"priority":1}, - "*": {"priority":2}, - "/": {"priority":3}, - "^": {"priority":4}, + "+": {'repr': "+", + 'precedence': 0, + 'operate': lambda x: x.__getattribute__("__add__"), + 'roperate': lambda x: x.__getattribute__("__radd__"), + }, + "-": {'repr': "-", + 'precedence': 1, + '_operate': lambda x: x.__getattribute__("__neg__"), + 'operate': lambda x: x.__getattribute__("__sub__"), + 'roperate': lambda x: x.__getattribute__("__rsub__"), + }, + "*": {'repr': "*", + 'precedence': 2, + 'operate': lambda x: x.__getattribute__("__mul__"), + 'roperate': lambda x: x.__getattribute__("__rmul__"), + }, + "/": {'repr': "/", + 'precedence': 3, + 'operate': lambda x: x.__getattribute__("__div__"), + 'roperate': lambda x: x.__getattribute__("__rdiv__"), + }, + "^": {'repr': "^", + 'precedence': 4, + 'operate': lambda x: x.__getattribute__("__pow__"), + 'roperate': lambda x: x.__getattribute__("__rpow__"), + }, } diff --git a/mapytex/calculus/core/tree.py b/mapytex/calculus/core/tree.py index f2b99c9..7a1f13c 100644 --- a/mapytex/calculus/core/tree.py +++ b/mapytex/calculus/core/tree.py @@ -243,7 +243,15 @@ class Tree(object): + > 3 * 4 > 2 - + >>> from .evaluate import compute + >>> tt = t.apply_on_last_level(compute) + >>> print(tt) + + + > 12 + > 2 + >>> ttt = tt.apply_on_last_level(compute) + >>> print(ttt) + 14 """ left_is_leaf = 0 right_is_leaf = 0 @@ -286,6 +294,10 @@ class Tree(object): >>> t.apply(to_nested) ('+', (('*', (3, 4)), 2)) + >>> from .evaluate import compute + >>> t.apply(compute) + 14 + """ try: left_value = self.left_value.apply(function)