Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple addition and subtraction for tuples of X and Y coordinates

Tags:

python

I have been studying Python for about 6 months now, and although I have a lot of factual knowledge, I still have very little experiential programming knowledge (in Python or otherwise). As a result, I'm concerned that 1. I am reinventing the wheel and 2. my attempts at solving my problem on my own are going to be fraught with issues I am not aware of.

Problem

The problem is simple. I have points composed of X and Y coordinates. I want to be able to simply add and subtract them together and test for equality:

a = Point(1,1)
b = Point(2,2)
assert a + a == b

An added difficulty is I have at least two different kinds of points, and I need to be able to convert between them and test for coordinate equality between them as well:

r = RegularPoint(1,1)
i = InterfacePoint(1,1)
ri = RegularPoint(i)
assert ri == i

These types of points are "exactly the same" animals, I just need to be able to differentiate between them.

Some more possibly relevant information: multiple object references to the points will be held in many containers, and there will only be tens of thousands of them at most.

Solution attempt

I have tried using collections.namedtuple:

from collections import namedtuple as nt
PointA = nt('PointA','x y')
PointB = nt('PointB','x y')

This is nice because testing for equality of the two different types of points is trivial, and "converting" works too:

a = PointA(1,1)
b = PointB(1,1)
assert a == b
aB = PointB(*a)
assert aB == a

But my test code will fail because adding tuples together behaves differently than the desired result:

assert a + a == (1, 1, 1, 1)

How can I get this working the way I want? I am not married to this approach at all, by the way, so tell me to throw it away completely if that's the best thing.

Other options I have considered

  • Independently implement the behavior by writing my Point classes, which doesn't seem too hard - but I feel like I'd be reinventing a wheel that has surely been created millions of times.
  • Use an abstract base class and just provide the requisite methods - perhaps numbers.Complex
  • use a numpy.matrix (or array) for the points
like image 831
Rick supports Monica Avatar asked Jan 05 '15 15:01

Rick supports Monica


1 Answers

Here's how to implement addition in a new class called Point:

class Point(namedtuple('Point', ['x', 'y'])):
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

You want a bit more than just a namedtuple, because you're doing more than just storing data. So I wrap that in a new class called Point. That new class needs to implement binary addition via +, which in Python is done by implementing a __add__ method.

Kevin's code on GitHub Gist could be useful if you want to see how to implement a more flexible Point class that can handle more than just 2 dimensions.

like image 142
ArtOfWarfare Avatar answered Oct 21 '22 11:10

ArtOfWarfare