conditional expression sought

E

Elaine Jackson

If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j without
evaluating any other B_i. This is such a useful mode of expression that I would
like to be able to use something similar even when there is an i with
bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and [B_1])
or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for obvious
reasons. Does anybody know a good way to express this? Any help will be mucho
appreciado.

Peace
 
M

Mark McEahern

Elaine said:
If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j without
evaluating any other B_i. This is such a useful mode of expression that I would
like to be able to use something similar even when there is an i with
bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and [B_1])
or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for obvious
reasons. Does anybody know a good way to express this? Any help will be mucho
appreciado.
Why not write a unit test that demonstrates the behavior you want?
It'll then likely be obvious to someone both what your problem is and
what a likely solution is.

Cheers,

// m
 
W

wes weston

Preferably, a program that runs or a screen dump.

Mark said:
Elaine said:
If bool(B_i)==True for 1<=i<=n and j is the smallest i with
bool(A_j)==True,
then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns
B_j without
evaluating any other B_i. This is such a useful mode of expression
that I would
like to be able to use something similar even when there is an i with
bool(B_i)==False. The only thing I can think of by myself is ( (A_1
and [B_1])
or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for
obvious
reasons. Does anybody know a good way to express this? Any help will
be mucho
appreciado.
Why not write a unit test that demonstrates the behavior you want?
It'll then likely be obvious to someone both what your problem is and
what a likely solution is.

Cheers,

// m
 
C

Corey Coughlin

Elaine Jackson said:
If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j without
evaluating any other B_i. This is such a useful mode of expression that I would
like to be able to use something similar even when there is an i with
bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and [B_1])
or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for obvious
reasons. Does anybody know a good way to express this? Any help will be mucho
appreciado.

Peace

Oh, this must be part of your truth table script. Interesting,
looking for something like a fast SOP evaluator, or more like a
function evaluation mechanism? It would probably be most useful to
share your containers for A and B. Are you really going to have
variables named A_1 to A_n, or will you just have a vector A[0:n]?
The vector would probably be easier to deal with. Using integer
representations for your boolean vectors is a good idea, and will
probably buy you enough speed that you won't need a more serious form
of short circuit evaluation, I imagine. Unless your vectors are very
large indeed. Hmm...
 
D

Dave K

If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j without
evaluating any other B_i. This is such a useful mode of expression that I would
like to be able to use something similar even when there is an i with
bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and [B_1])
or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for obvious
reasons. Does anybody know a good way to express this? Any help will be mucho
appreciado.

Peace

I'm not sure if this is what you're looking for, but for i > a very
small number, the zip function seems more appropriate:
for a, b in zip(A, B):
if a: return b
return A[-1]
print get_B_i([False, False, True, False], [0, 1, 2, 3]) 2
print get_B_i([False, False, False, False], [0, 1, 2, 3])
False

This has exactly the same effect provided that A and B are the same
length, otherwise the return value by failure should be adjusted to
whatever suits your purpose.

If you really want to write a conditional expression out in full, I
can't think of anything non-clumsy that would work for all possible
values of B_i, so unfortunately can't help you there.

Dave
 
E

Elaine Jackson

Sorry to take so long but I wasn't sure what a "unit test" was (the other guy's
post clarified it). Tell me if this isn't what you're looking for:

falsies=[0,0.0,[],(),{},'',None]
truies=[49,3.14,[1,2,3],(4,5,6),{7:8,9:10},'nonempty']

def demo(A,B):
print "If A is ",A
print "and B is ",B
print "then (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2]) = ",
print (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2])

A=[]
from random import randint
for i in range(3):
A.append(bool(randint(0,1)))
B=truies[0:3]
demo(A,B)

A=[False,False,False]
B=falsies[0:3]
demo(A,B)
print "I would have liked this to be B[2] = ",B[2]


| Elaine Jackson wrote:
|
| >If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
| >then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j
without
| >evaluating any other B_i. This is such a useful mode of expression that I
would
| >like to be able to use something similar even when there is an i with
| >bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and
[B_1])
| >or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for
obvious
| >reasons. Does anybody know a good way to express this? Any help will be mucho
| >appreciado.
| >
| Why not write a unit test that demonstrates the behavior you want?
| It'll then likely be obvious to someone both what your problem is and
| what a likely solution is.
|
| Cheers,
|
| // m
|
 
W

wes weston

Elaine,
The last code line:

print "I would have liked this to be B[2] = ",B[2]

prints the value of B[2]; the value you don't want.
I think what you meant was that you want B[2] to be
0.0 not false. bool(0.0) does equal false.
---------------------------------------------------
The code:

A.append(bool(randint(0,1)))

will always yield an A of [true,true,true]
---------------------------------------------------
I didn't know this about python, and I'm not sure I
like it:

wes@linux:~/amy> python
2.2

The order is important. To me, it should be printing true
and not either number or the last number.
 
E

Elaine Jackson

