def handle_zeros_for_point(self, point):
     """
     Checks if the function can be parsed, and if it can't, it sends the point to be fixed
     """
     try:
         FunctionParser.parse(point['formula'])
     except InvalidTokenException as e:
         # function cannot be parsed
         self.fix_zeros_for_point(point, e.position)
 def handle_parameters_for_point(self, point):
     """
     If the equation is valid, it will pass the point and the expression tree to get fixed
     """
     try:
         expression_tree = FunctionParser.parse(point['formula'])
         if len(expression_tree['identifier_names']) > 0:
             self.fix_parameters_for_point(point, expression_tree['identifier_names'])
     except:
         print point['id']
    def __init__(self):
        self.parser = Parser()
        self.operators = self.parser.get_operators()
        self.functions = {
            '+': lambda a, b: a + b,
            '-': lambda a, b: a - b,
            '*': lambda a, b: a * b,
            '^': math.pow,
            '/': lambda a, b: a / b,
            '%': lambda a, b: a % b,
            '<': lambda a, b: a < b,
            '>': lambda a, b: a > b,
            '==': lambda a, b: a == b,
            '!=': lambda a, b: a != b,
            '<=': lambda a, b: a <= b,
            '>=': lambda a, b: a >= b,
            '!': math.factorial,
            'sum': lambda *elements: sum(elements),
            'abs': lambda number: abs(number),
            'sin': math.sin,
            'asin': math.asin,
            'asinh': math.asinh,
            'cos': math.cos,
            'acos': math.acos,
            'acosh': math.acosh,
            'tg': math.tan,
            'atg': math.atan,
            'atgh': math.atanh,
            'max': max,
            'min': min,
            'ln': math.log,
            'log': math.log,
            'log10': math.log10,
        }
        self.parser.functions = self.get_functions()

        self.symbols = {
            'pi': math.pi,
            'e': math.e,
            'inf': math.inf,
            'nan': math.nan,
            'tau': math.tau,
        }

        self.equations = []
        self.end_function = None
        self.epsilon = None
        self.number_of_threads = None
        self.maximize = True
        self.multi_threading = True
        self.radian = None
        self.centre = None
        self.initialize()
def parse_formula(formula):
    try:
        expression_tree = FunctionParser.parse(formula["formula"])
        return jsonify(
            {
                "identifier_names": expression_tree["identifier_names"],
                "function_names": expression_tree["function_names"],
                "variable_names": expression_tree["variable_names"],
            }
        )
    except Exception as e:
        js = json.dumps(e.__dict__)
        response = Response(js, status=400, mimetype="application/json")
        return response
    def execute(self, command):
        command = command.split(' ', 1)
        args = []
        if len(command) is 2:
            command[1] = Parser.remove_spaces(command[1])
            args.extend(command[1].split('|'))

        command = command[0]

        result = None
        try:
            result = self.commands[command](*args)
        except KeyError:
            print(self.unknown_command(command))
        except TypeError as e:
            print(command + ": " + str(e))

        if result is not None:
            print(str(result))
Beispiel #6
0
from function_parser.FunctionParser import *

ex = 'sin(0.2.*x)'

parser = FunctionParser(ex)

f = parser.getFunction()

print(f(2))



