(no) fast boolean evaluation ?

E

Ed Leafe

Sorry, I forgot to mention the language did not allow to have else
& if
in the same statement. IOW :

if some_condition then
do_sometehing
else
if some_other_condition then
do_something_else
else
if yet_another_condition then
do_yet_another_thing
else
if your_still_here then
give_up('this language is definitively brain dead')
end if
end if
end if
end if

Usually that's because the language provides a switch/case statement
construct. If it does and you try to write the above code, it isn't
the language that's brain-dead! ;-)

-- Ed Leafe
-- http://leafe.com
-- http://dabodev.com
 
N

Neil Cerutti

Usually that's because the language provides a switch/case
statement construct. If it does and you try to write the above
code, it isn't the language that's brain-dead! ;-)

The switch statements I'm aware of are less generally applicable
than a tower of "if { else if }* else". For example, with a
switch statement you have to dispatch on the one value for every
case.

In some languages, it's even of more limited, e.g., C, which can
switch on only integers.
 
I

Irmen de Jong

John said:
(you_are_confused and/or
function_returns_bool_but_has__side_effects())

That above expression should be written more explicitly like:

function_result = function_returning_bool_but_with_side_effects()

if you_are_confused or function_result:
do_something_nice()


--irmen
 
T

Terry Reedy

| John Machin wrote:
| So now I'm left with just one question:
| for bitwise operations I should use &, |, ^
| for boolean operations I should use and, or, xor
| but after doing some test I find strange effects:
| >>> A = 4
| >>> B = 5
| >>> A and B
| 5
4

| >>> A & B
| 4
| >>> A or B
| 4
5

| >>> A | B
| 5
|
| So if I use the bitwise operation on integers,
| "and" changes into (bitwise) "or" and vise versa.

No, you hypnotised yourself by generalizing from insufficient data.
Repeat experiment with, for instance, 3 and 4 instead of 4 and 5. Then 3&4
= 0, 3|4 = 7.

tjr
 
F

Frank Swarbrick

Ian said:
It's called short circuit evaluation and as far as I know it's standard
in most all languages. This only occurs if a conditional evaluates to
True and the only other operators that still need to be evaluated are
'or's or the condition evaluates to False and all the other operators
are 'and's. The reason is those other operators will never change the
outcome: True or'd with any number of False's will still be True and
False and'ed to any number of Trues will still be False.

My question would be why would you *not* want this?

Pascal, and apparently Fortran, do not use short-circuit evaluation. I
remember learning this gotcha in my seventh-grade Pascal class (plus I
just googled it to make sure my memory was correct!).

Frank
 
P

Paddy

hello,

I discovered that boolean evaluation in Python is done "fast"
(as soon as the condition is ok, the rest of the expression is ignored).

Is this standard behavior or is there a compiler switch to turn it on/off ?

thanks,
Stef Mientki

The following program shows a(clumsy)? way to defeat the short-
circuiting:


def f(x):
print "f(%s)=%s" % ('x',x),
return x
def g(x):
print "g(%s)=%s" % ('x',x),
return x

print "\nShort circuit"
for i in (True, False):
for j in (True, False):
print i,j,":", f(i) and g(j)

print "\nShort circuit defeated"
for i in (True, False):
for j in (True, False):
print i,j,":", g(j) if f(i) else (g(j) and False)


The output is:

Short circuit
True True : f(x)=True g(x)=True True
True False : f(x)=True g(x)=False False
False True : f(x)=False False
False False : f(x)=False False

Short circuit defeated
True True : f(x)=True g(x)=True True
True False : f(x)=True g(x)=False False
False True : f(x)=False g(x)=True False
False False : f(x)=False g(x)=False False


- Paddy.
 
P

Paddy

The following program shows a(clumsy)? way to defeat the short-
circuiting:

def f(x):
print "f(%s)=%s" % ('x',x),
return x
def g(x):
print "g(%s)=%s" % ('x',x),
return x

