Pierre-Alain Dorange wrote:
What is the elegant way to handle coordinates ?
Do i need to continue using tuples or do i need to write a Point class.
I feel a point class would be nice, because i could implement operators
with it ? But i think Point class must exist allready ?
My instinctive advice is to use a point class. My wise advice is to put
it in a library you will maintain and reuse--or else you will find
yourself re-writing point classes all of the time.
A Point class will also give you a place to consolidate all of those
methods specific to manipulating points. Thanks to python magic methods,
you can also design some nifty shortcuts to access the attributes of
your point.
Here is a fun example for no other reason than I'm too tired to do
anything important right now:
class Point(object):
def __init__(self, axes):
self.axes_names = axes.split()
self.axes = dict(enumerate(self.axes_names))
for axis in self.axes_names:
setattr(self, axis, 0.0)
def check_axis(self, i):
if i not in self.axes:
raise ValueError, "No such axis %s" % i
def __setitem__(self, i, v):
self.check_axis(i)
setattr(self, self.axes[i], v)
def __getitem__(self, i):
self.check_axis(i)
return getattr(self, self.axes[i])
def __iter__(self):
return (getattr(self, i) for i in self.axes_names)
def move(self, other):
for i, v in enumerate(other):
self[i] += v
def magnitude(self):
import math
return math.sqrt(sum(v**2 for v in self))
E.g.:
py> p = Point('x y z')
py> list(p)
[0.0, 0.0, 0.0]
py> p.move([2, 3, 4])
py> p.x, p.y, p.z
(2, 3, 4)
py> p[0], p[1], p[2]
(2, 3, 4)
py> list(p)
[2, 3, 4]
py> tuple(p)
(2, 3, 4)
py> p.magnitude()
5.3851648071345037
py> q = Point('x y z')
py> q.move([1, 2, 3])
py> p.move(q)
py> list(p)
[3.0, 5.0, 7.0]
py> p[1] = 15.0
py> list(p)
[3.0, 15.0, 7.0]
With the introduction of the second point, q, one can begin to see the
necessity for a class factory that produces Point classes of the desired
dimensionalities in desired coordinate systems:
def point(axes):
class P(Point):
def __init__(self, values):
Point.__init__(self, axes)
self.move(values)
return P
Note that we have have not used metaclasses--which would require messier
code but produce classes that would potentially behave a better as super
classes.
The point function is used as simply as it is written:
py> Point3D = point('x y z')
py> p = Point3D([0.0, 0.0, 0.0])
py> list(p)
[0.0, 0.0, 0.0]
py> q = Point3D([5.0, 6.0, 7.0])
py> list(q)
[5.0, 6.0, 7.0]
py> p.move(q)
py> list(p)
[5.0, 6.0, 7.0]
Incidentally, the classes returned by point are heritable, etc.
class Point3D(point('x y z')):
def __repr__(self):
return "Point3D(%s)" % list(self)
def __add__(self, other):
return Point3D(sum(t) for t in zip(self, other))
py> p = Point3D([8, 7, 6])
py> p
Point3D([8.0, 7.0, 6.0])
py> str(p)
'Point3D([8.0, 7.0, 6.0])'
py> q = Point3D([5, 4, 3])
py> r = p + q
py> r
Point3D([13.0, 11.0, 9.0])
Now have fun with this stuff. I need to go to sleep.
James
--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095
http://www.jamesstroud.com
--
http://mail.python.org/mailman/listinfo/python-list