I had a student I tutored today say that his teacher didn’t like some code he did even though it worked.
He showed me the code and it was something like this:
if bmi < 25 > 18.5:
print (“message1”)
if bmi > 25:
print (“message2”)
if bmi < 18.5:
print (“message3”)
And it worked! He came up with this on his own (it doesn’t work for bmi exactly equal to 18.5 but that’s a side point).
Is this a known thing? So people often stack multiple conditions in one line like that in Python? Have I been missing out? And how does it parse them? Is it treated as “or” or “and”?
He definitely had bmi first and the < and > later, and we tried all 3 test cases and they all worked. I can see why his teacher told him to do it over again
(looking back, I think it was printing double messages and he only noticed the second ones. I am reconstructing this from memory, I just known the variable came before both inequalities)
Although chaining operators are perfectly legal, I can understand why the teacher didn’t like this example written like that. Consider the alternative:
Now if we want to change the boundary values, we only need to change them in one place. In the original one you need to update each boundary twice and keep them in sync.
Yeah, the intent is that you can do things like a < expensive_function() < c, without evaluating expensive_function twice. It’s not recommended to use comparisons in multiple directions like this, because it’s hard to understand at a glance—18.5 < bmi < 25 is the clearer way to write it.
A friend once accidentally typed x in y in z as a Python expression, and it took us the longest time to figure out (a) why it was legal and (b) what Python thought it meant.
Formally, if a, b, c, …, y, z are expressions and op1, op2, …, opN are comparison operators, then a op1 b op2 c … y opN z is equivalent to a op1 b and b op2 c and … y opN z, except that each expression is evaluated at most once.
IF-linking point: this clean version works in Ren’Py, the original formulation does not. Firstly, Ren’Py requires “and” or “or” between conditions (so, bmi < 25 and bmi > 18.5). Secondly, “elif” allows the check to be skipped if an earlier check satisfies it, whereas “if” gets treated as a separate check.
bmi > 18.5 excludes 18.5, while => 18.5 includes it. A Ren’Py teacher would probably prefer:
if bmi <= 25 and bmi >= 18.5:
(consequence tabbed)
elif bmi > 25:
(consequences tabbed)
else:
(consequences tabbed)
The latter doesn’t just cover underweight situation, it also catches situations where someone typed in letters, special characters or a negative number. Since the console is always accessible in Ren’Py (barring some truly spectacular means to block it) and it’s always possible to use it to change variables if one knows what the variables are, having an IF that can handle things when someone tries such a trick is a good idea.