Evaluation of Postfix notation - python

How to calculate the value of post fix notation:
i tried with:
import operator
operator = {
'+': operator.add, '-': operator.sub,
'*': operator.mul, '/': operator.div, '%': operator.mod,
'**': operator.pow, '//': operator.floordiv,
}
l = []
exp = "11+2*"
for i in exp:
if i in operator:
a = operator[i]
x = l[0]
y = l[1]
l[-2:] = [a(*l[-2:])]
print l
else:
l.append(i)
print l
How to do this?

Make sure to have Python parse your characters into integers before adding them to the stack:
l.append(int(i))

Some hints:
You need a better parser, iterating just character by character will not be enough (unless you only want to have single digit numbers). To make it a little simpler, you could require that numbers and operators are delimited by whitespace each and use str.split:
elems = "11 2 3 + *".split()
You need to convert the numbers to integers before pushing them on the stack
The stack operation also looks a little weird. Having it as
l.append(a(l.pop(), l.pop())
makes it more explicit.

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))

Python Performing Calculations with Strings

How do I perform calculations with strings? Like suppose I have:
a=('/')
print(10, a, 5)
How do I get the answer as '2'? Because 10/5 is 2.
There are multiple ways to do this.
The most common way, I guess, is using the operator module and a map (dictionary) to turn your strings into operators, as the next example.
import operator
run_ops = {
'+' : operator.add,
'-' : operator.sub,
'*' : operator.mul,
'/' : operator.truediv,
'%' : operator.mod,
'^' : operator.xor,
}.get
print(run_ops('/')(10, 5))
Or go with lambdas:
run_ops= {'+': lambda x, y: x + y,
'-': lambda x, y: x - y,
# ...
'/': lambda x, y: x / y
}
run_ops['/'] (10,5)
Cheers
A nice method has been posted by epap.
However if you want to stick to the order of the expression where the "/", comes between the two numbers then one of the ways you can do it, is as below.
You can wrap (Number_1, "/", Number_2) and send it to a class and then print it. Something like below.
class Divide(object):
def __new__(cls, a, symbol, b):
result = None
if symbol == "/":
result = a/b
return result
print(Divide(5,"/",2))
This yields the below output
2.5
You can use "eval" to evaluate expressions given as strings.
a = "/"
res = eval("10" + a + "5")
print(res)

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

How do I put mathematical operations in a list?

I need to make my code as short as possible and I need to put * - + in a list like this: op = [*,-,+]
It gives me a syntax error... I know I can put them as strings but is that the only way? My program picks a random operator from that list and makes a sum out of it, eg, sum = num1 op num2
my code:
import random
opL = [*,-,+]
def mathsQuiz(number1,operator,number2):
sum1=number1,operator,number2
print(sum1)
number1 = random.randint(1,12)
number2 = random.randint(1,12)
operator = random.choice(opL)
mathsQuiz(number1,operator,number2)
Use the operator module and create a dictionary instead that will map out your operators:
>>> import operator
>>> import random
>>> opL = {"*": operator.mul, "-": operator.sub, "+": operator.add}
>>> opL.get(random.choice(list(opL)))(1,2)
3
import operator
opL = operator.mul, operator.sub, operator.add

Categories

Resources