print "\nShort circuit"
for i in (True, False):
for j in (True, False):
print i,j,":", f(i) and g(j)

print "\nShort circuit defeated"
for i in (True, False):
for j in (True, False):
print i,j,":", g(j) if f(i) else (g(j) and False)

The output is:

Short circuit
True True : f(x)=True g(x)=True True
True False : f(x)=True g(x)=False False
False True : f(x)=False False
False False : f(x)=False False

Short circuit defeated
True True : f(x)=True g(x)=True True
True False : f(x)=True g(x)=False False
False True : f(x)=False g(x)=True False
False False : f(x)=False g(x)=False False

- Paddy.

And here are the bits for boolean OR:


print "\n\nShort circuit: OR"
for i in (True, False):
for j in (True, False):
print i,j,":", f(i) or g(j)

print "\nShort circuit defeated: OR"
for i in (True, False):
for j in (True, False):
print i,j,":", (g(j) or True) if f(i) else g(j)

- Paddy.
 
J

jim-on-linux

PY help,

Using sqlite3 v3.1.3

When I create a table collumn using;

newcollum VARCHAR(35),

I get a default of 10 spaces.

No matter what I set the size to I get 10 spqces,
even using varchar(0) defaults to 10 spaces.

I would appreciae the help if someone could tell
me what I'm missing, I want to varry the column
sizes.

jim-on-linux
 
P

Paddy

PY help,

Using sqlite3 v3.1.3

When I create a table collumn using;

newcollum VARCHAR(35),

I get a default of 10 spaces.

No matter what I set the size to I get 10 spqces,
even using varchar(0) defaults to 10 spaces.

I would appreciae the help if someone could tell
me what I'm missing, I want to varry the column
sizes.

jim-on-linux

Hi Jim,
You need to create a new thread for this new question so it gets
maximum visibility and so is more likely to be answered.

- Paddy.
 
C

Carsten Haese

PY help,

Using sqlite3 v3.1.3

When I create a table collumn using;

newcollum VARCHAR(35),

I get a default of 10 spaces.

No matter what I set the size to I get 10 spqces,
even using varchar(0) defaults to 10 spaces.

I would appreciae the help if someone could tell
me what I'm missing, I want to varry the column
sizes.

What you're missing is that sqlite columns are type-less. Column type
and size are irrelevant:
import sqlite3
conn = sqlite3.connect(":memory")
cur = conn.cursor()
cur.execute("create table t1 (c1 varchar(35))")
cur.executemany("insert into t1(c1) values(?)", .... [ ("X"*i*10,) for i in range(10) ] )
cur.execute("select * from t1")
for row in cur: print row
....
(u'',)
(u'XXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)

Even though the column was created to be 35 characters wide, it'll
happily accept 100-character strings.

HTH,
 
J

jim-on-linux

PY help,

Using sqlite3 v3.1.3

When I create a table collumn using;

newcollum VARCHAR(35),

I get a default of 10 spaces.

No matter what I set the size to I get 10
spqces, even using varchar(0) defaults to 10
spaces.

I would appreciae the help if someone could
tell me what I'm missing, I want to varry the
column sizes.

What you're missing is that sqlite columns are
type-less. Column type

and size are irrelevant:
... [ ("X"*i*10,) for i in range(10) ] )

...
(u'',)
(u'XXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',)
(u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
)

Even though the column was created to be 35
characters wide, it'll happily accept
100-character strings.

HTH,


Right, the data is there.
My question is framed wrong. Your answer pointed
out the flaw in the question.

Since I'm on linux, the database can be opened
with Knoda. Once opened the table collumns are
always 10 spaces so all the data is not readable
as presented. Not quite a python problem.

I can Tk a display for the data, just thought I
could save time by letting the user open the
table and read the data right from the table.

Thanks for the help.

jim-on-linux
 
B

Ben Finney

jim-on-linux said:
PY help,

Using sqlite3 v3.1.3

You made this message a reply to an existing discussion, so your
message is now part of that existing discussion. Please start a new
discussion thread by composing a new message.
 
