Home Accessing attributes of user defined object leads to "TypeError: object does not support indexing"
Reply: 2

Accessing attributes of user defined object leads to "TypeError: object does not support indexing"

fuji_doji
1#
fuji_doji Published in 2018-01-11 23:48:48Z

I have a class called LineString that consists of a list of Point objects. For example;

points = [Point(2,3), Point(7,8), Point(5,7)]

lin = LineString(points)

I want to write a function under LineString class that checks each point coordinate and returns (minimum_y, minimum_x, maximum_y, maximum_x).

Here is my Point class:

class Point(object):    
    def __init__(self, x, y):
        try:
            self.x = float(x)
            self.y = float(y)
        except ValueError as e:
            print(e)
            raise ValueError("x and y must be floating point numbers!")

And here is the LineString class

class LineString(points):
    def __init__(self, points):
        self.points = points

    def bounds(self):

        for point in points:
            x = point[0] 
            y = point[-1] 
            minx = min(x) 
            miny = min(y) 
            maxx = max(x) 
            maxy = max(x)    
            return (miny, minx, maxy, maxx)

I couldn't write the correct code to return the function minimum and maximum x,y values. When I run this, I get that:

x = point[0]
TypeError: 'Point' object does not support indexing"
cᴏʟᴅsᴘᴇᴇᴅ
2#
cᴏʟᴅsᴘᴇᴇᴅ Reply to 2018-01-12 00:28:01Z

The cause for your error is the fact that you are attempting to access coordinates using point[...] which does not work on objects of user defined classes which do not implement the __getitem__ magic method.

So, start by adding a __getitem__ method to your class.

class Point(object):
    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)

    def __getitem__(self, idx):
        try:
            return [self.x, self.y][idx]
        except IndexError:
            raise ValueError("Invalid Index") from None 

Note to readers - raise ... from None is supported from python3 onwards. For older versions, use raise ValueError("Invalid Index").

Now, your existing code should work.

>>> p = Point(1, 2)
>>> p[0]
1.0
>>> p[-1]
2.0
>>> p[2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in __getitem__
ValueError: Invalid Index

As an aside, you should seriously consider the use of namedtuples here.


Your LineString.bounds method is also flawed. My guess is you want to find the min/max across all points. If that's the case, you're supposed to first get all the coordinates, and call max/min outside the loop.

def bounds(self):
    X = [p[0] for p in points]
    y = [p[-1] for p in points]

    return min(y), min(X), max(y), max(X)
ahed87
3#
ahed87 Reply to 2018-01-12 00:12:13Z

You have not made the point class so that you can index into it. Either you fix that (see coldspeeds answer), or access the values as they are in the point class.

... 
for point in points:
    x = point.x 
    y = point.y 
    minx = min(x) 
    miny = min(y) 
    maxx = max(x) 
    maxy = max(x)    
    return (miny, minx, maxy, maxx)
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.32943 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO