How to solve expressions from a list? - python

I have a list of expressions (+ - *):
["2 + 3", "5 - 1", "3 * 4", ...]
and I need to convert every expresion to expression = answer like this 2 + 3 = 5.
I tried just doing print(listt[0]) but it outputs 2 + 3, not 5. So how do i get the answer of this expression? I know that there is a long way by doing .split() with every expression, but is there any other faster way of doing this?
UPD: I need to use only built-in functions

You can use the eval() function from Python Builtins :
for expr in yourlist:
print(expr, "=", eval(expr))
# 2+3 = 5
As stated in the comments, this is not malicious-proof. Use this only if you know the string being evaluated are indeed simple arithmetic expressions.

If you want to avoid using eval() (and you probably should) then you could do something like this:
from operator import add, sub, mul, truediv
from re import compile
OMAP = {
'+': add,
'-': sub,
'*': mul,
'/': truediv
}
pattern = compile(r'^(\d+\.*\d*)\s*(.)\s*(\d+\.*\d*)$')
exprs = ["2 + 3.5", "5 - 1", "3 * 4", "3 / 4"]
def convert(s):
try:
return int(s)
except ValueError:
pass
return float(s)
for expr in exprs:
x, o, y = pattern.findall(expr)[0]
r = OMAP[o](convert(x), convert(y))
print(f'{expr} = {r}')
Output:
2 + 3.5 = 5.5
5 - 1 = 4
3 * 4 = 12
3 / 4 = 0.75
Note:
This is not robust as it assumes that the operators are only ever going to be one of +, -, *, / and furthermore that the pattern always matches the regular expression.
Input data changed to include a floating point number

Use eval() function. The eval() function evaluates the specified expression, if the expression is a legal Python statement, it will be executed.

Related

How to use some operator that has been scraped from a string

I'm trying to add, subtract or multiply two integers based on the sign between the integers, as in 5 + 6. When I use + explicitly within the script, it works. However, I wish to parse that operator from the given string in order to use like int(numbers[0]) + operator + int(numbers[1]) or something similar that works.
I've tried with:
import re
str_number = "5 + 6"
numbers = re.findall('[0-9]+', str_number)
operator = re.findall('([^\s\d]+?)',str_number)[0]
result = int(numbers[0]) + operator + int(numbers[1])
print(result)
When I run the above, I get the error below:
result = int(numbers[0]) + operator + int(numbers[1])
TypeError: unsupported operand type(s) for +: 'int' and 'str'
You can use the inbuilt operator module and define a mappings dictionary that map the given operator to its corresponding operation.
Use:
import operator
mappings = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.floordiv}
equation = "5 + 6"
n1, op, n2 = equation.split()
result = mappings[op](int(n1), int(n2))
print(result)
This prints:
11
If I am correct it is not possible because the operator variable is a str but the number number variable is an int and you can’t do anything with these without type conversion
But you could accomplish your idea by using an if else statement.
try it that works, transform you equation in a string and use the eval() function
result = numbers[0] + operator + numbers[1]
print(eval(result))

How to identify a string as a binaryoperator

