FAQ

[Python] conditional expression sought

Elaine Jackson
Jan 29, 2004 at 5:58 pm
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
reply

Search Discussions

14 responses

  • Sidharth Kuruvila at Jan 29, 2004 at 6:18 pm
    since True and False
    can also evaluate as 1 and 0
    you can use the binary operators
    and &
    for or and and respectively
    class F:
    ... a = 5
    ... def b(self):
    ... self.a = 4
    ... return True
    ... def a(self):
    ... self.a = 1
    ... return False
    ...
    g = F()
    g.a() & g.b()
    False
    g.a
    4
    "Elaine Jackson" <elainejackson7355 at home.com> wrote in message
    news:pRbSb.330334$ts4.37644 at pd7tw3no...
    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
  • Mark McEahern at Jan 29, 2004 at 6:51 pm

    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
  • Wes weston at Jan 29, 2004 at 9:11 pm
    Preferably, a program that runs or a screen dump.

    Mark McEahern wrote:
    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
  • Corey Coughlin at Jan 30, 2004 at 12:25 am
    "Elaine Jackson" <elainejackson7355 at home.com> wrote in message news:<pRbSb.330334$ts4.37644 at pd7tw3no>...
    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...
  • Elaine Jackson at Jan 30, 2004 at 5:49 am
    This is just for theoretical interest. The A_i's and B_i's were meant as
    metavariables.

    "Corey Coughlin" <corey.coughlin at attbi.com> wrote in message
    news:a8623416.0401291625.594a9768 at posting.google.com...
    "Elaine Jackson" <elainejackson7355 at home.com> wrote in message
    news:<pRbSb.330334$ts4.37644 at pd7tw3no>...
    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...
  • Dave K at Jan 30, 2004 at 12:47 am

    On Thu, 29 Jan 2004 17:58:45 GMT in comp.lang.python, "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.

    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
  • Elaine Jackson at Jan 30, 2004 at 5:48 am
    This is a good idea. Thanks for pointing it out.

    "Dave K" <dk123456789 at REMOVEhotmail.com> wrote in message
    news:866j101bbuuhtpan29eop9o4mk1mt7nckn at 4ax.com...
    On Thu, 29 Jan 2004 17:58:45 GMT in comp.lang.python, "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.

    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
  • Elaine Jackson at Jan 30, 2004 at 1:06 am
    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]


    "Mark McEahern" <mark at mceahern.com> wrote in message
    news:mailman.1000.1075402284.12720.python-list at python.org...
    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
  • Wes weston at Jan 30, 2004 at 3:02 am
    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 at 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.
  • Elaine Jackson at Jan 30, 2004 at 6:07 am
    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").

    "wes weston" <wweston at att.net> wrote in message
    news:6PjSb.138487$6y6.2697536 at bgtnsc05-news.ops.worldnet.att.net...
    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 at 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.
  • Wes weston at Jan 30, 2004 at 2:28 pm
    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 weston wrote:
    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 at 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.
  • Mark McEahern at Jan 30, 2004 at 2:25 pm

    Elaine Jackson wrote:
    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()
  • Dave K at Jan 30, 2004 at 10:51 pm

    On Fri, 30 Jan 2004 01:06:55 GMT in comp.lang.python, "Elaine Jackson" wrote:

    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
  • Elaine Jackson at Jan 31, 2004 at 5:57 am
    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

    "Dave K" <dk123456789 at REMOVEhotmail.com> wrote in message
    news:ulnl10teov6ceq1q52laduq13d7u9edddd at 4ax.com...
    On Fri, 30 Jan 2004 01:06:55 GMT in comp.lang.python, "Elaine Jackson"
    wrote:
    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

Related Discussions