Making MyClass sum()-able sequence

This is the place for queries that don't fit in any of the other categories.

Making MyClass sum()-able sequence

Postby hrs » Fri Sep 20, 2013 1:17 pm

The code below implements a class that works with the sum() function but only if wrapped in a list first. Without [] Python will complain that it's a non-sequence. What needs to be done so I don't have to wrap it in a list? I'm guessing I need to implement __iter__ but I don't know what it should look like.

Code: Select all
class Vec2d():
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vec2d(x, y)

    def __radd__(self, other):
        return self.x + self.y + other

v1 = Vec2d(1, 2)
v2 = Vec2d(4, 5)

v3 = v1 + v2

print v3.x, v3.y
print sum([v3])

Output:
5 7
12
hrs
 
Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm

Re: Making MyClass sum()-able sequence

Postby hrs » Fri Sep 20, 2013 1:32 pm

Oh, I was doing something dumb. I got it to work with
Code: Select all
    def __init__(self, x, y):
    ...
        self.members = [x, y]

    def __iter__(self):
        for m in self.members:
            yield m


But if this is not the right way I'd love to know.
hrs
 
Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm

Re: Making MyClass sum()-able sequence

Postby micseydel » Fri Sep 20, 2013 5:38 pm

sum() accepts as an argument an iterable object. Your class (a vector?) doesn't look like it is an object which should be iterable. More likely, you should have a well-named method that does the operation you want. I'm not sure what adding the components of a vector is supposed to be for.
Join the #python-forum IRC channel on irc.freenode.net!
User avatar
micseydel
 
Posts: 1128
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: Making MyClass sum()-able sequence

Postby hrs » Fri Sep 20, 2013 7:28 pm

Yes, it's a vector. Actually it's a 3d vector, the above was simplified. The sum of all components allows me to write this
Code: Select all
def get_sample(origin, screen, sphere):
    ''' calculate vector sphere intersection '''
    x1 = origin.x
    y1 = origin.y
    z1 = origin.z

    x3 = sphere.x
    y3 = sphere.y
    z3 = sphere.z
    r3 = sphere.r

    for sample in screen.nextSample():
        a = (x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2
        b = 2 * ((x2 - x1) * (x1 - x3) + (y2 -y1) * (y1 - y3) + (z2 - z1) * (z1 - z3))
        c = x3**2 + y3**2 + z3**2 + x1**2 + y1**2 + z1**2 - 2 * (x3 * x1 + y3 * y1 * z3 * z1) - r3**2
        # do things with a, b and c


as this
Code: Select all
def get_sample(origin, screen, sphere):
    ''' calculate vector sphere intersection '''
    ozo = Vec3d(1, 0, 1)

    for sample in screen.nextSample():
        a = sum((sample - origin)**2)
        b = sum(-origin ** 2) + sum(origin * sample)
                              + sum(origin * sphere) + sum(-sample * sphere)
        c = sum(origin ** 2) + sum(sphere ** 2) - 2 * sum( ozo * origin * sphere) - sphere.r ** 2
        # do things with a, b and c

The result might not be correct (yet) as the code isn't working yet. But you are probably right that I should just define a method for this.

But apart from that, I also see examples (for making a class an iterable) that implement __iter__(), next() and something with StopIteration (can't find the link anymore :/ ). Assuming there's a legitemate case for making a class iterable, would this (__iter__(), next() and something with StopIteration) be better than using yield?

Edit: Hmm, it's a bit of a mess as I'm editing the code atm. The first code block is obviously missing the sample.x, sample.y and sample.z that should be there.
hrs
 
Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 1 guest