Perhaps this is an easy question, but I'm new to Python and haven't seen anyone else post anything similar to this.
We have a list:
lst1 = ["5", "+", "1"]
or
lst2 = ["10", "/", "2"]
How can one interpret this to: 5 + 1 or 10/2 ? I understand that you can write: int(lst2[0]) and then you would get 10, but how do you do the same with "+" or "/"?
Assuming you "know" that your list has three strings, with the first and last representing integers and the middle one representing one of a fixed set of operators, you just need a mapping from the operator to a function that implements it. For example:
import operator
ops = {"+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.div}
lst1 = ["5", "+", "1"]
f = ops[lst1[1]]
operand1 = int(lst1[0])
operand2 = int(lst1[2])
result = f(operand1, operand2)
However, things get complicated once you start allowing more general inputs, as you need some logic for deciding what parts of the list represent what. For that, you need:
A grammar, which identifies what role each element of your list plays
A parser, which uses the grammar to convert each string to a usuable value
An interpreter, which evaluates the thing produced by the parser to produce
a final value.
There may also be a tokenizer, which is what would convert a single string input like "5 + 1" into a list of tokens that the parser uses for its input.
Any further general discussion about how to define any of the 4 concepts defined above is far beyond the scope of Stack Overflow.
If I understand you right, here is a snippet you may start with:
import operator
operators = {'+': operator.add, '-': operator.sub, '/': operator.truediv, '*': operator.mul}
first, op, second = lst
first, op, second = int(first), operators[op], int(second)
op(first, second)
operator module contains operators as a functions, so you can map symbols to the operators. Note that I’ve used truediv for /, you may want to use variant which return int always
You can't transform the string "+" to the operator + because operators are not things that exist at runtime. Operators only exist in code. You can map the string "+" to a function that takes two arguments and returns their sum, though. Functional equivalents for most operators exist in the operator module:
lst1 = ["5", "+", "1"]
import operator
op_table = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv
}
lhs = int(lst1[0])
op = op_table[lst1[1]]
rhs = int(lst1[2])
print('result:', op(lhs, rhs)) # output: 6
You can use standard function eval()
https://www.journaldev.com/22504/python-eval-function
lst1 = ["5", "+", "1"]
result1 = eval("".join(lst1)) # 6
lst2 = ["10", "/", "2"]
result2 = eval("".join(lst2)) # 5.0

Is there a neat way to perform XOR operation on two conditions in IF statement?

I am currently creating a binary calculator which allows for both positive and negative binary inputs. I have the following code regarding my question:
if (firstvalue[0] == "-" and not secondvalue[0] == "-") or (secondvalue[0] == "-" and not firstvalue[0] == "-"):
invertedbinary.append("-")
So obviously, if either number is negative but not both then the final string will have a negative sign. Otherwise, both will be positive and there will be no negative sign on the string.
I'm just wondering if there is a neater way to do this? I tried using ^ but I guess its only a bitwise operator.
if firstvalue[0] == "-" ^ secondvalue[0] == "-":
I also tried xor incase of the off chance but obviously no luck. Any suggestions on a a neater way to do this?
^ will work just fine if you use parentheses:
if (firstvalue[0] == "-") ^ (secondvalue[0] == "-"):
You can also use != in the place of ^. It works the exact same way here, but may be a little more clear.
One thing to remember with ^ is that it will behave unexpectedly if any of the expressions is a non-bool: a ^ b does not equal (a and not b) or (b and not a) if, say a = 5 and b = 2!
Since xor can't short-circuit, you can as well use a function.
from operator import xor as xor_
from functools import reduce
def xor(*args):
return reduce(xor_, map(bool, args))
if xor(firstvalue[0] == '-', secondvalue[0] == '-'):
...
This works for any number of values, and non-boolean values too, so you can do xor(1, 1, 1, 1) = 0 and xor(1, 1, 1, 1, 1) = 1

TypeError: 'bool' object is not callable - python

