Using eval or exec for user input data is dangerous. Any valid syntax will be evaluated by the interpreter. The secure way is to verify if the operation is valid and then execute it.
There are plenty of algorithms to distinguish numbers from operators (search for infix notation).
To safely execute the operations, you could use the following functions
# For python 3.10 and above (with support for match statement)
def apply_function(argument1:int, argument2:int, function:str)->float:
match function:
case "add" | "sum"| "+":
return argument1 + argument2
case "sub" | "subtract" | "-":
return argument1 - argument2
case "mul" | "multiply" | "*" | "x" | "times":
return argument1 * argument2
case "div" | "divide" | "/":
return argument1 / argument2
case "pow" | "power" | "^"|"**":
return argument1 ** argument2
case _:
raise ValueError("Invalid function")
# For python 3.9 and below (without support for match statement)
def apply_function_v2(argument1:int, argument2:int, function:str)->float:
if function in ("add", "sum", "+"):
return argument1 + argument2
elif function in ("sub", "subtract", "-"):
return argument1 - argument2
elif function in ("mul", "multiply", "*", "x", "times"):
return argument1 * argument2
elif function in ("div", "divide", "/"):
return argument1 / argument2
elif function in ("pow", "power", "^", "**"):
return argument1 ** argument2
else:
raise ValueError("Invalid function")