This question already has answers here:
Turn string into operator
(8 answers)
Closed 11 months ago.
I have a few python strings parsed from a file where there are several hundred conditions that i need to evaluate. How would you experts out there recommend I evaluate these conditions? For example...
["20", "<=", "17.5"] # false
["15", ">=", "18.5"] # false
["20", "==", "20"] # true
["beta", "==", "beta"] # true
["beta", "!=", "beta"] # false
I wasn't sure if there were any tricks to resolving these equations, or if i should do some sort of if else like...
op = parts[1]
if op == '<=':
return op[0] <= op[2]
elif op == '>=':
return op[0] >= op[2]
elif op == '==':
return op[0] == op[2]
elif op == '!=':
return op[0] != op[2]
You could use the eval() function:
parts = ["20", "<=", "17.5"]
print(eval(' '.join(parts))) # False
Related
I am solving the following problem on Leetcode: https://leetcode.com/problems/valid-parentheses/submissions/
Where basically we have a list of parentheses s, and are checking if it is 'valid'.
Example:
Input: s = "()[]{}"
Output: true
Input: s = "(]"
Output: false
Basically the parentheses need to be closed in the right order.
Here is my code:
def isValid(s: str) -> bool:
stack = []
open_brackets = ["(", "[", "{"]
for bracket in s:
if bracket in open_brackets:
stack.append(bracket)
else:
if bracket == "]":
if stack.pop() != "[":
return False
elif bracket == ")":
if stack.pop() != "(":
return False
elif bracket == "}":
if stack.pop != "{":
return False
return True
For some reason, it is failing the test for input: s="(]" ; this is clearly supposed to return False, but it is returning True.
I printed the stack at the end of my code, and I am getting ["("], which means the else statement is not executing for some reason. Any ideas why- I have looked over this so many times and can't figure it out. Thanks
The return True statement prevents the other code from running, meaning it exits on the first loop.
Unindent it and your problem will be solved.
Unindent the final return True such that the loop can iterate through all characters in the input string:
def isValid(s: str) -> bool:
stack = []
open_brackets = ["(", "[", "{"]
for bracket in s:
if bracket in open_brackets:
stack.append(bracket)
else:
if bracket == "]":
if stack.pop() != "[":
return False
elif bracket == ")":
if stack.pop() != "(":
return False
elif bracket == "}":
if stack.pop != "{":
return False
return True
I'm feeling quite generally stupid at the moment.
I've been attempting to get my function to run a some code once a specific name has been inputted.
I feel as if the code I am putting together is quite childish and I'm currently trying to find some help on what I am doing wrong. Any input is appreciated. I apologise for my messy code.
I want to simply get my function argument (cond) to be able to run this specific code if its either inexpensive, large_screen or apple_product. Thanks for all your help :)
def satisfies(product, cond):
inexpensive = (4, '<=', 1000)
large_screen = (2, '>=', 6.3)
apple_product = (1, '==', 'Apple')
conditions = (inexpensive, large_screen, apple_product)
if cond == conditions[0]:
if cond[1] == '<=':
return True if cond[2] <= product[4] else False
elif cond[1] == '<=':
return True if cond[2] <= product[4] else False
elif cond[1] == '==':
return True if cond[2] == product[4] else False
if cond == conditions[1]:
if cond[1] == '<=':
return True if cond[2] <= product[4] else False
elif cond[1] == '<=':
return True if cond[2] <= product[4] else False
elif cond[1] == '==':
return True if cond[2] == product[4] else False
if cond == conditions[2]:
if cond[1] == '==':
return True if cond[2] == product[1] else False
Input : A product feature list (product() and a condition
(cond) as specified above.
Output: True if cond holds for the product otherwise False.
Calling satisfies(['Nova 5T', 'Huawei', 6.26, 3750, 497], inexpensive) should return True.
You can simplify your code by
splitting it into two functions:
one that checks a single condition
another that checks many using a combinator function; the default is all(), for "AND"; if you want, you can use combinator=any for an "OR" sort of query).
using the operator module, which contains predicate functions for various operators, and a mapping for your operator strings to those functions
import operator
operators = {
"<=": operator.le,
">=": operator.ge,
"==": operator.eq,
"!=": operator.ne,
"<": operator.lt,
">": operator.gt,
}
def check_condition(product, cond):
field, operator, value = cond
return operators[operator](product[field], value)
def check_conditions(product, conditions, combinator=all):
return combinator(
check_condition(product, cond)
for cond in conditions
)
def check_products_conditions(products, conditions, combinator=all):
return [
product
for product in products
if check_conditions(product, conditions, combinator=combinator)
]
inexpensive = (4, "<=", 1000)
large_screen = (2, ">=", 6.3)
apple_product = (1, "==", "Apple")
product = ['Nova 5T', 'Huawei', 6.26, 3750, 497]
# Check single condition
check_condition(
product,
inexpensive,
)
# Check multiple conditions
check_conditions(
product,
conditions=(
inexpensive,
large_screen,
apple_product,
),
)
# Check multiple products against multiple conditions
matching_products = check_products_conditions(
products=[product, product, product],
conditions=(
inexpensive,
large_screen,
apple_product,
),
)
This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 6 years ago.
how can I shut down script in python?
sys.exit()
does not work.. so where the problem is?
Edit: changed indentation as in my file
import sys
def sifra():
retezec = input("Zadejte slovo: ")
print("Zadali jste slovo: ",retezec)
zprava = ""
posun = int(input("Zadejte číslo o kolik se má šifra posouvat: "))
for znak in retezec:
i = ord(znak)
i = i + posun
if (i > ord("z")):
i = i - 26
znak = chr(i)
zprava = zprava + znak
print("Zašifrovaná zpráva: ", zprava)
znovu = input("Znovu? A/N ")
if(znovu == "A" or "a"):
sifra()
elif(znovu == "N" or "n"):
sys.exit()
else:
pass
sifra()
znovu == "N" or "n" is not what you want. You need to compare znovu to both these values:
elif (znovu == 'N') or (znovu == 'n'):
sys.exit()
Another alternative would be the one suggested in the comments or simply:
elif znovu in 'Nn': sys.exit()
Assuming that nobody inputs 'Nn' as an answer, but even if they (accidentally) do so, this can still be considered as 'No'.
This is my code:
import easygui
from random import randint
Minimum = easygui.enterbox(msg = "Choose your minimum number")
Maximum = easygui.enterbox(msg = "Choose your maximum number")
operator = easygui.enterbox( msg="which operator would you like to use? X,/,+ or - ?",title="operator")
questions = easygui.enterbox(msg = "enter your desired amount of questions")
for a in range(int(questions)):
rn1 = randint(int(Minimum), int(Maximum))
rn2 = randint(int(Minimum), int(Maximum))
answer = easygui.enterbox("%s %s %s =?" %(rn1, operator, rn2))
realanswer = operator (int(rn1,rn2))
if answer == realanswer:
print "Correct"
else:
print 'Incorrect, the answer was' ,realanswer
When I try and run it, all the enterboxes come up fine, it is when it looks at line 13 that it produces this error:
int() can't convert non-string with explicit base
I tried running the code without the int(), and then it gives me:
'str' object is not callable
First: Your operator is a string, not a function. You can't call '/'(2,3), so if operator=='/', you still can't call operator(2,3).
Second: int(rn1), int(rn2) is how you convert two different numbers to integers, not int(rn1, rn2).
Third: Return values from randint() are already integers, and don't need to be converted again.
I'd suggest converting your numbers to integers as they're entered, only once, rather than doing so on each reference. Thus:
minimum = int(easygui.enterbox(msg="Choose your minimum number"))
maximum = int(easygui.enterbox(msg="Choose your maximum number"))
operator = easygui.enterbox(msg="which operator would you like to use? X,/,+ or - ?", title="operator")
questions = int(easygui.enterbox(msg="enter your desired amount of questions"))
# Select a function associated with the chosen operator
operators = {
'*': lambda a,b: a*b,
'/': lambda a,b: a/b,
'+': lambda a,b: a+b,
'-': lambda a,b: a-b,
}
operator_fn = operators.get(operator)
if operator_fn is None:
raise Exception('Unknown operator %r' % operator)
for a in range(questions):
rn1 = randint(minimum, maximum))
rn2 = randint(minimum, maximum))
answer = int(easygui.enterbox("%s %s %s = ?" % (rn1, operator, rn2)))
realanswer = operator_fn(rn1,rn2)
if answer == realanswer:
print "Correct"
else:
print 'Incorrect, the answer was', realanswer
Your operator variable hold a string. You have to use that string to determine the real operation to perform.
Something like that:
if operator == "+":
realanswer = rn1 + rn2
elif operator == "-":
realanswer = rn1 - rn2
elif operator == "/":
realanswer = rn1 / rn2
elif operator == "*":
realanswer = rn1 * rn2
else
raise Exception('Bad operator {}'.format(operator))
Or better using the operator module:
# top of your program
import operator
my_operators = { '+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.div }
# ...
# and later:
realanswer = my_operators[operator](rn1,rn2)
Of course, in a real application, you would somehow have to deal with "invalid" user input. For example using proper exception handling. But this is an other story...
operator is just a string, you still need to write the code that makes it mean something. You could do something like:
if operator in ('+', 'add'):
realanswer = rn1 + rn2
elif operator in ('-', 'subtract'):
realanswer = rn1 - rn2
else:
print operator, "is not valid"
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 9 years ago.
I am changing infix to postfix and then evaluating it.
#!/usr/bin/python
import sys
import fileinput
import operator
operator_functions = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.div,
'%': operator.mod
}
def tokenise( line ) :
'''generator, serves up one token at a time
input - a valid, openo file handle (object)
output - next token (as a string)
side-effects - input pointer is moved'''
for tok in line.split() :
yield tok
#Define types with corresponding ID numbers to distinguish them.
OPERATOR = 1
OPERAND = 2
LEFT_PARENTHESES = 3
RIGHT_PARENTHESES = 4
def precedence(s): #Returns the precedence of the operators
if s == '(':
return 3
elif s == '+' or s == '-':
return 2
elif s == '*' or s == '/' or s == '%':
return 1
else:
return 0
def typeof(s): #Returns the type of the symbol
if s == '(':
return LEFT_PARENTHESES
elif s == ')':
return RIGHT_PARENTHESES
elif s == '+' or s == '-' or s == '*' or s == '%' or s == '/':
return OPERATOR
else :
return OPERAND
def infix2postfix(infix):
postfix = []
stack = []
for i in infix:
symbol_type = typeof(i)
if symbol_type == LEFT_PARENTHESES :
#If it is a left paren, push it onto the stack
stack.append(i)
elif symbol_type == RIGHT_PARENTHESES :
#If it is a right paren, pop operators from the stack and append to the postfix expression,
#until a left paren is encountered on the stack. Remove and discard the left paren
next = stack.pop()
while next != '(':
postfix.append(next)
next = stack.pop()
elif symbol_type == OPERAND:
#If it is an operand, append it to the postfix expression
postfix.append(i)
elif symbol_type == OPERATOR:
#If it is an operator, then pop operators from the stack and append to the postfix expression
#while the operators have equal or higher precedence than the current token. Push current
#token (operator) onto the stack
p = precedence(i)
#print i
while len(stack) != 0 and p <= precedence(stack[-1]) :
print stack
postfix.append(stack.pop())
stack.append(i)
while len(stack) > 0 : #Add to postfix
postfix.append(stack.pop())
evalPostfix(postfix) #Call evalPostFix to get result
def evalPostfix(postfix_expression):
stack = []
for token in postfix_expression :
if token in operator_functions:
no1 = int(stack.pop()) #First Number
no2 = int(stack.pop()) #Second Number
stack.append(operator_functions[token](no2, no1))
else :
stack.append(token)
print ' '.join(postfix_expression),'=',stack.pop() #The Result
##########
#Main Code
##########
if len(sys.argv) == 2: #Read from file
f = open( sys.argv[1] )
elif len(sys.argv) == 1: #Read from stdin
f = sys.stdin
else:
print 'Invalid Number of arguments. Supply either no arguments or an input file.'
sys.exit(0)
lines = [line.strip() for line in f]
for i in lines:
arr=[] #Array containing all infix expressions
tokens = tokenise( i )
for t in tokens :
#print t
arr.append(t)
infix2postfix(arr) #Call infix2postfix
Input example:
1 + 2 - 3
Output example:
1 2 + 3 - = 0
That works as desired, but when I try this:
Input:
13 + 23 - 42 * 2
I get
Output:
13 23 + 42 - 2 * = -12
Instead of:
13 23 + 42 2 * - = -48
I am not sure what is going wrong. Any ideas?
Use == instead of is operator , there is difference between is and ==, is check returns True when both objects are same == returns true if value are equal.
additionally, Condition:
s is '+' or '-':
Should be:
s == '+' or s == '-':
Note an non-empty string is always true e.g.
>>> bool('')
False
>>> bool('+')
True