I'm trying to implement a simple maths game where the user is given random numbers and operators then they have to work out the answer, I found sources on the internet that suggested using the operator module, which is why i used it, if there is a more efficient/ easier way of achieving this I am very open for interpretation.
Essentially i am trying to remove this horrible <built-in function add> and swap it to be more user friendly by saying '+' or 'add', something along those lines but i keep getting the error 'TypeError: 'bool' object is not callable - python', i really dont know what this means, i am new to python and am very confused.
from operator import add, sub, mul, floordiv
operators = (add == str("add"), sub == str("subtract"), mul == str("multiply"), floordiv == str("divide"))
operator = random.choice(operators)
answer = operator(number1, number2)
question = print("What is ", number1, operator, number2, "?")
You want two seperate things: the string representation of the operator and the operator itself. You can use dictionary to store the function and the corresponding string representation:
from operator import add, sub, mul, floordiv
import random
number1 = 9
number2 = 3
operators = {'+':add, '-':sub, '*':mul, '/':floordiv}
operator_name = random.choice(operators.keys())
op = operators[operator_name]
answer = op(number1, number2)
question = "What is {}{}{}?".format(number1, operator_name, number2)
print question
print answer
What you get as a result of the first line is
operators = (False, False, False, False, False)
or something in those lines.
Then you are trying to call a boolean that gets you the exception you have.
add == str("add") will evaluate to False, since you're trying to compare a function to a string.
I'm assuming you are trying to implement a simple math game, hence instead of using operator, which are in fact math operation functions, you can just use a simple dictonary:
operators = { 'add': add, 'substract': sub, 'multiply': mul }
answer = operators[random.choice(operators.keys())](number1, number2)
Here's an implementation using tuples instead of dicts, I added in more ways to represent each operation.
import random
from operator import add, sub, mul, floordiv
number1 = 5
number2 = 10
operators = (
(add, ("add", "plus", "+")),
(sub, ("subtract", "minus", "-")),
(mul, ("multiply", "times", "*")),
(floordiv, ("divide", "over", "/")),
)
operator, (name, operation, symbol) = random.choice(operators)
print("What is ", number1, operation, number2, "?")
print(operator(number1, number2))
Output
13:50 ~ $ python3 StackOverflow/27128400.py
What is 5 times 10 ?
50
13:55 ~ $ python3 StackOverflow/27128400.py
What is 5 plus 10 ?
15
13:55 ~ $ python3 StackOverflow/27128400.py
What is 5 minus 10 ?
-5
13:55 ~ $ python3 StackOverflow/27128400.py
What is 5 over 10 ?
0
What you're trying to do here is certainly possible. The formation of the tuple above does not return anything useful. A dictionary is more appropriate.
You can construct the dictionary as:
operators = {'add':add, 'minus':sub, 'multiplied by':mul, 'divided by':floordiv}
This gives you a dictionary of related strings and functions. You can choose a random operator name (this will give the string value, not the operator itself.
operator = random.choice(list(operators.keys()))
Then compute the answer:
answer = operators.get(operator)(number1, number2)
This gets the operator function from the operators dictionary by 'searching' for its string partner.
Altogether now (with some numbers so it runs off the bat):
from operator import add, sub, mul, floordiv
import random
operators = {'add':add, 'minus':sub, 'multiplied by':mul, 'divided by':floordiv}
operator = random.choice(list(operators.keys()))
number1 = 2
number2 = 3
answer = operators.get(operator)(number1, number2)
print "What is " + str(number1) + " " + operator + " " + str(number2) + "?"
print answer
(I'm using 2.7 for this)

How can I remove the single quotes from a string and use it for division in Python?

How can I remove ' from the string '/' and use it for division in Python?
For example:
a='/'
b=6
c=3
bac
The answer should be 2.
You can get the built-in operators as functions from the operator module:
import operator
a = operator.div
b = 6
c = 3
print a(b, c)
If you want to get the correct operator by the symbol, build a dict out of them:
ops = {
"/": operator.div,
"*": operator.mul,
# et cetera
}
a = ops["/"]
Python has an eval() function that can do this:
a = "/"
b = "6"
c = "3"
print eval(b + a + c)
However, please note that if you're getting input from a remote source (like over a network), then passing such code to eval() is potentially very dangerous. It would allow network users to execute arbitrary code on your server.
There are no single quotes in the variable a. Python just uses these to denote a represents a string. b and c represent ints and don't have the single quotes. If you ensure all of these variables are strings, you can join() them together:
>>> a='/'
>>> b=6
>>> c=3
>>> bac = ''.join(str(x) for x in (b, a, c))
>>> bac
'6/3'
See how there are single quotes at the beginning and end of the string.
You could then use eval() (with caution) to perform the division:
>>> eval(bac)
2
Related: Is using eval in Python a bad practice?

Categories

Resources