0

I want the result of four numbers connected by random mathematical operations. While it's quite simple for ONE random operation and two numbers, I struggle with more than two, as due to the sequential nature of my code "point before line" fails.

e.g.:

import random
import operator


def random_operation(desired_result):
    ops = {'+':operator.add,
           '-':operator.sub,
           '*':operator.mul,
           '/':operator.truediv}
    
    num = 8
    
    op1 = random.choice(list(ops.keys()))
    op2 = random.choice(list(ops.keys()))
    op3 = random.choice(list(ops.keys()))
    
    result = ops.get(op3)(ops.get(op2)(ops.get(op1)(num,num),num),num)
    
    if result == desired_result:
        print('Found {} {} {} {} {} {} {} = {}\n'.format(num, op1, num, op2, num, op3, num, result))
    return result, desired_result



random_operation(8)

a possible output would be

Found 8 - 8 / 8 + 8 = 8.0

which is wrong, as the operations are done in order and not by mathematical rules. Is there a better way to do this? A way to collapse

result = ops.get(op3)(ops.get(op2)(ops.get(op1)(num,num),num),num)

such that "point before line" works?

Nikolaij
  • 321
  • 1
  • 2
  • 8
  • 2
    Does this answer your question? [Evaluating a mathematical expression in a string](https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string) – Random Davis Oct 01 '21 at 17:38

2 Answers2

1

You could create a str out of your number and your operators while using build-in function eval to evaluate it as a python expression that takes into account arithmetic rules.


import random
import operator


def random_operation(desired_result):
    ops = {'+':operator.add,
           '-':operator.sub,
           '*':operator.mul,
           '/':operator.truediv}
    
    num = 8
    
    op1 = random.choice(list(ops.keys()))
    op2 = random.choice(list(ops.keys()))
    op3 = random.choice(list(ops.keys()))
    
    #result = ops.get(op3)(ops.get(op2)(ops.get(op1)(num,num),num),num)
    
    result = eval(f'{num} {op1} {num} {op2} {num} {op3} {num}')

    if result == desired_result:
        print('Found {} {} {} {} {} {} {} = {}\n'.format(num, op1, num, op2, num, op3, num, result))
    return result, desired_result

marcel h
  • 742
  • 1
  • 7
  • 20
1

One option would be to use the python-built eval() function. This takes in a string, which can contain a mathematical operation, and calculate it. Here is an example:

print(eval("5+5"))
>>> 6

You can then turn the operators list into an array and pick random operators. Here is an example:

operators = ["+", "-", "*", "/"]
num = 8

ops = [random.choice(operators) for x in range(3)]

finalStr = str(num).join(ops)

print(eval(f'{num} {finalStr} {num}'))
Paul Bekaert
  • 81
  • 1
  • 10