-6

I'm having an issue with my code, for some reason "result" sometimes returns with some wacky number that doesn't make sense. Is there a better way of doing this?

import random

number1 = random.randint(1,9)
operator = random.choice(r"+-*")
number2 = random.randint(1,9)
x1 = random.randint(1,9)

print(x1)
result = eval(str(number1)*int(x1) + operator + str(number2)*int(x1))
answer = x1
print("solve for x: {}x {} {}x = {}".format(number1, operator, number2, result))
print(number1*x1,operator,number2*x1,"=",result)
newbpy
  • 1
  • 2

3 Answers3

2

The expression str(number1)*int(x1) doesn't do what you think it does. It converts number1 to a string (a single digit from 1 to 9), then it replicates it x1 times, like this:

print(str(7)*3)
# '777'

So you need to do the multiplication before converting to a string, like this:

print(str(7*3))
# 21

Or, change the main line of your code to this:

result = eval(str(number1*x1) + operator + str(number2*x1))

You should know that eval is generally considered a dangerous tool. So you might do better with something like this:

import random, operator

operators = [
    ('+', operator.add),
    ('-', operator.sub),
    ('*', operator.mul)
]

number1 = random.randint(1, 9)
op_str, op_func = random.choice(operators)
number2 = random.randint(1, 9)
x1 = random.randint(1, 9)

print(x1)
result = op_func(number1 * x1, number2 * x1)
print("solve for x: {}x {} {}x = {}".format(number1, op_str, number2, result))
print(number1 * x1, op_str, number2 * x1, "=" , result)
Matthias Fripp
  • 17,670
  • 5
  • 28
  • 45
  • Ohhh, sorry I'm fairly new to programming. I've been trying to research this for a while but it wasn't clicking in my head. The repeating number makes sense now since it's trying to eval a string. I kept on seeing more complicated expressions in other examples. Changing the main line of code to your `result = eval(str(number1*x1) + operator + str(number2*x1))` fixed my issue. Thank you so much! – newbpy Feb 27 '19 at 20:11
  • Glad to help! I also added some advice on doing this without using the `eval` function. Let me know if you have questions about how the extra code works. The hardest part is probably the `op_str, op_func = random.choice(operators)` line. That selects a random item from the list. Since the `operators` is a list of tuples, the selected item will be a tuple of a string and a function. Assigning that to a pair of variables is a quick way to split the selected item it into two different variables. Also note, since `op_func` is a function, you can call it just by writing `op_func(something)`. – Matthias Fripp Feb 27 '19 at 20:18
  • Ive ran into an issue where when it's picking random numbers, sometimes the answer could be "all real numbers" where x=0, i've tried to add `if result == 0: pass` but it still spits out problems where it could be all real numbers. – newbpy Mar 03 '19 at 23:17
  • I don't really understand your question. When the operator is `+` or `-`, you get `result == x1 * (number1 +/- number2)`, and `x1` could have any value if and only if `result == 0`. When the operator is `*`, then you have `result == x1 * x1 * number1 * number2`. Again, if and only if `result == 0` then `x1` could have any value. Otherwise `x1` can have two values: `+/- sqrt(number1 * number2)`. So if you put `if result == 0:` before the last two `print` calls, you should filter out those cases (and get no output instead). I would need to see more complete code to diagnose it further. – Matthias Fripp Mar 04 '19 at 19:19
0
import random
number1 = random.randint(1,9)
operator = random.choice(r"+-*")
number2 = random.randint(1,9)
x1 = random.randint(1,9)
print(x1)
result = eval(str(number1*x1) + operator + str(number2*x1))
answer = x1
print("solve for x: {}x {} {}x = {}".format(number1, operator, number2, result))
print(number1*x1,operator,number2*x1,"=",result)

The reason, I believe, it wasn't working was eval interprets everything as string and tries to give an answer. In the code above I have simply changed type of everything in eval to string.

Read more here: On Eval

Sid
  • 3,749
  • 7
  • 29
  • 62
0

Instead of doing

result = eval(str(number1)*int(x1) + operator + str(number2)*int(x1))

I would do

result = eval(str(number1*x1) + str(operator) + str(number2*x1))
Professor Dragon
  • 217
  • 1
  • 4
  • 14
  • Why use eval at all? – juanpa.arrivillaga Feb 27 '19 at 20:19
  • Welcome to StackOverflow! Be sure to take the [tour](https://stackoverflow.com/tour) and visit the [help center](https://stackoverflow.com/help). This is exactly the same as the other two answers, you just wrapped `operator` in a (superfluous, because it's already a string) `str`. – Michail Feb 27 '19 at 20:32