Re: simultaneous assignment

2006-05-10 Thread Boris Borcic
Steve R. Hastings wrote:

> You could also use a function that counts all different values in a list,
> reducing the list to a dictionary whose keys are the unique values from
> the list.  I got the idea from a discussion here on comp.lang.python; I
> called my version of it tally().
> 
> d = tally(bool(x) for x in seq)
> print d[True]  # prints how many true values in seq
> print d[False]  # prints how many false values in seq
> 
> 
> tally() is in my iterwrap.py module, which you can get here:
> 
> http://home.blarg.net/~steveha/iterwrap.tar.gz
> 

 >>> from itertools import groupby
 >>> tally = lambda it : dict((x,sum(1 for _ in y)) for x,y in 
 >>> groupby(sorted(it)))
 >>> tally('abbcabbcca')
{'a': 3, 'c': 3, 'b': 4}
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-04 Thread Paul Rubin
Dave Hansen <[EMAIL PROTECTED]> writes:
> Well, if you want something minimalist, you could try
> 
>def truth_test(seq):
>   return sum(1 for item in seq if item) == 1

def truth_test(seq):
   return sum(map(bool, seq)) == 1
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-04 Thread Dave Hansen
On Tue, 02 May 2006 18:52:48 GMT in comp.lang.python, John Salerno
<[EMAIL PROTECTED]> wrote:

[...]
>
>Yeah, after trying some crazy things, I just wrote it this way:
>
>def truth_test(seq):
> truth = 0
> for item in seq:
> if item:
> truth += 1
> if truth == 1:
> return True
> else:
> return False

You could replace those last four lines with

  return truth == 1

>
>Not sure I like having to keep a counter though, but the other stuff I 

Well, if you want something minimalist, you could try

   def truth_test(seq):
  return sum(1 for item in seq if item) == 1

Though I'm not sure it's really any clearer...

>did was really convoluted, like checking to see if the first item was 
>True, and if it was, popping it from the list and iterating over the 
>rest of the items (needless to say, the in-place change wasn't helpful).

Perhaps something like

   def truth_test(seq):
  found = False
  for item in seq:
 if item:
if found:
   return False
found = True
  return found

Gets you an early exit, anyway...

All code untested.  Regards,
-=Dave

-- 
Change is inevitable, progress is not.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-03 Thread Steve R. Hastings
On Wed, 03 May 2006 17:51:03 +, Edward Elliott wrote:

> Steve R. Hastings wrote:
>> You could also use a function that counts all different values in a list,
>> reducing the list to a dictionary whose keys are the unique values from
>> the list. 
> 
> Wouldn't reducing to a set instead of a dict make more sense if all you want
> to do is count uniq elements?

My apologies for not explaining tally() better.

The dict has one key for each unique element, and the value associated
with each key is a count of how many times that element appeared in the
original list.

lst = ['a', 'b', 'b', 'c', 'c', 'c']
d = iterwrap.tally(lst)
print d  # prints something like: {'a': 1, 'c': 3, 'b': 2}


If you didn't care how many times the values appeared in the original
list, and just just wanted the unique values, then a set would be perfect.

If you happen to have tally(), it is an easy way to solve the original
problem: figure out whether a list has exactly one true value in it.

d = tally(bool(x) for x in lst)
if d[True] == 1:
print "and there was much rejoicing"

-- 
Steve R. Hastings"Vita est"
[EMAIL PROTECTED]http://www.blarg.net/~steveha

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-03 Thread Edward Elliott
Steve R. Hastings wrote:
> You could also use a function that counts all different values in a list,
> reducing the list to a dictionary whose keys are the unique values from
> the list. 

Wouldn't reducing to a set instead of a dict make more sense if all you want
to do is count uniq elements?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-03 Thread John Salerno
bruno at modulix wrote:
> John Salerno wrote:
>> Bruno Desthuilliers wrote:
>>
>>> But my question (sorry, it may not have been clear) was more along the
>>> line of : "why do you worry about identity in the given snippet ?". 
>>
>> Actually, I kind of thought that maybe it *didn't* matter in this
>> particular example anyway, so my question was meant to be more general
>> than I might have written it. It seems like the identity issue can be a
>> problem in certain cases, although I can't think of a case right now! :)
> 
> something
> a = b = []
> a.append(1)
> print b
> 
> 

Ah ha!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-03 Thread Christos Georgiou
On Tue, 02 May 2006 17:15:05 GMT, rumours say that John Salerno
<[EMAIL PROTECTED]> might have written:

>Another thing I'm trying to do is write a function that tests to see if 
>a list contains exactly one true item, and the rest are false (obviously 
>this would have to be a list of boolean values, I guess). I'm sure this 
>isn't a handy utility, but I enjoy figuring out how to implement it.

>>> def true_count_is(predicates, count):
return count == sum(map(bool, predicates))

>>> true_count_is([True, True, False], 1)
False
>>> true_count_is([True, False, False], 1)
True
-- 
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-03 Thread bruno at modulix
John Salerno wrote:
> Bruno Desthuilliers wrote:
> 
>> But my question (sorry, it may not have been clear) was more along the
>> line of : "why do you worry about identity in the given snippet ?". 
> 
> 
> Actually, I kind of thought that maybe it *didn't* matter in this
> particular example anyway, so my question was meant to be more general
> than I might have written it. It seems like the identity issue can be a
> problem in certain cases, although I can't think of a case right now! :)

something
a = b = []
a.append(1)
print b


-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])"
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Steve R. Hastings
On Tue, 02 May 2006 21:44:21 +0200, Boris Borcic wrote:
> note that generators have no defined length - precisely because they feed
> values one at a time while you need them all together to speak of a
> length. The second expression will raise a TypeError because of that.

