Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Augmented Assignment question

Reply
Thread Tools

Augmented Assignment question

 
 
Doug Tolton
Guest
Posts: n/a
 
      07-16-2003
I have a function that returns a tuple:

def checkdoc(self, document):
blen = document['length']
bates = document['obates']

normal, truncated, semicolon = 0,0,0
for bat in bates:
if len(bat) == 2 * blen:
semicolon += 1
if len(bat) == blen - 1:
truncated += 1
if len(bat) == blen:
normal += 1

return normal, truncated, semicolon

on the other side I have 3 variables:
normal, truncated and semicolon

I would like to be able to do an augmented assignment such as:

normal, truncated, semicol += self.checkdoc(mydoc)

however this returns the following error:
SyntaxError: augmented assign to tuple not possible

I did some reading and it seems that an augmented assignment is
specifically verboten on tuples and lists. Is there a clean way to
accomplish this? I dislike in the extreme what I've resorted to:

fnormal, ftruncated, fsemicolon = 0,0,0

// loop through a file and process all documents:
normal, truncated, semicolon = self.checkdoc(curdoc)
fnormal += normal
ftruncated += truncated
fsemicolon += semicolon

This solution strikes me as inelegant and ugly. Is there a cleaner
way of accomplishing this?

Thanks in advance,
Doug Tolton
dougt at<remove this>case<remove this too>data dot com
 
Reply With Quote
 
 
 
 
Adam Ruth
Guest
Posts: n/a
 
      07-16-2003
In <(E-Mail Removed)> Doug Tolton wrote:
> I have a function that returns a tuple:
>
> def checkdoc(self, document):
> blen = document['length']
> bates = document['obates']
>
> normal, truncated, semicolon = 0,0,0
> for bat in bates:
> if len(bat) == 2 * blen:
> semicolon += 1
> if len(bat) == blen - 1:
> truncated += 1
> if len(bat) == blen:
> normal += 1
>
> return normal, truncated, semicolon
>
> on the other side I have 3 variables:
> normal, truncated and semicolon
>
> I would like to be able to do an augmented assignment such as:
>
> normal, truncated, semicol += self.checkdoc(mydoc)
>
> however this returns the following error:
> SyntaxError: augmented assign to tuple not possible
>
> I did some reading and it seems that an augmented assignment is
> specifically verboten on tuples and lists. Is there a clean way to
> accomplish this? I dislike in the extreme what I've resorted to:
>
> fnormal, ftruncated, fsemicolon = 0,0,0
>
> // loop through a file and process all documents:
> normal, truncated, semicolon = self.checkdoc(curdoc)
> fnormal += normal
> ftruncated += truncated
> fsemicolon += semicolon
>
> This solution strikes me as inelegant and ugly. Is there a cleaner
> way of accomplishing this?
>
> Thanks in advance,
> Doug Tolton
> dougt at<remove this>case<remove this too>data dot com
>


I don't think it's all that inelegant, and it's definitely clear. I can
see, though, why a one liner would seem a little cleaner.

Off the top of my head, I'd say to change your checkdoc function to this:

> def checkdoc(self, document, normal=0, truncated=0, semicolon=0):
> blen = document['length']
> bates = document['obates']
> for bat in bates:
> if len(bat) == 2 * blen:
> semicolon += 1
> if len(bat) == blen - 1:
> truncated += 1
> if len(bat) == blen:
> normal += 1
>
> return normal, truncated, semicolon


And then call it like this:

> normal, truncated, semicolon = self.checkdoc(curdoc, normal,
> truncated, semicolon)


As a side note, I wouldn't have thought that the augmented assign would
work the way you tried to use it. I would have thought that it would be
analagous to the + operator and sequences:

> x = [1,2,3]
> y = [1,2,3]
> x + y

[1,2,3,1,2,3]

So that the agumented form would be:

> x = [1,2,3]
> x += [1,2,3]

[1,2,3,1,2,3]

But I've never tried it before and didn't know that it didn't work with
sequences. You learn something new every day.

Adam Ruth
 
Reply With Quote
 
 
 
 
Aahz
Guest
Posts: n/a
 
      07-16-2003
In article <(E-Mail Removed)>,
Doug Tolton <(E-Mail Removed)> wrote:
>
>I did some reading and it seems that an augmented assignment is
>specifically verboten on tuples and lists. Is there a clean way to
>accomplish this?


Really?

>>> l = []
>>> l+=[1]
>>> l

[1]
>>> l+=['foo']
>>> l

[1, 'foo']
--
Aahz ((E-Mail Removed)) <*> http://www.pythoncraft.com/

A: No.
Q: Is top-posting okay?
 
Reply With Quote
 
Steven Taschuk
Guest
Posts: n/a
 
      07-17-2003
Quoth Doug Tolton:
[...]
> fnormal, ftruncated, fsemicolon = 0,0,0
>
> // loop through a file and process all documents:
> normal, truncated, semicolon = self.checkdoc(curdoc)
> fnormal += normal
> ftruncated += truncated
> fsemicolon += semicolon
>
> This solution strikes me as inelegant and ugly. Is there a cleaner
> way of accomplishing this?


