vinci1it2000 / formulas

Excel formulas interpreter in Python.
https://formulas.readthedocs.io/
European Union Public License 1.1
342 stars 75 forks source link

possibility to init excelModel from a function #136

Open dberardo-com opened 3 months ago

dberardo-com commented 3 months ago

is it possible to:

import formulas func = formulas.Parser().ast('=(1 + 1) + B3 / A2')[1].compile() xl_model = ExcelModel().from_compiled_function(func)

?

dberardo-com commented 3 months ago

my current implementation:

import formulas
FUNCTIONS = formulas.get_functions()
FUNCTIONS['MYFUNC'] = lambda x, y: 1 + y + x
func = formulas.Parser().ast('=(1 + 1) + B3 / A2')[1].compile()
def func_to_excel(func):
    graph = func.dsp.nodes
    import re
    new_dict = dict()
    for i,( key, val) in enumerate(graph.items()):
        if val["type"] == "data":
            if re.match(r'^[A-Z]+[0-9]+$',key): 
                # new_dict[key] = key
                continue
            else:
                j = i + 1
                new_key = f'A{j}' 
                while new_key in (list(new_dict.keys()) + list(graph.keys())):
                    i += 1
                    new_key = f'A{j}' 
                new_dict[new_key] = key
    return formulas.ExcelModel().from_dict(new_dict)
func_to_excel(func),to_dict() --> returns: {'A1': '((1 + 1) + (B3 / A2))', 'A3': '(1 + 1)', 'A4': '(B3 / A2)'}
dberardo-com commented 3 months ago

rethinking about this, it seems a very specific issue to my use case. i am sharing my solution below for future reference, but this issue can be closed for the time being if not considered too relevant.

def func_to_excel(func,validate=False):
    graph = func.dsp.nodes
    import re
    refs = []
    new_dict = dict()
    j = 1
    for i,( key, val) in enumerate(graph.items()):
        if val["type"] == "data":
            if "c0>" in key: 
                continue
            elif re.match(r'^[A-Z]+[0-9]+$',key): 
                refs.append(key)
                continue
            else:
                new_key = f'A{j}' 
                while new_key in (list(new_dict.keys()) + list(graph.keys())):
                    j += 1
                    new_key = f'A{j}' 
                new_dict[new_key] = key
    return formulas.ExcelModel().from_dict(new_dict) if validate else  type('obj', (object,), {'to_dict' : lambda: new_dict})