Reputation: 31
I'm willing to make a program that evaluates all possible combinations of operations ( + , - , * , / ) on a set of positive integers of length 6 (eg : [1, 6, 3, 9, 2, 9] ).
To do so, I am using the list
symbols = ['+', '-', '*', '/']
and wrote a nested loop to create all possibilities
+ + + + +
+ + + + -
.
.
.
/ / / / *
/ / / / /
by calling each row (eg : + - + * / ) a motif, and M the set of all motifs where
M[0] = ['+', '+', '+', '+', '+']
M[1] = ['+', '+', '+', '+', '-']
and so on. My goal now would be to write a function
evaluate_expression(motif, a, b, c, d, e, f)
that spits out the result of the expression a motif[0] b motif[1] c motif[2] d motif[3] e motif[4] f
my idea was to try converting '+' into the symbol + but I couldn't find a way to do it, I hope some of you guys here would know how to do that, I'm open to any suggestion of modification to make this cleaner.
Upvotes: 2
Views: 347
Reputation: 119
You can execute strings with eval("...")
.
def evaluate_expression(operands, operators):
assert len(operands)==len(operators)+1
expression = str(operands[0])
for idx, operator in enumerate(operators):
expression += str(operator)+str(operands[idx+1])
return eval(expression)
The function can be called like this evaluate_expression([1,2,3,4,5],["+","-","+","-"])
and will calculate 1+2-3+4-5 = -1
Upvotes: -1
Reputation: 21
I don't think there's a direct way to typecast a string to an operator (at least in the core python library) but what you could do is create the whole expression as a string and run eval()
whiles passing it in.
opnd = [1, 6, 3, 9, 2]
oprt = ['+', '-', '*', '/']
def string_eval(operands,operators):
final_string = ""
for i in range(len(operands)):
final_string += str(operands[i])
if i < len(operators):
final_string += str(operators[i])
return eval(final_string)
print(string_eval(opnd,oprt))
Output -6.5
Upvotes: -1
Reputation: 2318
The operator library gives you functions for the basic operators (e.g. add()
, sub()
)
So, you could replace your symbols = ['+', '-', '*', '/']
with:
from operator import add, sub, mul, truediv
symbols = [add, sub, mul, truediv]
and now your motif-generating function should make lists of functions instead of lists of strings.
Then, assuming you have a motif
list, as you call it (check out itertools.combinations_with_replacement()
for a function to generate all motifs), you can apply it by doing something like:
motif = [add, add, sub]
values = [5, 6, 7, 8]
result = values[0]
for i, current_func in enumerate(motif):
result = current_func(result, value[i+1])
print(result)
Note: this method will not respect order of operations, it will apply the functions in order, left to right.
Upvotes: 4
Reputation: 81
Using a Dictionary of function pointers seeems to be what you want to use.
from operator import add, sub, mul, truediv
operators = {
'+': add,
'-': sub,
'*': mul,
'/': truediv
}
def op(operator, a, b):
return operators[operator](a, b)
print(op('+', 1, 2))
print(op('-', 1, 2))
In total, it could look like this:
from operator import add, sub, mul, truediv
operators = {
'+': add,
'-': sub,
'*': mul,
'/': truediv
}
def op(operator_list, param_list):
assert len(operator_list)+1 == len(param_list)
assert len(param_list) > 0
res = param_list[0]
for i in range(len(operator_list)):
res = operators[operator_list[i]](res, param_list[i])
return res
print(op(['+', '-'], [1, 2, 4]))
Upvotes: 2