Is there a more elegant way to do this?

K

Kamilche

'''
Is there a more elegant way of doing this?
I would like to have the arguments to pack
automatically taken from lst.
'''

def pack(self):
lst = ['id', 'parent', 'number', 'x', 'y', 'z', 'red', \
'green', 'blue', 'size', 'rotate', 'translucency']
return struct.pack('<IIIiiiBBBHHH', \
self.id, self.parent, self.number, \
self.x, self.y, self.z, \
self.red, self.green, self.blue, \
self.size, self.rotate, self.translucency)
 
J

Jeff Epler

something like this:
def pack(self):
lst = ['id', 'parent', 'number', 'x', 'y', 'z', 'red', \
'green', 'blue', 'size', 'rotate', 'translucency']
values = [getattr(self, attr) for attr in lst]
return struct.pack('<IIIiiiBBBHHH', *values)

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFA3fVyJd01MZaTXX0RAlgYAJ0UCE8OTGA4AqL/B0PxAzulzaWFgwCgppRS
BxN53Hjck5yxly91Eme1+4w=
=ea/I
-----END PGP SIGNATURE-----
 
P

Peter Otten

Kamilche said:
'''
Is there a more elegant way of doing this?
I would like to have the arguments to pack
automatically taken from lst.
'''

def pack(self):
lst = ['id', 'parent', 'number', 'x', 'y', 'z', 'red', \
'green', 'blue', 'size', 'rotate', 'translucency']
return struct.pack('<IIIiiiBBBHHH', \
self.id, self.parent, self.number, \
self.x, self.y, self.z, \
self.red, self.green, self.blue, \
self.size, self.rotate, self.translucency)

There is an alternative

struct.pack("<IIIiiiBBBHHH", *[getattr(self, name) for name in lst])

and you could even add the typecodes

lst = [("I", 'id'), ("I", 'parent'), ... ]
struct.pack("<" + "".join([t for (t, n) in lst]),
*[getattr(self, n) for (t, n) in lst])


but frankly, I prefer your original version.

Peter
 
S

Shalabh Chaturvedi

Kamilche said:
'''
Is there a more elegant way of doing this?
I would like to have the arguments to pack
automatically taken from lst.
'''

def pack(self):
lst = ['id', 'parent', 'number', 'x', 'y', 'z', 'red', \
'green', 'blue', 'size', 'rotate', 'translucency']
return struct.pack('<IIIiiiBBBHHH', \
self.id, self.parent, self.number, \
self.x, self.y, self.z, \
self.red, self.green, self.blue, \
self.size, self.rotate, self.translucency)

Note that you don't have to use backslashes when you're inside any kind
of brackets. Makes it look a little cleaner.
 
K

Kamilche

Peter Otten said:
struct.pack("<IIIiiiBBBHHH", *[getattr(self, name) for name in lst])


Thanks Peter! I knew there must be a way, but I don't comprehend list
comprehensions yet.

And I didn't know about the 'don't need backslashes when in a
bracket', thanks Shalabh.

:)
 
P

Peter Hansen

Kamilche said:
Is there a more elegant way of doing this?
I would like to have the arguments to pack
automatically taken from lst.

def pack(self):
lst = ['id', 'parent', 'number', 'x', 'y', 'z', 'red', \
'green', 'blue', 'size', 'rotate', 'translucency']
return struct.pack('<IIIiiiBBBHHH', \
self.id, self.parent, self.number, \
self.x, self.y, self.z, \
self.red, self.green, self.blue, \
self.size, self.rotate, self.translucency)

The following is perhaps the most easily maintainable
of the responses *if* you expect things to change at
all. If the whole thing is very stable, the explicit
approach, as Peter Otten says, might be preferred.

def pack(self):
args = ('Iid Iparent Inumber ix iy iz Bred Bgreen Bblue '
'Hsize Hrotate Htranslucency')
lst = zip(*[(x[0],x[1:]) for x in s.split()])
return struct.pack('<' + ''.join(lst[0]),
*[getattr(self, n) for n in lst[1]])

It's also easily the most inscrutable of the responses... but
if you have to do this sort of thing in various places in your
code, it makes a nice utility function.

-Peter
 
K

Kamilche

Peter Hansen said:
def pack(self):
args = ('Iid Iparent Inumber ix iy iz Bred Bgreen Bblue '
'Hsize Hrotate Htranslucency')
lst = zip(*[(x[0],x[1:]) for x in s.split()])
return struct.pack('<' + ''.join(lst[0]),
*[getattr(self, n) for n in lst[1]])

You scary c-like-code-creator, you. :-O
 
P

Peter Hansen

Kamilche said:
def pack(self):
args = ('Iid Iparent Inumber ix iy iz Bred Bgreen Bblue '
'Hsize Hrotate Htranslucency')
lst = zip(*[(x[0],x[1:]) for x in s.split()])
return struct.pack('<' + ''.join(lst[0]),
*[getattr(self, n) for n in lst[1]])


You scary c-like-code-creator, you. :-O

More like Perl, I think, which packs all the unreadability of C
into one tenth the space.

Actually, I thought someone would comment on the emergent
Hungarianesque notation in the above... I think if I
were doing this for real (and I might well if I had the
need), I'd use a decent separator to make the args string
more readable, maybe just 'I-id I-parent I-robot...' or
something. That makes the (x[0], x[1:]) turn into the
somewhat cleaner x.split('-').

Another actually: zip I find just plain incomprehensible,
but it sure comes in handy from time to time. I can't
seem to fit it in my brain though, and constantly resort
to the interactive prompt to figure out how to use it.
Bummer....

-Peter
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top