Er, yes.  If I had actually run that code, I would have seen that error.

Thank you for the correction.


> If you want to count objects 
> with a generator expression, use
> 
> sum(1 for v in seq if some_condition(v))
> 
> which is also clearer imho; summing ones for each item satisfying a
> condition - isn't that a definition of counting ?

That is indeed very clear and I like it.

You could also use a function that counts all different values in a list,
reducing the list to a dictionary whose keys are the unique values from
the list.  I got the idea from a discussion here on comp.lang.python; I
called my version of it tally().

d = tally(bool(x) for x in seq)
print d[True]  # prints how many true values in seq
print d[False]  # prints how many false values in seq


tally() is in my iterwrap.py module, which you can get here:

http://home.blarg.net/~steveha/iterwrap.tar.gz

-- 
Steve R. Hastings"Vita est"
[EMAIL PROTECTED]http://www.blarg.net/~steveha

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Steve R. Hastings
On Tue, 02 May 2006 12:58:14 -0700, Roger Miller wrote:

> Steve R. Hastings wrote:
> 
>> a = 0
>> b = 0
>> a is b  # always true
> 
> Is this guaranteed by the Python specification, or is it an artifact of
> the current implementation?

I believe it's an artifact of the current implementation.  And I only
tested that on CPython; I don't know if it will work like that on
Jython, IronPython, etc.  I can't imagine why the Python spec would
guarantee such a thing anyway.  :-)


> My understanding has been that an
> implementation is free to share integer objects or not, so using 'is'
> as an equality test takes you into undefined territory, regardless  of
> the size of the value.

This sounds correct to me.  (Note: I do not claim to be an authority on
Python!  But there are several authorities here who will no doubt correct
this if I am wrong.)
-- 
Steve R. Hastings"Vita est"
[EMAIL PROTECTED]http://www.blarg.net/~steveha

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Mel Wilson
Roger Miller wrote:
> Steve R. Hastings wrote:
> 
> 
>>a = 0
>>b = 0
>>a is b  # always true
> 
> 
> Is this guaranteed by the Python specification, or is it an artifact of
> the current implementation? 

AFAIK it's an artifact.  The performance hit it Python 
stopped sharing small integers could be enormous, 
nonetheless sharing isn't part of the specification
>My understanding has been that an
> implementation is free to share integer objects or not, so using 'is'
> as an equality test takes you into undefined territory, regardless  of
> the size of the value.
> 
I agree.  "is" is for working with linked-lists or trees, or 
other applications where object identity is really and truly 
what you're interested in.

Some amusing is/== facts, some suggested by recent threads

Python 2.4.2 (#1, Jan 23 2006, 21:24:54)
[GCC 3.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more 
information.
 >>> 0 is 0.0
False
 >>> -0.0 is 0.0
False
 >>> 0 == 0.0 == -0.0
True
 >>> 100 is (200/2)
False
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Steve R. Hastings
On Tue, 02 May 2006 21:20:48 +0200, Boris Borcic wrote:

> Steve R. Hastings wrote:
>> So, don't test to see if something is equal to True or False:
>> 
>> if 0 == False:
>> pass  # never executed; False and 0 do not directly compare
> 
> of course they do - ie  isinstance(False,int) is True and False == 0

I stand corrected.  I tested most of my examples; I thought I had tested
that example, but clearly I did not.

I just tried "0 == False" in Python and it does evaluate True.

"[] == False" still does not, of course...

Thank you for the correction.
-- 
Steve R. Hastings"Vita est"
[EMAIL PROTECTED]http://www.blarg.net/~steveha

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Grant Edwards
On 2006-05-03, John Salerno <[EMAIL PROTECTED]> wrote:
> Bruno Desthuilliers wrote:
>
>> But my question (sorry, it may not have been clear) was more
>> along the line of : "why do you worry about identity in the
>> given snippet ?". 
>
> Actually, I kind of thought that maybe it *didn't* matter in
> this particular example anyway, so my question was meant to be
> more general than I might have written it. It seems like the
> identity issue can be a problem in certain cases, although I
> can't think of a case right now! :)

When it seems like the "identity issue" is a problem, that
usually indicates you're looking at the problem from the wrong
angle. 

1/2 :)

-- 
Grant Edwards   grante Yow!  I am having a
  at   CONCEPTION--
   visi.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Bruno Desthuilliers wrote:

> But my question (sorry, it may not have been clear) was more along the 
> line of : "why do you worry about identity in the given snippet ?". 

Actually, I kind of thought that maybe it *didn't* matter in this 
particular example anyway, so my question was meant to be more general 
than I might have written it. It seems like the identity issue can be a 
problem in certain cases, although I can't think of a case right now! :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Heiko Wundram wrote:

> Hummm... Isn't it easier and faster to solve this problem by hand than to 
> code 
> a Python program for it? I had proofs for what has to be on both papers in 
> about 30 seconds... ;-)