class Executor:
    def __init__(self):
        self.parser = Parser()
        self.operators = self.parser.get_operators()
        self.functions = {
            '+': lambda a, b: a + b,
            '-': lambda a, b: a - b,
            '*': lambda a, b: a * b,
            '^': math.pow,
            '/': lambda a, b: a / b,
            '%': lambda a, b: a % b,
            '<': lambda a, b: a < b,
            '>': lambda a, b: a > b,
            '==': lambda a, b: a == b,
            '!=': lambda a, b: a != b,
            '<=': lambda a, b: a <= b,
            '>=': lambda a, b: a >= b,
            '!': math.factorial,
            'sum': lambda *elements: sum(elements),
            'abs': lambda number: abs(number),
            'sin': math.sin,
            'asin': math.asin,
            'asinh': math.asinh,
            'cos': math.cos,
            'acos': math.acos,
            'acosh': math.acosh,
            'tg': math.tan,
            'atg': math.atan,
            'atgh': math.atanh,
            'max': max,
            'min': min,
            'ln': math.log,
            'log': math.log,
            'log10': math.log10,
        }
        self.parser.functions = self.get_functions()

        self.symbols = {
            'pi': math.pi,
            'e': math.e,
            'inf': math.inf,
            'nan': math.nan,
            'tau': math.tau,
        }

        self.equations = []
        self.end_function = None
        self.epsilon = None
        self.number_of_threads = None
        self.maximize = True
        self.multi_threading = True
        self.radian = None
        self.centre = None
        self.initialize()

    def initialize(self):
        self.end_function = None
        self.epsilon = 0.1**6
        self.number_of_threads = 10
        self.maximize = True
        self.multi_threading = True
        self.radian = 1000.0
        self.centre = 0.0

    def add(self, equation):
        u"""Adds "subject to" function"""
        self.equations.append(equation)

    def set_radian(self, radian):
        self.radian = radian

    def remove(self, index):
        try:
            del self.equations[int(index)]
        except TypeError:
            print("Index out of range")

    def set_epsilon(self, eps):
        self.epsilon = float(eps)

    def set_end_function(self, equation):
        self.end_function = equation

    # TODO finish
    def create_custom_function(self, name, body):
        if type(body) is str:
            body = self.parser.parse(body)

        function_name = name

        exec("def " + function_name + "(*args):\n\tvar = self.get_decisibody ")
        self.functions[function_name] = name

    def clear(self):
        self.equations.clear()

    def clear_all(self):
        self.clear()
        self.initialize()

    def get_operators(self):
        return self.functions.keys()

    def get_functions(self):
        return [
            key for key, func in self.functions.items()
            if key not in self.operators
        ]

    def set_number_of_threads(self, size):
        self.number_of_threads = size

    def set_range(self, begging, end):
        self.radian = abs(end - begging) / 2
        self.centre = (end - begging)

    def get_decision_variables(self, expression=None):
        if expression is None:
            expression = self.end_function

        if type(expression) is str:
            expression = self.parser.parse(expression)

        excluded = list(self.get_operators()) + list(self.symbols.keys())

        def find_operators(tmp_expression):
            tmp = set()
            for item in tmp_expression:
                if type(item) is list:
                    tmp.update(find_operators(item))
                elif item not in excluded and type(item) is str:
                    tmp.add(item)
            return tmp

        return find_operators(expression)

    @staticmethod
    def fill_variables(equation, values):
        """ :param equation: list representing equation
            :param values: map, where keys are variables like x or y and values are floats
        """
        return forEach(equation, lambda x: values[x], lambda x: x in values)

    def calculate(self, equation):
        if type(equation) is str:
            result = self.parser.parse(equation)
        else:
            result = equation[:]

        # FIXME: it can be better
        if type(result[1]) is list:
            if len(result[1]) > 0:
                try:
                    if type(result[1][0]) is list:
                        result[1][0] = self.calculate(result[1][0])
                except TypeError:
                    pass

        if type(result[1]) is list:
            if len(result[1]) is 2:
                try:
                    if type(result[1][1]) is list:
                        result[1][1] = self.calculate(result[1][1])
                except TypeError:
                    pass

        return self.functions[result[0]](*result[1])

    def execute(self):
        # initialize
        radian = self.radian

        # parse string equations to list representations
        equations = forEach(self.equations,
                            lambda item: self.parser.parse(item),
                            recursion=False)
        end_function = self.parser.parse(self.end_function)

        # change constant symbols to matching floats
        equations = self.fill_variables(equations, self.symbols)

        variables = self.get_decision_variables()

        initial_point = {key: self.centre for key in variables}

        fields = self.ExecuteFields(
            initial_point,
            self.calculate(self.fill_variables(end_function, initial_point)))

        lock = Lock()
        if self.multi_threading:
            queue = Queue()

            def threads_task():
                while True:
                    item = queue.get()
                    if item is None:
                        break

                    item()
                    queue.task_done()

            threads = []
            for i in range(self.number_of_threads):
                t = Thread(target=threads_task)
                t.daemon = True
                threads.append(t)
                t.start()

        def number_of_samples():
            return int((radian + 10)**len(variables))

        def random_values():
            """:return point inside figure, where best_solution is center"""
            return {
                key: uniform(fields.best_point[key] - radian,
                             fields.best_point[key] + radian)
                for key in variables
            }

        def find_possible_result():
            point = random_values()
            if all([
                    self.calculate(self.fill_variables(equation, point))
                    for equation in equations
            ]):
                tmp_result = self.calculate(
                    self.fill_variables(end_function, point))

                with lock:
                    if self.maximize:
                        is_positive_difference = tmp_result > fields.best_result
                    else:
                        is_positive_difference = tmp_result < fields.best_result

                    if is_positive_difference:
                        fields.best_point = point
                        fields.best_result = tmp_result

        # end of initialization

        while radian - self.epsilon > 0:

            for index in range(number_of_samples()):
                if self.multi_threading:
                    queue.put(find_possible_result)
                else:
                    find_possible_result()

            if self.multi_threading:
                queue.join()

            print(radian, ":", fields.best_point, " - times:",
                  number_of_samples())
            radian *= 0.925

        return fields.best_point

    class ExecuteFields:
        def __init__(self, point, result):
            self.best_point = point
            self.best_result = result
            self.task_index = 0
    def load_calculations(self):
        wb = xlrd.open_workbook(self.file_path)
        sheet = wb.sheet_by_name("Calculations ID Table")

        self.calculations = dict()

        current_calculation = {
            "id": None,
            "code": None,
            "description": None,
            "formula": None,
            "parameters": set(),
            "units": None
        }
        for row_num in range(3, sheet.nrows + 1):
            if row_num < sheet.nrows:
                id = sheet.cell(row_num, 1).value
                code = sheet.cell(row_num, 2).value
                description = sheet.cell(row_num, 3).value
                formula = sheet.cell(row_num, 4).value
                energy_point_code = sheet.cell(row_num, 6).value
                numeric_point_code = sheet.cell(row_num, 8).value
                calculated_point_code = sheet.cell(row_num, 10).value
                units = sheet.cell(row_num, 12).value
            else:
                code = None

            if (code or row_num == sheet.nrows) and (current_calculation["code"] is None or code != current_calculation["code"]):
                if current_calculation["code"]:
                    expression_tree = None
                    try:
                        expression_tree = FunctionParser.parse(current_calculation["formula"])

                        identifier_names = set(expression_tree["identifier_names"])
                        if len(current_calculation["parameters"] - identifier_names) > 0:
                            logging.info("Unknown parameters in formula for calculation " + current_calculation["code"])

                        current_calculation["parameters"] = identifier_names

                        self.calculations[current_calculation["id"]] = current_calculation

                    except Exception as e:
                        logging.error("Error parsing formula for calculation " + current_calculation["code"])

                current_calculation = {
                    "id": id,
                    "code": code,
                    "description": description,
                    "formula": formula.split("=")[1],
                    "parameters": set(),
                    "units": units
                }


            if energy_point_code:
                current_calculation["parameters"].add(energy_point_code.upper())
            if numeric_point_code:
                current_calculation["parameters"].add(numeric_point_code.upper())
            if calculated_point_code:
                current_calculation["parameters"].add(calculated_point_code.upper())

        logging.info("Found " + str(len(self.calculations)) + " calculations")
Beispiel #9
0
                                     None)
        while object_builder.stop_build(ar_node) is False:
            top_trio = object_builder.search_top(ar_node)
            print(top_trio)
            lec = top_trio.lec
            top_index = self.infl_point(lec)
            if isinstance(lec[top_index], object_types.Function) or isinstance(
                    top_element, object_types.UnaryMinus):
                left_lec = None
                right_lec = lec[1:]
            else:
                left_lec = lec[0:top_index]
                right_lec = lec[top_index + 1:]

            duo = self.build_ar_node(None, left_lec, right_lec, None, top_trio)
            ar_node = ar_node + duo
        for node in ar_node:
            if node:
                if node.parent is None:
                    result = node.calc()
                    print(f'result{result}')
        return result


if __name__ == '__main__':
    obj = FunctionParser(['math'])
    builder = TreeBuilder()
    string1 = '5*(3+3*(5*5))'
    arr_node = builder.build_tree(string1)
    print(f'result {arr_node}')