This is a good idea. Thanks for pointing it out.

| On Thu, 29 Jan 2004 17:58:45 GMT in comp.lang.python, "Elaine Jackson"
|
| >If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
| >then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j
without
| >evaluating any other B_i. This is such a useful mode of expression that I
would
| >like to be able to use something similar even when there is an i with
| >bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and
[B_1])
| >or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for
obvious
| >reasons. Does anybody know a good way to express this? Any help will be mucho
| >appreciado.
| >
| >Peace
| >
|
| I'm not sure if this is what you're looking for, but for i > a very
| small number, the zip function seems more appropriate:
|
| >>> def get_B_i(A, B):
| for a, b in zip(A, B):
| if a: return b
| return A[-1]
| >>> print get_B_i([False, False, True, False], [0, 1, 2, 3])
| 2
| >>> print get_B_i([False, False, False, False], [0, 1, 2, 3])
| False
|
| This has exactly the same effect provided that A and B are the same
| length, otherwise the return value by failure should be adjusted to
| whatever suits your purpose.
|
| If you really want to write a conditional expression out in full, I
| can't think of anything non-clumsy that would work for all possible
| values of B_i, so unfortunately can't help you there.
|
| Dave
|
|
 
E

Elaine Jackson

This is just for theoretical interest. The A_i's and B_i's were meant as
metavariables.

| > If bool(B_i)==True for 1<=i<=n and j is the smallest i with bool(A_j)==True,
| > then the evaluation of (A_1 and B_1) or ... or (A_n and B_n) returns B_j
without
| > evaluating any other B_i. This is such a useful mode of expression that I
would
| > like to be able to use something similar even when there is an i with
| > bool(B_i)==False. The only thing I can think of by myself is ( (A_1 and
[B_1])
| > or ... or (A_n and [B_n]) )[0], and I can't be satisfied with that for
obvious
| > reasons. Does anybody know a good way to express this? Any help will be
mucho
| > appreciado.
| >
| > Peace
|
| Oh, this must be part of your truth table script. Interesting,
| looking for something like a fast SOP evaluator, or more like a
| function evaluation mechanism? It would probably be most useful to
| share your containers for A and B. Are you really going to have
| variables named A_1 to A_n, or will you just have a vector A[0:n]?
| The vector would probably be easier to deal with. Using integer
| representations for your boolean vectors is a good idea, and will
| probably buy you enough speed that you won't need a more serious form
| of short circuit evaluation, I imagine. Unless your vectors are very
| large indeed. Hmm...
 
E

Elaine Jackson

Thanks for your help. I just looked at some values of random.randint(0,1) in my
interpreter, and one of them was 0. Getting nonboolean values from conjunction
and disjunction allows conditional evaluation of expressions; for example:
reciprocal = lambda x: (x!=0 and 1.0/x) or (x==0 and "undefined").

| Elaine,
| The last code line:
|
| print "I would have liked this to be B[2] = ",B[2]
|
| prints the value of B[2]; the value you don't want.
| I think what you meant was that you want B[2] to be
| 0.0 not false. bool(0.0) does equal false.
| ---------------------------------------------------
| The code:
|
| A.append(bool(randint(0,1)))
|
| will always yield an A of [true,true,true]
| ---------------------------------------------------
| I didn't know this about python, and I'm not sure I
| like it:
|
| wes@linux:~/amy> python
|
| >>> print 1.1 and 2.2
| 2.2
| >>> print 2.2 and 1.1
| 1.1
| >>> print (1.1 and 2.2)
| 2.2
|
| The order is important. To me, it should be printing true
| and not either number or the last number.
|
 
M

Mark McEahern

Elaine said:
Sorry to take so long but I wasn't sure what a "unit test" was (the other guy's
post clarified it). Tell me if this isn't what you're looking for:

falsies=[0,0.0,[],(),{},'',None]
truies=[49,3.14,[1,2,3],(4,5,6),{7:8,9:10},'nonempty']

def demo(A,B):
print "If A is ",A
print "and B is ",B
print "then (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2]) = ",
print (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2])

A=[]
from random import randint
for i in range(3):
A.append(bool(randint(0,1)))
B=truies[0:3]
demo(A,B)

A=[False,False,False]
B=falsies[0:3]
demo(A,B)
print "I would have liked this to be B[2] = ",B[2]

Try this:

def whatever(A, B):
"""I don't know what to call this function because it doesn't really
make sense to me, but, whatever..."""
c = zip(A, B)
last = len(c) - 1
for i, item in enumerate(c):
a, b = item
# If both items are true, return b.
if a and b:
return b
# If we're at the last item, return b.
if i == last:
return b

print whatever(A, B)

import unittest

class test(unittest.TestCase):

def testAllFalse(self):
A = [False, False, False]
B = [0, 0.0, []]
expected = []
actual = whatever(A, B)
self.assertEquals(actual, expected)