Yeah, I had actually already figured it out in my head fairly quickly.

> If you're looking for things to code in Python, I'd rather suggest you look 
> at 
> number theory than at logic problems. Basically, every logic problem can be 
> solved by exhaustive search (which is always the same algorithm), whereas a 
> number theory problem requires that you implement a certain algorithm from 
> scratch for each problem you're trying to tackle.

Thanks for the suggestion. Do you know where I might find number theory 
problems that aren't too complicated? (No math degree here, in fact, 
just the opposite: English!)  :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Bruno Desthuilliers
Heiko Wundram a écrit :
(snip)
> If you're looking for things to code in Python, I'd rather suggest you look 
> at 
> number theory than at logic problems. 
 >
> Basically, every logic problem can be 
> solved by exhaustive search (which is always the same algorithm), whereas a 
> number theory problem requires that you implement a certain algorithm from 
> scratch for each problem you're trying to tackle.

Well... I do see the point, but still boolean logic is a mandatory part 
of programming, and one that wannabee programmers should get right.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Bruno Desthuilliers
John Salerno a écrit :
> bruno at modulix wrote:
> 
>> Now if I may ask: what is your actual problem ?
> 
> 
> Ok, since you're so curious. :)

Sorry !-)

> Here's a scan of the page from the puzzle book:
> http://johnjsalerno.com/spies.png
> 
> Basically I'm reading this book to give me little things to try out in 
> Python. There's no guarantee that this puzzle is even conducive to (or 
> worthy of) a programming solution.

Well, this is probably a good exercice in boolean logic - which is 
something very important in CS.

But my question (sorry, it may not have been clear) was more along the 
line of : "why do you worry about identity in the given snippet ?". 
Rebinding a name already bound to a given object doesn't affect other 
names bound to the same object. So in this case, multiple assignement is 
perfectly safe.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Heiko Wundram
Am Dienstag 02 Mai 2006 22:47 schrieb Gary Duzan:
> >Here's a scan of the page from the puzzle book:
> >http://johnjsalerno.com/spies.png
> >
> >Basically I'm reading this book to give me little things to try out in
> >Python. There's no guarantee that this puzzle is even conducive to (or
> >worthy of) a programming solution.
>
> Given the appropriate spy() function, this will return a set of
> values for the truthful (logically coherent) spy and nothing for
> the other spy. The details are left as an exercise for the reader.

Hummm... Isn't it easier and faster to solve this problem by hand than to code 
a Python program for it? I had proofs for what has to be on both papers in 
about 30 seconds... ;-)

If you're looking for things to code in Python, I'd rather suggest you look at 
number theory than at logic problems. Basically, every logic problem can be 
solved by exhaustive search (which is always the same algorithm), whereas a 
number theory problem requires that you implement a certain algorithm from 
scratch for each problem you're trying to tackle.

Implementing the sieve of Erathosthenes comes to mind straight away.

--- Heiko.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Grant Edwards
On 2006-05-02, Boris Borcic <[EMAIL PROTECTED]> wrote:
> Grant Edwards wrote:
>> On 2006-05-02, Boris Borcic <[EMAIL PROTECTED]> wrote:
>>> Grant Edwards wrote:
 Python knows how to count.  :)

 def countFalse(seq):
 return len([v for v in seq if not v])

 def countTrue(seq):
 return len([v for v in seq if v])

 def truth_test(seq):
 return countTrue(seq) == 1

>>> I'd suggest the more direct
>>>
>>> def countFalse(seq) :
>>>  return sum(1 for v in seq if not v)
>> 
>> I guess I don't see how that is more direct.
>> 
>> If you want to know how many items are in a seqneuce, you call
>> len().  
>
> sum doesn't construct a sequence

Doh!  I missed the fact that you used a generator rather than a
list comprehension.

>> Converting that list to a list of 1's
>
> that's not what my suggestion is doing

I see that now.

-- 
Grant Edwards   grante Yow!  Hey, waiter! I want
  at   a NEW SHIRT and a PONY TAIL
   visi.comwith lemon sauce!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Gary Duzan
In article <[EMAIL PROTECTED]>,
John Salerno  <[EMAIL PROTECTED]> wrote:
>bruno at modulix wrote:
>
>> Now if I may ask: what is your actual problem ?
>
>Ok, since you're so curious. :)
>
>Here's a scan of the page from the puzzle book:
>http://johnjsalerno.com/spies.png
>
>Basically I'm reading this book to give me little things to try out in 
>Python. There's no guarantee that this puzzle is even conducive to (or 
>worthy of) a programming solution.

   Exhaustive search is quite practical for this problem:

[(x,y,z,w) for x in (True, False)
   for y in (True, False)
   for z in (True, False)
   for w in (True, False)
   if spy(x,y,x,w)]

Given the appropriate spy() function, this will return a set of
values for the truthful (logically coherent) spy and nothing for
the other spy. The details are left as an exercise for the reader.
:-)

