From 04adfe4155e1bb37609edfe78ae67b361f51e0cf Mon Sep 17 00:00:00 2001 From: Byron Ullauri Date: Thu, 3 Jan 2019 04:03:13 -0500 Subject: Provide basic math operations on bills (#413) * allow basic math ops in amount field for bills form * docs: changing compile-translations to build-translations --- ihatemoney/utils.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'ihatemoney/utils.py') diff --git a/ihatemoney/utils.py b/ihatemoney/utils.py index ec22834..2fac4ef 100644 --- a/ihatemoney/utils.py +++ b/ihatemoney/utils.py @@ -1,5 +1,8 @@ +from __future__ import division import base64 import re +import ast +import operator from io import BytesIO, StringIO import jinja2 @@ -206,3 +209,33 @@ class IhmJSONEncoder(JSONEncoder): except ImportError: pass return JSONEncoder.default(self, o) + + +def eval_arithmetic_expression(expr): + def _eval(node): + # supported operators + operators = { + ast.Add: operator.add, + ast.Sub: operator.sub, + ast.Mult: operator.mul, + ast.Div: operator.truediv, + ast.USub: operator.neg, + } + + if isinstance(node, ast.Num): # + return node.n + elif isinstance(node, ast.BinOp): # + return operators[type(node.op)](_eval(node.left), _eval(node.right)) + elif isinstance(node, ast.UnaryOp): # e.g., -1 + return operators[type(node.op)](_eval(node.operand)) + else: + raise TypeError(node) + + expr = str(expr) + + try: + result = _eval(ast.parse(expr, mode='eval').body) + except (SyntaxError, TypeError, ZeroDivisionError, KeyError): + raise ValueError("Error evaluating expression: {}".format(expr)) + + return result -- cgit v1.1