def testSomeTrue(self):
A = [0, 1, 0, 1, 0, 1]
B = ['a', 'b', 'c', 'd', 'e', 'f']
expected = 'b'
actual = whatever(A, B)
self.assertEquals(actual, expected)

unittest.main()
 
W

wes weston

oops;

The code:

A.append(bool(randint(0,1)))

will always yield an A of [true,true,true]


WRONG; was thinking it was a rand float;.


Thanks for replying to all who tried to help.

wes



wes said:
Elaine,
The last code line:

print "I would have liked this to be B[2] = ",B[2]

prints the value of B[2]; the value you don't want.
I think what you meant was that you want B[2] to be
0.0 not false. bool(0.0) does equal false.
---------------------------------------------------
The code:

A.append(bool(randint(0,1)))

will always yield an A of [true,true,true]
---------------------------------------------------
I didn't know this about python, and I'm not sure I
like it:

wes@linux:~/amy> python
2.2

The order is important. To me, it should be printing true
and not either number or the last number.
 
D

Dave K

Sorry to take so long but I wasn't sure what a "unit test" was (the other guy's
post clarified it). Tell me if this isn't what you're looking for:

falsies=[0,0.0,[],(),{},'',None]
truies=[49,3.14,[1,2,3],(4,5,6),{7:8,9:10},'nonempty']

def demo(A,B):
print "If A is ",A
print "and B is ",B
print "then (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2]) = ",
print (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2])

A=[]
from random import randint
for i in range(3):
A.append(bool(randint(0,1)))
B=truies[0:3]
demo(A,B)

A=[False,False,False]
B=falsies[0:3]
demo(A,B)
print "I would have liked this to be B[2] = ",B[2]
(snip)

Do you mean that the expression should return the last element in B if
all elements in A are false? If all subexpressions before the last are
false, the whole conditional reduces to:
A[-1] and B[-1]

So simply force (a copy of) A[-1] to always be true. Instead of
rewriting demo, I'll cheat by modifying the call:
A=[False, False, False]
B=[0, 0.0, []]
demo(A[:-1]+[True], B)
If A is [False, False, True]
and B is [0, 0.0, []]
then (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2]) = [][False, False, False]

For complete generality, you should also consider the case where
len(A) != len(B). Truncate the longer list, or extend the shorter?
Does it matter which list is shorter? Or forget the whole mess and
raise an exception? There are lots of reasonable possibilities, but
they won't all lead to the same result for certain input values.
You're in charge of this project, you decide :)

Dave
 
E

Elaine Jackson

Thanks. I've got this straightened around in my head now. I just sort-of
'panicked' when I saw a boolean literal where I didn't expect one to be (ie:
returned by the expression with the A's and B's when all the A's are False). I
realized later that that's what I should have expected, and that you could
always just add "...or undefined()" to such an expression, where

def undefined():
raise "undefined conditional expression"

This is all just part of my newbie efforts to assimilate the language. Anyway,
thanks again for your help.

Peace

| On Fri, 30 Jan 2004 01:06:55 GMT in comp.lang.python, "Elaine Jackson"
|
| >Sorry to take so long but I wasn't sure what a "unit test" was (the other
guy's
| >post clarified it). Tell me if this isn't what you're looking for:
| >
| >falsies=[0,0.0,[],(),{},'',None]
| >truies=[49,3.14,[1,2,3],(4,5,6),{7:8,9:10},'nonempty']
| >
| >def demo(A,B):
| > print "If A is ",A
| > print "and B is ",B
| > print "then (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2]) = ",
| > print (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2])
| >
| >A=[]
| >from random import randint
| >for i in range(3):
| > A.append(bool(randint(0,1)))
| >B=truies[0:3]
| >demo(A,B)
| >
| >A=[False,False,False]
| >B=falsies[0:3]
| >demo(A,B)
| >print "I would have liked this to be B[2] = ",B[2]
| >
| (snip)
|
| Do you mean that the expression should return the last element in B if
| all elements in A are false? If all subexpressions before the last are
| false, the whole conditional reduces to:
| A[-1] and B[-1]
|
| So simply force (a copy of) A[-1] to always be true. Instead of
| rewriting demo, I'll cheat by modifying the call:
|
| >>> A=[False, False, False]
| >>> B=[0, 0.0, []]
| >>> demo(A[:-1]+[True], B)
| If A is [False, False, True]
| and B is [0, 0.0, []]
| then (A[0] and B[0]) or (A[1] and B[1]) or (A[2] and B[2]) = []
| >>> print A
| [False, False, False]
|
| For complete generality, you should also consider the case where
| len(A) != len(B). Truncate the longer list, or extend the shorter?
| Does it matter which list is shorter? Or forget the whole mess and
| raise an exception? There are lots of reasonable possibilities, but
| they won't all lead to the same result for certain input values.
| You're in charge of this project, you decide :)
|
| Dave
 

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,596
Members
45,143
Latest member
SterlingLa
Top