Gary Duzan
Motorola CHS


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Edward Elliott
Heiko Wundram wrote:
> Integer and string objects
> are immutable in Python, so why'd you want to have different IDs for an
> object of the same value? It's the value you're working with in a program,
> not the objects ID. At least it should be, if you're truly intent on
> working with the (pseudo-random) object-ID, something with your design is
> really, really broken.

Hence I said, this is an academic exercise.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Heiko Wundram
Am Dienstag 02 Mai 2006 22:39 schrieb Edward Elliott:
> Which raises an interesting parallel question:  is there a way to clone an
> arbitrary object?

Yes, check the copy module.

copy.copy() does a shallow copy of the parameter, copy.deepcopy() a deep copy 
of the parameter. For the difference between the two, check the manual. 
(basically, a deep copy copies the whole object tree for container objects 
such as lists/tuples/dicts/instances, a shallow copy copies only the topmost 
container)

> 
> but not small ones:
> >>> a = 5
> >>> b = a + 0
> >>> id(a) == id(b)
>
> True

What sense is there cloning integers/strings? Integer and string objects are 
immutable in Python, so why'd you want to have different IDs for an object of 
the same value? It's the value you're working with in a program, not the 
objects ID. At least it should be, if you're truly intent on working with the 
(pseudo-random) object-ID, something with your design is really, really 
broken.

--- Heiko.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Edward Elliott
bruno at modulix wrote:
> re-phrase it according to how Python works, and you'll get the answer:
> 
> "Is there a way to bind multiple names to the same object, but so the
> identity of this object is different from the identity of this object ?"

Which raises an interesting parallel question:  is there a way to clone an
arbitrary object?  If so you could do this:

>>> a = something
>>> b = clone (a)
>>> id(a) == id(b)
False

For lists, a slice-copy creates a clone:

>>> a = [1,2,3]
>>> b = a[:]
>>> id(a) == id(b)
False


For arithmetic types, an identity operation works for large values:

>>> a = 12345
>>> b = a + 0
>>> id(a) == id(b)
False

but not small ones:

>>> a = 5
>>> b = a + 0
>>> id(a) == id(b)
True

With booleans (and None) it will never work since the interpreter only
stores one copy of each value.

I'm not saying this approach is a good idea -- value semantics are almost
always preferable, and playing with interpreter internals usually leads to
trouble.  But as an academic exercise, how close can you get to a universal
clone function?


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Serge Orlov
John Salerno wrote:
> bruno at modulix wrote:
>
> > Now if I may ask: what is your actual problem ?
>
> Ok, since you're so curious. :)
>
> Here's a scan of the page from the puzzle book:
> http://johnjsalerno.com/spies.png
>
> Basically I'm reading this book to give me little things to try out in
> Python. There's no guarantee that this puzzle is even conducive to (or
> worthy of) a programming solution.

So what you're trying to do is to run over all possible combinations?
Anyway you don't need to worry about identity, since boolean values are
immutable. In general when you see statement like

some_var = immutable value

you can be *sure* you're changing *only* some_var

Warning! Half-spoiler below :) Following is a function run_over_space
from my personal utils package for generating all combinations and an
example how it can be applied to your puzzle:

def decrement(point, space):
""" Yield next point of iteration space """
for coord in range(len(point)):
if point[coord] > 0:
point[coord] -= 1
return
else:
point[coord] = space[coord]
continue
raise StopIteration

def run_over_space(space):
""" Yield all points of iteration space.
Space is a list of maximum values of each dimension"""
point = space[:]
while True:
yield point
decrement(point,space)

def describe_point(spy,w,x,y,z):
if spy:
print "Spy1 is right, ",
else:
print "Spy1 is wrong, ",
print "w, x, y, z = ", w, x, y, z

for point in run_over_space([1,1,1,1,1]):
describe_point(*point)

-- 
http://mail.python.org/mailman/listinfo/python-list


[SPOILER] Re: simultaneous assignment

2006-05-02 Thread Boris Borcic
John Salerno wrote:
> bruno at modulix wrote:
> 
>> Now if I may ask: what is your actual problem ?
> 
> Ok, since you're so curious. :)
> 
> Here's a scan of the page from the puzzle book:
> http://johnjsalerno.com/spies.png
> 
> Basically I'm reading this book to give me little things to try out in 
> Python. There's no guarantee that this puzzle is even conducive to (or 
> worthy of) a programming solution.

def spyAreports(W,X,Y,Z) :
 return W+X+Y == X+Y+Z == W+Z == 1*True

def spyBreports(W,X,Y,Z) :
 return W+X+Y == X+Y+Z == W+Y+Z == 1*True

ft = (False,True)

possibilities =  [(W,X,Y,Z) for W in ft for X in ft for Y in ft for Z in ft]

def testReport(report,name) :
 print name+"'s report",
 n=sum(report(*possibility) for possibility in possibilities)
 if n>0 :
 if n == len(possibilities) :
 print "must",
 else :
 print "may",
 else :
 print "can not",
 print "be true"

testReport(spyAreports,"Spy A")
testReport(spyBreports,"Spy B")
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Boris Borcic
Grant Edwards wrote:
> On 2006-05-02, Boris Borcic <[EMAIL PROTECTED]> wrote:
>> Grant Edwards wrote:
>>> Python knows how to count.  :)
>>>
>>> def countFalse(seq):
>>> return len([v for v in seq if not v])
>>>
>>> def countTrue(seq):
>>> return len([v for v in seq if v])
>>>
>>> def truth_test(seq):
>>> return countTrue(seq) == 1
>>>
>> I'd suggest the more direct
>>
>> def countFalse(seq) :
>>  return sum(1 for v in seq if not v)
> 
> I guess I don't see how that is more direct.
> 
> If you want to know how many items are in a seqneuce, you call
> len().  

sum doesn't construct a sequence

> 
> That's what it's for.
> 
> The number of objects in a list is returned in O(1) time by
> len(sequence). 

yeah, but you need to construst the list first, and that isn't O(1) neither in 
time or space.

> 
> Converting that list to a list of 1's

that's not what my suggestion is doing

and then summing the 1's
> is O(N).
> 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Roger Miller
Steve R. Hastings wrote:

> a = 0
> b = 0
> a is b  # always true

Is this guaranteed by the Python specification, or is it an artifact of
the current implementation? My understanding has been that an
implementation is free to share integer objects or not, so using 'is'
as an equality test takes you into undefined territory, regardless  of
the size of the value.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Grant Edwards
On 2006-05-02, Boris Borcic <[EMAIL PROTECTED]> wrote:
> Grant Edwards wrote:
>> Python knows how to count.  :)
>> 
>> def countFalse(seq):
>> return len([v for v in seq if not v])
>> 
>> def countTrue(seq):
>> return len([v for v in seq if v])
>> 
>> def truth_test(seq):
>> return countTrue(seq) == 1
>> 
>
> I'd suggest the more direct
>
> def countFalse(seq) :
>  return sum(1 for v in seq if not v)

I guess I don't see how that is more direct.

If you want to know how many items are in a seqneuce, you call
len().  

That's what it's for.

The number of objects in a list is returned in O(1) time by
len(sequence). 

Converting that list to a list of 1's and then summing the 1's
is O(N).

-- 
Grant Edwards   grante Yow!  Actually, what
  at   I'd like is a little toy
   visi.comspaceship!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Terry Reedy

"John Salerno" <[EMAIL PROTECTED]> wrote in message 
news:[EMAIL PROTECTED]
> I'm sure it's not necessary. Basically W, X, Y and Z are propositions
> that are either true or false, and the puzzle lists a few statements
> such as "Exactly one of X, Y and Z is true", and I'm trying to work out
> a little algorithm that might test for this kind of stuff.

X+Y+Z == 1 # or bool(X)... if not booleam

> Another thing I'm trying to do is write a function that tests to see if
> a list contains exactly one true item, and the rest are false (obviously
> this would have to be a list of boolean values, I guess). I'm sure this
> isn't a handy utility, but I enjoy figuring out how to implement it.

Use sum().  Being able to count true values by adding is a reason bool is a 
subclass of int.

Terry Jan Reedy



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Steve R. Hastings wrote:

> We could also use "generator expressions", available only in
> Python 2.4 and newer.
> 
> A list comprehension always builds a list.  A generator expression can
> return values one at a time.
> 
> [v for v in seq if v]  # builds a list and returns it
> (v for v in seq if v)  # returns a generator object

Woah, interesting. Somehow I don't think I knew that generators could 
exist outside of generator functions (using yield)! I was wondering why 
the second one above worked without brackets. :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Boris Borcic
Steve R. Hastings wrote:

> len([v for v in seq if v])  # builds a list, then feeds it to len()
> len(v for v in seq if v)  # gen obj feeds values to len one at a time

note that generators have no defined length - precisely because they feed 
values 
one at a time while you need them all together to speak of a length. The second 
expression will raise a TypeError because of that. If you want to count objects 
with a generator expression, use

sum(1 for v in seq if some_condition(v))

which is also clearer imho; summing ones for each item satisfying a condition - 
isn't that a definition of counting ?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Steve R. Hastings
On Tue, 02 May 2006 19:11:36 +, John Salerno wrote:

> Grant Edwards wrote:
> 
>> Python knows how to count.  :)
>> 
>> def countFalse(seq):
>> return len([v for v in seq if not v])
>> 
>> def countTrue(seq):
>> return len([v for v in seq if v])
>> 
>> def truth_test(seq):
>> return countTrue(seq) == 1
> 
> Gosh, so much to learn! Of course, I already know all about list 
> comprehensions, but now I just need to learn to *use* them! :)

Play around with them.  They are fun. :-)


We could also use "generator expressions", available only in
Python 2.4 and newer.

A list comprehension always builds a list.  A generator expression can
return values one at a time.

[v for v in seq if v]  # builds a list and returns it
(v for v in seq if v)  # returns a generator object

len([v for v in seq if v])  # builds a list, then feeds it to len()
len(v for v in seq if v)  # gen obj feeds values to len one at a time


The generator expression saves Python from having to build a list and then
destroy the list.  It's useful when you only care about the *values* and
you don't want to save the list.

For a short list, the savings are small; but for a really large list, a
generator expression can save a lot of wasted effort in building the new
list and destroying it.


Python 2.5 will be introducing two new functions, "all()" and "any()",
which are intended for use mostly with generator expressions:

any(v for v in seq if v)  # true if any v evaluates true
all(v for v in seq if v)  # true if *all* v evalute true


Or a better example:

any(is_green(x) for x in lst)  # true if any value in list is green

-- 
Steve R. Hastings"Vita est"
[EMAIL PROTECTED]http://www.blarg.net/~steveha

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Boris Borcic
Grant Edwards wrote:
> Python knows how to count.  :)
> 
> def countFalse(seq):
> return len([v for v in seq if not v])
> 
> def countTrue(seq):
> return len([v for v in seq if v])
> 
> def truth_test(seq):
> return countTrue(seq) == 1
> 

I'd suggest the more direct

def countFalse(seq) :
 return sum(1 for v in seq if not v)

def countTrue(seq) :
 return sum(1 for v in seq if v)

- not to speak of

def countFalse(seq) :
 return sum(not v for v in seq)

def countTrue(seq) :
 return sum(bool(v) for v in seq)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Grant Edwards
On 2006-05-02, John Salerno <[EMAIL PROTECTED]> wrote:

>> Python knows how to count.  :)
>> 
>> def countFalse(seq):
>> return len([v for v in seq if not v])
>> 
>> def countTrue(seq):
>> return len([v for v in seq if v])
>> 
>> def truth_test(seq):
>> return countTrue(seq) == 1
>
> Gosh, so much to learn! Of course, I already know all about list 
> comprehensions, but now I just need to learn to *use* them! :)

That's the part that takes a while...

-- 
Grant Edwards   grante Yow!  Is this "BOOZE"?
  at   
   visi.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Boris Borcic
Steve R. Hastings wrote:
> So, don't test to see if something is equal to True or False:
> 
> if 0 == False:
> pass  # never executed; False and 0 do not directly compare

of course they do - ie  isinstance(False,int) is True and False == 0

> 
> 
> You *could* do this, but I don't really recommend it:
> 
> if bool(0) == False:
> pass  # always executed
> 
> 
> Do this:
> 
> if not 0:
> pass  # always executed
> 
> if 1:
> pass  # always executed
> 
> 
> To convert a random value into a boolean value, you could use either
> "bool()" or you could use "not not":
> 
> a = not not 0
> b = bool(0)
> 
> 
> "not not" will work on older versions of Python that didn't have an
> explicit boolean type; "not 0" would return 1 in that case.  "bool()"
> will work in Python 2.2 and newer.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Grant Edwards wrote:

> Python knows how to count.  :)
> 
> def countFalse(seq):
> return len([v for v in seq if not v])
> 
> def countTrue(seq):
> return len([v for v in seq if v])
> 
> def truth_test(seq):
> return countTrue(seq) == 1

Gosh, so much to learn! Of course, I already know all about list 
comprehensions, but now I just need to learn to *use* them! :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Grant Edwards
On 2006-05-02, John Salerno <[EMAIL PROTECTED]> wrote:

> Yeah, after trying some crazy things, I just wrote it this way:
>
> def truth_test(seq):
>  truth = 0
>  for item in seq:
>  if item:
>  truth += 1
>  if truth == 1:
>  return True
>  else:
>  return False
>
> Not sure I like having to keep a counter though, but the other stuff I 
> did was really convoluted, like checking to see if the first item was 
> True, and if it was, popping it from the list and iterating over the 
> rest of the items (needless to say, the in-place change wasn't helpful).

Python knows how to count.  :)

def countFalse(seq):
return len([v for v in seq if not v])

def countTrue(seq):
return len([v for v in seq if v])

def truth_test(seq):
return countTrue(seq) == 1

-- 
Grant Edwards   grante Yow!  I FORGOT to do the
  at   DISHES!!
   visi.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Steve R. Hastings wrote:

> Anyway, the major point I want you to take away from all this: it doesn't
> matter whether the "is" test succeeds or fails, if all you care about is
> the *value* of a variable.  Python reuses object references to save
> memory, because this doesn't affect expressions that only care about the
> *value*.  Your logic tests only care about True vs. False; they don't care
> about the underlying implementation of how True and False are expressed.

Great explanation. Thanks!

> This is a simple problem.  I suggest you loop over the list and simply
> count how many values are false, and how many are true.  I just wrote and
> tested this function in about a minute.

Yeah, after trying some crazy things, I just wrote it this way:

def truth_test(seq):
 truth = 0
 for item in seq:
 if item:
 truth += 1
 if truth == 1:
 return True
 else:
 return False

