Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Augmented Assignment question (http://www.velocityreviews.com/forums/t319778-augmented-assignment-question.html)

Doug Tolton 07-16-2003 06:13 PM

Augmented Assignment question
 
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

Adam Ruth 07-16-2003 07:25 PM

Re: Augmented Assignment question
 
In <215bhv0bnkn13eivh0s64ic5ml8obpgfg7@4ax.com> 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

Aahz 07-16-2003 08:51 PM

Re: Augmented Assignment question
 
In article <215bhv0bnkn13eivh0s64ic5ml8obpgfg7@4ax.com>,
Doug Tolton <dtolton@yahoo.com> 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 (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/

A: No.
Q: Is top-posting okay?

Steven Taschuk 07-17-2003 02:01 AM

Re: Augmented Assignment question
 
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 staschuk@telusplanet.net
"Please don't damage the horticulturalist."
-- _Little Shop of Horrors_ (1960)


Tim Lesher 07-17-2003 02:17 AM

Re: Augmented Assignment question
 
Doug Tolton <dtolton@yahoo.com> wrote in message news:<215bhv0bnkn13eivh0s64ic5ml8obpgfg7@4ax.com>. ..
> 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())

Bengt Richter 07-17-2003 05:38 AM

Re: Augmented Assignment question
 
On Wed, 16 Jul 2003 22:17:40 GMT, Doug Tolton <dtolton@yahoo.com> wrote:

>On 16 Jul 2003 16:51:38 -0400, aahz@pythoncraft.com (Aahz) wrote:
>
>>In article <215bhv0bnkn13eivh0s64ic5ml8obpgfg7@4ax.com>,
>>Doug Tolton <dtolton@yahoo.com> 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

John Machin 07-19-2003 12:52 AM

Re: Augmented Assignment question
 
Doug Tolton <dtolton@yahoo.com> wrote in message news:<215bhv0bnkn13eivh0s64ic5ml8obpgfg7@4ax.com>. ..
> 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
>



All times are GMT. The time now is 10:32 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57