Package: safe-evaluation
safe_evaluationsafe_evaluation - is an implementation of polish notation algorithm for mathematical and dataframe operationshow to useInstallationpip install safe-evaluationTutorialimport evaluation classfrom safe_evaluation import Evaluatorinitialize evaluatorevaluator = Evaluator()send string that you want to evaluateresult = evaluator.solve(command="2 + 2")method will return resultprint(result)Examples of usageevaluator.solve(command="2 + 2")  # 4evaluator.solve(command="lambda x: x * 2")  # lambda x: x * 2evaluator.solve(command="2 * x - y", local={"x": 2, "y": 3})  # 1import pandas as pd

df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})
evaluator.solve(command="${col1} + ${col2}", df=df)  # 0   4
                                                        1   6
                                                        dtype: int64evaluator.solve(command="list(map(lambda x, y: x * 2 + y, range(5), range(3, 8)))")  # [3,6,9,12,15]evaluator.solve(command="list(map(lambda x: x + y, [0,1,2,3,4]))", local={"y": 10})  # [10,11,12,13,14]import pandas as pd

df = pd.DataFrame(data={'col1': [1, 2, 4, 7], 'col2': [3, 4, 8, 9]})
evaluator.solve(command="np.mean(${col1}) + np.mean(${col2})", df=df)  # 9.5import pandas as pd

df = pd.DataFrame(data={'col1': [1, 2, 4, 7], 'col2': [3, 4, 8, 9]})
evaluator.solve(command="${col1}.apply(lambda v: v ** 2 > 0).all()", df=df)  # Trueimport pandas as pd

df = pd.DataFrame(data={'col1': [1, 2, 4, 7], 'col2': [3, 4, 8, 9]})
evaluator.solve(command="${col1}.apply(lambda v: 1 if v < 3 else 2)", df=df)  # 0    1
                                                                                 1    1
                                                                                 2    2
                                                                                 3    2
                                                                                 Name: col1, dtype: int64from datetime import datetime

import pandas as pd

dates = [datetime(year=2022, month=11, day=11 + i) for i in range(7)]
df = pd.DataFrame(data={'dates': dates})
evaluator.solve(command="${dates}.dt.dayofweek", df=df)  # 0    4
                                                            1    5
                                                            2    6
                                                            3    0
                                                            4    1
                                                            5    2
                                                            6    3
                                                            Name: dates, dtype: int64range = evaluator.solve(command="pd.date_range(start='2021-02-05', end='2021-03-05', freq='1D')"")
len(range)  # 29df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})
sorted_df = evaluator.solve(command="${__df}.sort_values('col2', ascending=False)", df=df)  #    col1  col2
                                                                                               0     2     4
                                                                                               1     1     3Supported operationsin is not supported yetcomparation (<=, <, > , >=, !=, ==)unary (+, -)boolean (~, &, |, ^)binary (+, -, /, *, //, %, **)Supported functionsmap, filter, list, rangebool, int, float, complex, strnumpy module functions (np.mean, etc.)pandas module functions (pd.date_range, etc.)anonymous functionsSupported access to data${col_name} is same as df['col_name']${__df} is same as dfIt is possible to use your own class for preprocessing or calculatingfrom safe_evaluation import Evaluator, BasePreprocessor
from safe_evaluation.constants import TypeOfCommand

class MyPreprocessor(BasePreprocessor):
    def __init__(self, evaluator):
        self.evaluator = evaluator

    def prepare(self, command, df, local):
        return [(TypeOfCommand.VARIABLE, 'v'), '**', (TypeOfCommand.VALUE, 2), '>', (TypeOfCommand.VALUE, 5)]


evaluator = Evaluator(preprocessor=MyPreprocessor)

expression = 'v ** 2 > 5'

output = evaluator.solve(expression, local={'v': 2})    #    FalseIt is possible to use your own settingsfrom safe_evaluation import Evaluator, Settings

evaluator = Evaluator()
settings = Settings(allowed_funcs=['filter', 'list'])
evaluator.change_settings(settings)

output = evaluator.solve("list(filter(lambda x: x < 0, [-1,0,1]))")   #    [-1]from safe_evaluation import Evaluator, Settings

evaluator = Evaluator()
settings = Settings(allowed_funcs=['list'])
evaluator.change_settings(settings)

output = evaluator.solve("list(filter(lambda x: x < 0, [-1,0,1]))")   #    Exception: Unsupported function filter