Not sure I like having to keep a counter though, but the other stuff I 
did was really convoluted, like checking to see if the first item was 
True, and if it was, popping it from the list and iterating over the 
rest of the items (needless to say, the in-place change wasn't helpful).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Steve R. Hastings
On Tue, 02 May 2006 17:15:05 +, John Salerno wrote:
> Basically W, X, Y and Z are propositions 
> that are either true or false, and the puzzle lists a few statements 
> such as "Exactly one of X, Y and Z is true", and I'm trying to work out 
> a little algorithm that might test for this kind of stuff.

Okay.  You don't need to worry about the "is" tests at all.


Python always represents the value "True" with a reference to a True
object, and likewise "False" is a reference to a False object.  To save
memory, Python has just one of each object, so:

a = False
b = False
a is b  # this will always be true


As some other posters showed by example, but didn't really explain, Python
will *sometimes* but not always reuse integer objects.  For common integer
values such as 0 and 1, Python will reuse the objects; for uncommon
(larger) values, Python usually won't.  So:

a = 12345
b = 12345
a is b  # probably not true
a = 0
b = 0
a is b  # always true


A key point is that you never really "assign a value to a variable".  What
you really do is "bind an object reference to a name".  The long,
simultaneous assignment form binds the same object reference to multiple
variables:

a = b = c = d = 12345
a is b  # always true


But as soon as you reassign any of the variables you will rebind the name
to some other object reference:

a += 1
a is b  # definitely false
a = 12345
a is b  # probably false


Python *could* notice that it already has an integer object with the value
12345, and rebind the name a with a reference to it.  But in practice
Python will probably just create a new integer object with value 12345,
since the Python interpreter doesn't spend large amounts of time looking
through its collection of objects to find ones that can be reused.

Python also has exactly one "None" object, and always uses references to
it whenever you reference None in your code.  This is why it is preferred
Python style to test for None with an "is" test:

a is None


Anyway, the major point I want you to take away from all this: it doesn't
matter whether the "is" test succeeds or fails, if all you care about is
the *value* of a variable.  Python reuses object references to save
memory, because this doesn't affect expressions that only care about the
*value*.  Your logic tests only care about True vs. False; they don't care
about the underlying implementation of how True and False are expressed.


> Another thing I'm trying to do is write a function that tests to see if 
> a list contains exactly one true item, and the rest are false (obviously 
> this would have to be a list of boolean values, I guess). I'm sure this 
> isn't a handy utility, but I enjoy figuring out how to implement it.

This is a simple problem.  I suggest you loop over the list and simply
count how many values are false, and how many are true.  I just wrote and
tested this function in about a minute.

The list doesn't have to be a list of booleans, actually.  Python has a
set of rules for evaluating other values as booleans:

if 0:
pass  # never executed; 0 always false

if "":
pass  # never executed; 0-length string always false

if []:
pass  # never executed; 0-length list always false


So, don't test to see if something is equal to True or False:

if 0 == False:
pass  # never executed; False and 0 do not directly compare


You *could* do this, but I don't really recommend it:

if bool(0) == False:
pass  # always executed


Do this:

if not 0:
pass  # always executed

if 1:
pass  # always executed


To convert a random value into a boolean value, you could use either
"bool()" or you could use "not not":

a = not not 0
b = bool(0)


"not not" will work on older versions of Python that didn't have an
explicit boolean type; "not 0" would return 1 in that case.  "bool()"
will work in Python 2.2 and newer.
-- 
Steve R. Hastings"Vita est"
[EMAIL PROTECTED]http://www.blarg.net/~steveha

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
bruno at modulix wrote:

> Now if I may ask: what is your actual problem ?

Ok, since you're so curious. :)

Here's a scan of the page from the puzzle book:
http://johnjsalerno.com/spies.png

Basically I'm reading this book to give me little things to try out in 
Python. There's no guarantee that this puzzle is even conducive to (or 
worthy of) a programming solution.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread bruno at modulix
John Salerno wrote:
> Boris Borcic wrote:
> 
>>  >>> w ==  x
>> False
>>  >>> w is x
>> True
>>  >>>
> 
> 
> That's the opposite of what I want to happen.

And that wouldn't be really helpful anyway !-)

-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])"
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread bruno at modulix
John Salerno wrote:
> Is there a way to assign multiple variables to the same value,
> but so
> that an identity test still evaluates to False?

re-phrase it according to how Python works, and you'll get the answer:

"Is there a way to bind multiple names to the same object, but so the
identity of this object is different from the identity of this object ?"

> e.g.:
> 
 w = x = y = z = False

the statement:
  a = False
doesn't mean "assign the value False to the variable a", but "make the
name 'a' reference the object False" - which is quite different.

>>> a = False
>>> b = False
>>> a is b
True
>>> id(False)
46912499309888
>>> id(a)
46912499309888
>>> id(b)
46912499309888
>>>


 w
> False
 x
> False
 w == x
> True
 w is x
> True # not sure if this is harmful

Using identity test for boolean tests is usually not a good idea since
many other objects evals to True or False in a boolean context while not
being neither the True nor the False objects.

> The first line above is the only way I know to do it, but it seems to
> necessarily lead to the true identity test.

It does.

Now if I may ask: what is your actual problem ?

-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])"
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Diez B. Roggisch
> Hmm, classes still scare me a little, but I should consider this. The
> only thing is, it is not known in advance if the propositions are true
> or false, you have to figure that out yourself based on the combination
> of the statements given. I don't know if this changes the idea behind
> your Proposition class...I'll have to give it some more thought.

No, that was just an example to illustrate the comparison semantics. I don't
know enough about your problem to model it more appropriately.

Besides, you can of course change that self._v of a proposition.

Diez
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread David Isaac

"John Salerno" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> Is there a way to assign multiple variables to the same value, but so
> that an identity test still evaluates to False?

Make sure the value is not a singleton.
Assign them one at a time.
>>> w=1000
>>> x=1000
>>> w==x
True
>>> w is x
False
>>> w=2
>>> x=2
>>> w==x
True
>>> w is x
True

Hope that helps,
Alan Isaac


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Diez B. Roggisch wrote:

> Then use a Proposition-class that holds the actual value.
>  
>> Another thing I'm trying to do is write a function that tests to see if
>> a list contains exactly one true item, and the rest are false (obviously
>> this would have to be a list of boolean values, I guess).
> 
> No - you can for example override the comparison-semantics on the
> Proposition-class to be comparable with True/False with the proper
> semantics:

Hmm, classes still scare me a little, but I should consider this. The 
only thing is, it is not known in advance if the propositions are true 
or false, you have to figure that out yourself based on the combination 
of the statements given. I don't know if this changes the idea behind 
your Proposition class...I'll have to give it some more thought.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Diez B. Roggisch
John Salerno wrote:

> Diez B. Roggisch wrote:
> 
>> I can't imagine what you're actually after here, but assuming that you
>> really need this
> 
> Hard to explain because I'm still trying to figure out how to do it
> myself. I'm trying to solve a little puzzle using Python, even though
> I'm sure it's not necessary. Basically W, X, Y and Z are propositions
> that are either true or false, and the puzzle lists a few statements
> such as "Exactly one of X, Y and Z is true", and I'm trying to work out
> a little algorithm that might test for this kind of stuff.

Then use a Proposition-class that holds the actual value.
 
> Another thing I'm trying to do is write a function that tests to see if
> a list contains exactly one true item, and the rest are false (obviously
> this would have to be a list of boolean values, I guess).

No - you can for example override the comparison-semantics on the
Proposition-class to be comparable with True/False with the proper
semantics:




class Proposition(object):

def __init__(self, v):
self._v = v


def __eq__(self, o):
return self._v == o


TrueProposition = Proposition(True)
FalseProposition = Proposition(False)

print True == TrueProposition
print False == TrueProposition
print False == FalseProposition



Diez
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Diez B. Roggisch wrote:

> I can't imagine what you're actually after here, but assuming that you
> really need this

Hard to explain because I'm still trying to figure out how to do it 
myself. I'm trying to solve a little puzzle using Python, even though 
I'm sure it's not necessary. Basically W, X, Y and Z are propositions 
that are either true or false, and the puzzle lists a few statements 
such as "Exactly one of X, Y and Z is true", and I'm trying to work out 
a little algorithm that might test for this kind of stuff.

Another thing I'm trying to do is write a function that tests to see if 
a list contains exactly one true item, and the rest are false (obviously 
this would have to be a list of boolean values, I guess). I'm sure this 
isn't a handy utility, but I enjoy figuring out how to implement it.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread John Salerno
Boris Borcic wrote:

>  >>> w ==  x
> False
>  >>> w is x
> True
>  >>>

That's the opposite of what I want to happen.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Boris Borcic
John Salerno wrote:
> Is there a way to assign multiple variables to the same value, but so 
> that an identity test still evaluates to False?
> 
> e.g.:
> 
>  >>> w = x = y = z = False
>  >>> w
> False
>  >>> x
> False
>  >>> w == x
> True
>  >>> w is x
> True # not sure if this is harmful
> 
> The first line above is the only way I know to do it, but it seems to 
> necessarily lead to the true identity test.

 >>> class Foo :
def __eq__(*blah) : return False


 >>> w = x = y = z = Foo()
 >>> w ==  x
False
 >>> w is x
True
 >>>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: simultaneous assignment

2006-05-02 Thread Diez B. Roggisch
John Salerno wrote:

> Is there a way to assign multiple variables to the same value, but so
> that an identity test still evaluates to False?
> 
> e.g.:
> 
>  >>> w = x = y = z = False
>  >>> w
> False
>  >>> x
> False
>  >>> w == x
> True
>  >>> w is x
> True # not sure if this is harmful
> 
> The first line above is the only way I know to do it, but it seems to
> necessarily lead to the true identity test.

Yes, and there is no way around that - given that python has not an
overloadable assignment operator as e.g. C++ offers (praise the BDFL!). The
semantics of what looks like assignment in python is "I've got a fancy
object somewhere, and now I want to be able to refer to it by that nice
name here". Actually things are somewhat more complicated in case of
list/dictionary element assignment, but for your case that is irrelevant.

Besides, depending on what you assign (e.g. integers, as well as the boolean
constants I guess) you might not even have the choice to guarantee how the
identity test results anyway. Consider this:

>>> a = 100
>>> b = 100
>>> a is b
False
>>> a = 100
>>> b = 100
>>> a is b
False
>>> a = 10
>>> b = 10
>>> a is b
True
>>>

I can't imagine what you're actually after here, but assuming that you
really need this and that we're talking "real" objects here, sequence
unpacking and assignment might come handy here, together with a small
list-comp:

a, b, c = [copy.copy(o) for i in xrange(3)]


Diez
-- 
http://mail.python.org/mailman/listinfo/python-list


simultaneous assignment

2006-05-02 Thread John Salerno
Is there a way to assign multiple variables to the same value, but so 
that an identity test still evaluates to False?

e.g.:

 >>> w = x = y = z = False
 >>> w
False
 >>> x
False
 >>> w == x
True
 >>> w is x
True # not sure if this is harmful

The first line above is the only way I know to do it, but it seems to 
necessarily lead to the true identity test.
-- 
http://mail.python.org/mailman/listinfo/python-list