D

Dennis Lee Bieber

if A and Some_Function (4 ):
print 'I knew it was True'
else:
print 'I''ll never print this'
</Python>

<Output>
Ive been here 4
I knew it was True
</Output

I was expected that the function would not be called,
because A is True.
No, the function HAS to be called "because A is True"... the
situation depends on the conjunction...

"and" can only be short-circuited when it is known that one side is
False. "if False and anything:" is ALWAYS false.

"or" can be short-circuited once it is known that one side is True.

In Ada, there is actually syntax to force short-circuit evaluation
-- otherwise the compiler code optimization is free to evaluate the
sides in any order...

if this and that then...
vs
if this and then that then...

if this or that then
vs
if this or else that then

<quote>
or_test ::= and_test | or_test "or" and_test
</quote

Can you imagine, while I'm not a programmer, just a human,
that I don't understand one bit of this line.

BNF (Backus-Naur Form)... It's a notation (language) for defining
the syntax of programming languages. You need to look at the definition
for an and_test to complete the mix...

What that says is that an "or_test" is either:

an "and_test"

or it is an "or_test" separated from an "and_test" by the literal word
"or"

A recursive definition, you'll note.

I suspect that "and_test" probably has something like (I'm not
looking it up)

and_test ::= boolean | and_test "and" or_test

(since an or_test can be a naked and_test, and that and_test could be a
naked boolean, the syntax supports boolean "and" boolean, along with
and_test "and" and_test)

Non-zero integers are "True" so the evaluation is

A is 4 (non-zero, true) thereby the "and" must evaluate the other
side to determine if the whole expression is true... For simplicity,
Python just "returns" the value of B, which is 5 (non-zero, true).


Bitwise... 0100 & 0101 => 0100

A is 4 (non-zero, true), therefore there is no need to look at be,
as no matter what value is in B, the expression is going to be "true" --
for simplicity, return the value of A.
Bitwise... 0100 | 0101 => 0101
So if I use the bitwise operation on integers,
"and" changes into (bitwise) "or" and vise versa.
No it doesn't -- you chose integers that mask the real behavior...
There is one bit in common (ignore common 0 bits), and one bit that
differs.

With 6 (0110) and 5 (0101) there are one bit in common, and two bits
that differ

"and" returned b
"or" returned a
& returned only the set (1) bits common to both, clear (0) bits for
others
| returned only the clear (0) bits common to both, set (1) bits for others

"and", "or" are concerned only with "truthness" -- which is
basically defined as: true is non-zero, non-empty, non-None, false is 0,
empty, None... They return (as the truth value) the exact source value
that determined the result of the operation.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
G

Gabriel Genellina

En Fri, 03 Aug 2007 11:56:07 -0300, Roel Schroeven
Paul Boddie schreef:

I even thought Pascal never uses short-circuit evaluation, and always
evaluates all terms. I might be wrong about that though; it's been quite
a long time since I've used Pascal.

Delphi defaults to short-circuit, but there is a compiler switch to make
it evaluate all the arguments.
But most people rely on this, and write code like:

if (MyObject <> nil) and (MyObject.Event <> nil) then MyObject.Event(Self);

and that would break if not short-circuited.
 
P

Paddy

And here are the bits for boolean OR:

print "\n\nShort circuit: OR"
for i in (True, False):
for j in (True, False):
print i,j,":", f(i) or g(j)

print "\nShort circuit defeated: OR"
for i in (True, False):
for j in (True, False):
print i,j,":", (g(j) or True) if f(i) else g(j)

- Paddy.

Dumb!
Use & and |
Gosh That port last night was good ;-)
 
B

Bruno Desthuilliers

Ed Leafe a écrit :
Usually that's because the language provides a switch/case statement
construct.

Err... You may have forgotten from lack of practice, but there are
complex conditions that may not always be expressed using a switch/case...
If it does and you try to write the above code, it isn't the
language that's brain-dead! ;-)

Lats time I checked, my brain was still alive.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top