if statement short circuiting
-
- Posts: 22
- Joined: Wed Jan 13, 2021 6:08 pm
- Location: Northern Florida
if statement short circuiting
I'm new to Python and MicroPython so a circumstance came up where I was wondering of those who knew more about the Python language and processing might know about the execution of "if" statement conditions and whether there's any short-circuiting with "if" statements that have multiple conditions, for example: if a > b and b > c and c < d: In some languages the execution will immediately move on to the next line of code if the first condition fails, while others will evaluate every condition before it moves onto the next. In the case of the former, putting together an "if" statement with a 1/2 dozen conditions will run faster the first condition fails, and in some cases the latter will also use up more memory.
Re: if statement short circuiting
You can use expressions with observable side-effects to find out what the implementation is doing:
will succeed, while
will tell you that foo isn't defined.
Out of curiosity, which languages have a different evaluation-order for their boolean operators?
Code: Select all
if False && foo[0]:
pass
Code: Select all
if True && foo[0]:
pass
Out of curiosity, which languages have a different evaluation-order for their boolean operators?
Re: if statement short circuiting
https://docs.python.org/3/library/stdty ... and-or-not so yes, supported.
Also wondering which languages (which are effectively in use) do not support short circuiting.
Also wondering which languages (which are effectively in use) do not support short circuiting.
Re: if statement short circuiting
Well, MATLAB has short-circuiting and non-short-circuiting versions of the logical operators:
executes without an error, but
fails.
(The non-short-circuiting version can operate on array as well as scalar inputs - and it does short-circuit if it's in the condition of an if or while.)
Code: Select all
x = false && undefined
Code: Select all
x = false & undefined
(The non-short-circuiting version can operate on array as well as scalar inputs - and it does short-circuit if it's in the condition of an if or while.)
-
- Posts: 22
- Joined: Wed Jan 13, 2021 6:08 pm
- Location: Northern Florida
Re: if statement short circuiting
From what I've read since I posted this, Python does short-circuit if statements.
There are a few languages and what I'll call DEs (development environments) that don't short-circuit, such as MSSQL and C# (at least for some boolean expressions). To short-circuit in C# and SQL you need to use "case" statements. I'm not a big VB developer, but since they're all based on the CRL, I suspect that any CRL will not short-circuit.
My query originated largely because there is no "case" handling in Python and I'm trying to optimize if statements that have multiple conditions. In languages where there is no case, I'd do a cascading (b-tree style) if statement to reduce the number of times a condition was tested, but that makes it harder to test and read. Now that I know it short-circuits, I just have to figure out a good way to emulate a case statement.
There are a few languages and what I'll call DEs (development environments) that don't short-circuit, such as MSSQL and C# (at least for some boolean expressions). To short-circuit in C# and SQL you need to use "case" statements. I'm not a big VB developer, but since they're all based on the CRL, I suspect that any CRL will not short-circuit.
My query originated largely because there is no "case" handling in Python and I'm trying to optimize if statements that have multiple conditions. In languages where there is no case, I'd do a cascading (b-tree style) if statement to reduce the number of times a condition was tested, but that makes it harder to test and read. Now that I know it short-circuits, I just have to figure out a good way to emulate a case statement.
Re: if statement short circuiting
Fair point about Matlab. Funny, because I use it from time to time, but never looked at it that way. Nor realized it does short-circuit sometimes and sometimes doesn't.
Hard to tell without actual code, but if it's really like one big case you could use a dict instead i.e.I just have to figure out a good way to emulate a case statement
Code: Select all
print({'a': 0, 'b': 1, 'c': 2}['b']) # Prints 1
-
- Posts: 22
- Joined: Wed Jan 13, 2021 6:08 pm
- Location: Northern Florida
Re: if statement short circuiting
I've researched using a dictionary to substitute for a case statement, but that seems to work only if you're just returning a value, say month of the year, or day of the week. I'm having a hard time figuring out how to make that useful for executing a function. For example, here's a case statement from an Arduino project:
Is there a way to use a dictionary for something like that?
Code: Select all
void displaySegment(int controller, int digit, char segment)
{
// testLED(digit, "segment : " + segment);
switch (segment)
{
case 'A':
{
lc.setRow(controller, digit, B01000000); // segment A
break;
}
case 'B':
{
lc.setRow(controller, digit, B00100000); // segment B
break;
}
case 'C':
{
lc.setRow(controller, digit, B00010000); // segment C
break;
}
case 'D':
{
lc.setRow(controller, digit, B00001000); // segment D
break;
}
case 'E':
{
lc.setRow(controller, digit, B00000100); // segment E
break;
}
case 'F':
{
lc.setRow(controller, digit, B00000010); // segment F
break;
}
case 'G':
{
lc.setRow(controller, digit, B00000001); // segment G
break;
}
case 'P':
{
lc.setRow(controller, digit, B10000000); // decimal place
break;
}
case 'N':
{
lc.setRow(controller, digit, B00000000); // none
break;
}
}
}
Re: if statement short circuiting
You could use a lambda function as the value. Something like this: will give these results: For more complex things you can use a function: and you can return values as well:which produces
Code: Select all
case = {
'a': lambda: print('case a called'),
'b': lambda: print('case b called'),
}
case['a']()
case['b']()
case2 = {
'a': lambda x: print('case a called, x =', x),
'b': lambda x: print('case b called, x =', x),
}
case2['a'](123)
case2['b']('some string')
Code: Select all
case a called
case b called
case a called, x = 123
case b called, x = some string
Code: Select all
def foo(arg):
print('foo called with arg =', arg)
case3 = {
'd': foo,
'e': lambda arg: print('lambda called arg =', arg)
}
case3['d']('argument to foo')
case3['e']('argument to lambda')
Code: Select all
def bar(num):
return num * 2
case4 = {
'f': bar,
'g': lambda arg: arg * 4
}
print("Result of calling case4['f'] =", case4['f'](7))
print("Result of calling case4['g'] =", case4['g'](7))
Code: Select all
Result of calling case4['f'] = 14
Result of calling case4['g'] = 28
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: if statement short circuiting
The general point here is that in Python a callable is a first class object and can be stored in dictionaries, lists or sets. Though I doubt there's much application for the latter. You can pass callables as arguments to other callables, and return them as results. This enables a lot of flexibility.
A callable is anything that accepts function call syntax, including functions, methods, class constructors and objects with a __call__ special method.
A callable is anything that accepts function call syntax, including functions, methods, class constructors and objects with a __call__ special method.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 22
- Joined: Wed Jan 13, 2021 6:08 pm
- Location: Northern Florida
Re: if statement short circuiting
Thanks for the help.
I've rewritten
as
Easier to read and manage. The only issue is that I think Python is converting the binary values into an integer and it's messing up the call to setRow().
I've rewritten
Code: Select all
def drawCircle(display, digit, speed=1):
display.setRow(display,digit,0b01000000) #Segment A
sleep(speed)
display.setRow(display,digit,0b00100000) #Segment B
sleep(speed)
display.setRow(display,digit,0b00010000) #Segment C
sleep(speed)
display.setRow(display,digit,0b00001000) #Segment D
sleep(speed)
display.setRow(display,digit,0b00000100) #Segment E
sleep(speed)
display.setRow(display,digit,0b00000010) #Segment F
sleep(speed)
display.setRow(display,digit,0b00000000) #clear last segment
sleep(speed)
Code: Select all
def segmentBinary(segment):
switcher={
'A' : 0b01000000,
'B' : 0b00100000,
'C' : 0b00010000,
'D' : 0b00001000,
'E' : 0b00000100,
'F' : 0b00000010,
'G' : 0b00000001,
'P' : 0b10000000, #dot
'N' : 0b00000000, #no segment
}
return switcher.get(segment, 0b00000000)
def drawCircle(display, digit, speed=1):
segs = ['A', 'B', 'C', 'D', 'E', 'F', 'N']
for seg in (segs):
display.setRow(display,digit,segmentBinary(seg))
sleep(speed)