While playing around with pyautogui I decided to make a method to limit the position of my cursor depending on the size of my monitor, since I was moving my cursor randomy.
This is what my first attempt looked like.
max_x = 10
max_y = 40
def limitXandY(x_arg, y_arg):
# expected to outputs a tuple of integers with length 2
return x_arg, y_arg if x_arg < max_x and y_arg < max_y else max_x, max_y
When running the code I did not get the expected output.
print(limitXandY(5, 19)) # (5, 19, 40) => (x_arg, y_arg, max_y)
x, y = limitXandY(5, 19) # ValueError: too many values to unpack (expected 2)
print(limitXandY(50, 100)) # (50, 10, 40) => (x_arg, max_x, max_y)
x, y = limitXandY(50, 100) # ValueError: too many values to unpack (expected 2)
As you can see above, my method returns a tuple of length 3 instead of 2. If the ternary operator goes in the if statement, I get the desired output plus last value of the else statement and if the operator returns in the else statement, I get the first value of the if statement as the first value of the methods output tuple.
I have found a work around using parentheses, but this doesn't really satisfy me and I would like to understand why this ternary operator acts like this.
def correctedLimitXandY(x_arg, y_arg):
# expected to output a tuple of tuple with length 1
# inner tuple should containt integers of length 2
return (x_arg, y_arg) if x_arg < max_x and y_arg < max_y else (max_x, max_y)
print(correctedLimitXandY(5, 19)) # (5, 19) => (x_arg, y_arg)
x, y = correctedLimitXandY(5, 19) # no error
print(correctedLimitXandY(50, 100)) # (10, 40) => (max_x, max_y)
x, y = correctedLimitXandY(50, 100) # no error
Any explanations would be a help!
While ternaries have a fairly low precedence, they're still considered an operator and thus binding "tighter" than tuple literal, much like e.g.
is interpreted as
not
When you write
Python will first "resolve"
<, thenand, thenif/else, and only after that does it resolve the tuples, so the result is:You can infer this from the full language grammar, specifically:
Here you can see that an
expressionsis a comma-separated sequence ofexpression, and eachexpressioncan be a ternary (if/else), therefore the language "resolves" ternaries (the inner structure) first.