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!

Please do not PM members regarding questions which are meant to be discussed publicly. The point of the forum is so that others can benefit from it. We don't want to help you over PMs or emails.
User avatar
micseydel
 
Posts: 1222
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 3 guests