0

Just doing a fun project.

Is it possible to concatenate operators with numbers and then return the statement(s) to a boolean?

import random

num1 = random.randint(1,50)
num2 = random.randint(1,50)

operators = ['<', '>', '<=', '>=', '==']

for i in range(5):
    print("Number 1: " + str(num1))
    print("Number 2: " + str(num2))
    print(num1 + operators[i] + num2)

Output: TypeError: unsupported operand type(s) for +: 'int' and 'str'

AcK
  • 2,063
  • 2
  • 20
  • 27
  • 1
    Do these answer your question? [How can I concatenate str and int objects?](https://stackoverflow.com/questions/25675943/how-can-i-concatenate-str-and-int-objects) and [How do I execute a string containing Python code in Python?](https://stackoverflow.com/questions/701802/how-do-i-execute-a-string-containing-python-code-in-python) – wjandrea Sep 25 '21 at 03:24
  • 1
    BTW, you can simplify that loop: `for operator in operators: ... print(... operator ...)` – wjandrea Sep 25 '21 at 03:28

3 Answers3

2

You need to cast num1 and num2 to string before concatenating in the final print:

for i in range(5):
    print("Number 1: " + str(num1))
    print("Number 2: " + str(num2))
    print(str(num1) + operators[i] + str(num2))
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • I understand how to cast. What I should've said was how to return a statement to a boolean using a for loop. But using the eval is what I was wanting to do on answer 1. – Caleb Murnan Sep 25 '21 at 20:06
2

@Tim's answer shows you how to print out the expression, but to actually determine the result of the expression, you should create a dictionary with the operators like this:

import random, operator

num1 = random.randint(1,50)
num2 = random.randint(1,50)

operators = ['<', '>', '<=', '>=', '==']
dct = dict(zip(operators, [operator.lt, operator.gt, operator.le, operator.ge, operator.eq]))
for i in range(5):
    print("Number 1: " + str(num1))
    print("Number 2: " + str(num2))
    print(num1, operators[i], num2)
    print(dct[operators[i]](num1, num2))

In this solution instead of:

dct = dict(zip(operators, [operator.lt, operator.gt, operator.le, operator.ge, operator.eq]))

You could define the dictionary as:

dct = {'<': operator.lt, '>': operator.gt, '<=': operator.le, '>=': operator.ge, '==': operator.eq}

Example output:

Number 1: 32
Number 2: 27
32 < 27
False
Number 1: 32
Number 2: 27
32 > 27
True
Number 1: 32
Number 2: 27
32 <= 27
False
Number 1: 32
Number 2: 27
32 >= 27
True
Number 1: 32
Number 2: 27
32 == 27
False

Unless you want to use the evil eval:

operators = ['<', '>', '<=', '>=', '==']
for i in range(5):
    print("Number 1: " + str(num1))
    print("Number 2: " + str(num2))
    x = str(num1) + ' ' + operators[i] + ' ' + str(num2)
    print(x)
    print(eval(x))

I suggest not to use the eval in general! It's bad practice!

But as @MarkTolonen mentioned, in this case, eval is fine, It wouldn’t be evaluating potentially dangerous user input.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
  • I haven't learned how to use dict or zip, but I can see why it's useful to return the operator statement to a boolean. Is there perhaps a simpler method to return the statement to a boolean? – Caleb Murnan Sep 25 '21 at 03:25
  • 3
    `eval` would be fine in this instance. It wouldn’t be evaluating potentially dangerous user input. – Mark Tolonen Sep 25 '21 at 03:25
  • @CalebMurnan You should use `eval` here then. – U13-Forward Sep 25 '21 at 03:27
  • @CalebMurnan You should use `eval`, also I just added a similar thing, but instead of `dict(zip(...))` I created a bare dictionary from a literal. – U13-Forward Sep 25 '21 at 03:28
0

Or you could use f-strings and in combination with how pythons loops work:

for op in operators:
    print(f"Number 1: {num1}")
    print(f"Number 2: {num2}")
    print(f"{num1} {op} {num2}")
Jab
  • 26,853
  • 21
  • 75
  • 114