It seems possible that your normal, truncated and semicolon
variables should be bundled into a single object:

class DocumentStatistics(object):
# ...
def __iadd__(self, (deltanormal, deltatruncated, deltasemicolon)):
self.normal += deltanormal
self.truncated += deltatruncated
self.semicolon += deltasemicolon

Then you can just do
docstats = DocumentStatistics()
# ...
docstats += self.checkdoc(curdoc)
If these variables usually change in synch, this seems a natural
way to organize them.

You might also want to look into Numeric's arrays.

(And there's always

normal, truncated, semicolon = map(operator.add,
(normal, truncated, semicolon),
self.checkdoc(curdoc))

which I consider inferior to your straightforward approach with
three augmented assignments.)

--
Steven Taschuk http://www.velocityreviews.com/forums/(E-Mail Removed)
"Please don't damage the horticulturalist."
-- _Little Shop of Horrors_ (1960)

 
Reply With Quote
 
Tim Lesher
Guest
Posts: n/a
 
      07-17-2003
Doug Tolton <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> This solution strikes me as inelegant and ugly. Is there a cleaner
> way of accomplishing this?


The problem is this: performing addition of tuples is concatenation,
not addition of the elements. If you try to decompose the augmented
addition into an addition and an assignment, you get a tuple that is
(in your case) the concatenation of the two 3-tuples, or a 6-tuple,
which can't unpack into a 3-tuple.

That said, for some definition of "cleaner", you could do:
def accumulate(i,j):
return map(int.__add__, i, j)

// loop
i,j,k = accumulate((i,j,k), fn())
 
Reply With Quote
 
Bengt Richter
Guest
Posts: n/a
 
      07-17-2003
On Wed, 16 Jul 2003 22:17:40 GMT, Doug Tolton <(E-Mail Removed)> wrote:

>On 16 Jul 2003 16:51:38 -0400, (E-Mail Removed) (Aahz) wrote:
>
>>In article <(E-Mail Removed)>,
>>Doug Tolton <(E-Mail Removed)> wrote:
>>>
>>>I did some reading and it seems that an augmented assignment is
>>>specifically verboten on tuples and lists. Is there a clean way to
>>>accomplish this?

>>
>>Really?
>>
>>>>> l = []
>>>>> l+=[1]
>>>>> l

>>[1]
>>>>> l+=['foo']
>>>>> l

>>[1, 'foo']

>
>
>I mis-spoke, lists are not included. You cannot do augmented
>assignments on tuples or multiple targets.
>
>you can do what you typed, but you can't do.
>
>>>> a,b = 0,0
>>>> a,b += 1,1

>SyntaxError: augmented assign to tuple not possible
>
>or this:
>
>>>> a,b = [],[]
>>>> a,b += [1],[1]

>SyntaxError: augmented assign to tuple not possible
>
>That is specifically the point I was getting at. Forgive the
>technical slip of including lists in the discussion.
>

A little experiment (not tested beyond what you see :

>>> class TX(tuple):

... def __add__(self, other):
... return TX([s+o for s,o in zip(self, other)])
...
>>> tx = TX((2,2))
>>> tx

(2, 2)
>>> tx + (3,5)

(5, 7)
>>> tx

(2, 2)
>>> tx += (3,5)
>>> tx

(5, 7)
>>> tx += 10,20
>>> tx

(15, 27)
>>> tt = TX(('ab','cd','ef'))
>>> tt

('ab', 'cd', 'ef')
>>> tt += '123'
>>> tt

('ab1', 'cd2', 'ef3')


Regards,
Bengt Richter
 
Reply With Quote
 
John Machin
Guest
Posts: n/a
 
      07-19-2003
Doug Tolton <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> I have a function that returns a tuple:
>
> def checkdoc(self, document):
> blen = document['length']
> bates = document['obates']
>
> normal, truncated, semicolon = 0,0,0
> for bat in bates:
> if len(bat) == 2 * blen:
> semicolon += 1
> if len(bat) == blen - 1:
> truncated += 1
> if len(bat) == blen:
> normal += 1


self.total_normal += normal
# etc etc
# someone else suggested a separate class just for statistics
# --- this is overkill IMHO
>
> return normal, truncated, semicolon
>

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Nested scopes, and augmented assignment Tim N. van der Leeuw Python 39 07-10-2006 03:05 PM
Re: [Python-Dev] The baby and the bathwater (Re: Scoping,augmented assignment, 'fast locals' - conclusion) Josiah Carlson Python 4 06-19-2006 01:34 PM
Augmented assignment Suresh Jeevanandam Python 8 02-21-2006 07:20 PM
User-defined augmented assignment Pierre Barbier de Reuille Python 4 10-01-2005 11:58 PM
RE: Augmented Assignment question Delaney, Timothy C (Timothy) Python 0 07-17-2003 12:25 AM



Advertisments