0

So for a line class I'm doing, I keep getting an error that says

AttributeError: Line instance has no attribute 'point0'

I'm declaring the line like this:

def __init__(self, point0, point1):
    self.x = point0
    self.y = point1

def __str__(self):
    return '%d %d' % (int(round(self.point0)), int(round(self.point1)))

And I get the x and y from my point class which should already be float values so I don't need to check for an error in my init method however I do check to see if point0 and point1 are floats in my rotate method:

def rotate(self, a):
        if not isinstance(a, float) or not isinstance(self.point0, float) or not isinstance(self.point1, float):
            raise Error("Parameter \"a\" illegal.")
        self.point0 = math.cos(a) * self.point0 - math.sin(a) * self.point1
        self.point1 = math.sin(a) * self.point0 + math.cos(a) * self.point1

So why does python keep saying that it has no attribute point0? I also tried changing my init method to look like this:

def __init__(self, point0, point1):
    self.point0 = point0
    self.point1 = point1

But when I do that the error says point0 has no attribute float. So why do I keep getting this error? Here's the code I'm using to test:

p0 = Point(0.0, 1.0)
p1 = Point(2.0, 3.0)
line = Line(p0,p1)
print line
3
  • It would be esier if you can provide the whole code you have already written. Thus its easier for debugging. Commented Mar 8, 2016 at 20:56
  • Alright I updated it to show my entire code. Commented Mar 8, 2016 at 20:59
  • Don't bother checking the types of all your arguments. Python's philosophy is that we're all responsible enough to read the documentation and pass arguments of the correct type. isinstance is used primarily to modify behavior depending on whether an argument is, say, a string or a tuple (cf str.endswith), not to raise errors if a value isn't the right type. Commented Mar 8, 2016 at 22:05

4 Answers 4

1

I'm curious... how much do you know about scope in Python?

In your class, you have a member variable named x and another named y. Your init function accepts an argument called point0 and another called point1. It saves point0 in the x member variable, and point1 in y. Then, in your rotate function, you attempt to access a variable called point0. Do you see the problem?

An important thing to understand when programming (and this is true in most programming languages, if not all of them) is that the name of an argument doesn't affect the name of that data elsewhere. I can pass a variable called foo into a function that takes an argument called bar. In that function, I have to refer to the data as bar because that's the name of the variable. Later, after I've called that function, the name of the variable is still foo, because only the variable inside the function is called bar. Does that make sense?

Sign up to request clarification or add additional context in comments.

4 Comments

I just don't know what self does in python because I never saw it in any other programming languages.
Its basically a handle to your instance of the class you are using it in. Like in c# this.
I still have no idea what to do. If I change my point0 back to x I get another error that says "AttributeError: Point instance has no attribute 'float'" and I have no idea how to fix that.
Most OOP languages that I've seen use 'this', as sens4 mentioned above. Python has 'self. If you're used to programming in C++ or Java or other languages like those, you're probably used to seeing the type of the variable when you're passing it. In Python, you can't. Functions don't accept an int or a str; they just accept variables. Where are you seeing this error? What line? Are you sure that the variable that you're passing to it it a Point variable?
1

your class accept point0 and point1 parameters when you call it. If you want to get values of these parameters you should use self.x(for point0) and self.y(for point1) or another way;

class Line:
   def __init__(self, point0, point1):
       self.point0 = point0
       self.point1 = point1

I suggest you to read;

Python __init__ and self what do they do?

https://www.ibiblio.org/swaroopch/byteofpython/read/class-init.html

https://docs.python.org/2/tutorial/classes.html

9 Comments

I did do that but for my str method it keeps saying "AttributeError: Point instance has no attribute 'float'" and I have no idea why it keeps saying that.
can you share the full traceback?
It was for the str method in my line class. The str method in my point class works fine but for the str in my line class it says return '%d %d' % (int(round(self.point0)), int(round(self.point1))) AttributeError: Point instance has no attribute 'float'
it is not the reason. Here I tried ; In [7]: line = Line(3.2, 4.1) In [8]: line.__str__() Out[8]: '3 4'
I just added my test code. What it does is take a p0 and p1. p0 = Point(0.0, 1.0) and p1 = Point(2.0, 3.0) and then there's line = Line(p0,p1) and this generates the error about not being able to find a float value. While the error points to the str method, the problem could be in another method.
|
0

A few overall points before displaying your corrected code. (Note that not much actually changed):

  1. Don't bother checking argument types. Python programmers are assumed to be responsible enough to read the documentation and pass values of the correct value.

  2. Your Line class was duplicating code that you had already defined in the Point class. The attributes of a line are Point instances, so you can use the methods you defined to implement the Line methods.

  3. There's no reason to round the point coordinates to integers when displaying them; show the actual floating-point values that define the point. Your Line.__str__ method can take advantage of the fact that you've defined Point.__str__.

And now, your much shorter and corrected code, with some interspersed comments.

import math


class Point:
    def __init__(self, x, y):
        '''x and y should be floats'''
        self.x = x
        self.y = y

    def rotate(self, a):
        '''Rotate the point around the origin by a radians'''
        self.x = math.cos(a) * self.x - math.sin(a) * self.y
        self.y = math.sin(a) * self.x + math.cos(a) * self.y
        # If you *were* going to check if a is a float, you
        # need to do it *before* you use it.

    def scale(self, f):
        '''Scale the point by f units'''  # you get the idea
        self.x = f * self.x
        self.y = f * self.y

    def translate(self, delta_x, delta_y):
        self.x = self.x + delta_x
        self.y = self.y + delta_y

    def __str__(self):
        # If you're storing floats, it's probably useful
        # to output them.
        return '(%f, %f)' % (self.x, self.y)


# Operations on a line all involve applying the same operations
# to each of its end points.
class Line:
    def __init__(self, point0, point1):
        self.point0 = point0
        self.point1 = point1

    def rotate(self, a):
        self.point0.rotate(a)
        self.point1.rotate(a)

    def scale(self, factor):
        self.point0.scale(factor)
        self.point1.scale(factor)
        # If for whatever reason you didn't want to use Point.scale
        # here, the code would be...
        # self.point0.x = f * self.point0.x
        # self.point0.y = f * self.point0.y
        # self.point1.x = f * self.point0.x
        # self.point1.y = f * self.point0.y

    def translate(self, delta_x, delta_y):
        self.point0.translate(delta_x, delta_y)
        self.point1.translate(delta_x, delta_y)

    def __str__(self):
        # You've already defined out to turn a Point into
        # a string, so you can take advantage of that here.
        return "%s -- %s" % (self.point0, self.point1)

4 Comments

Your code almost gets me the correct output however there's one more test case where I test for a shallow copy. p0.scale(2.0) p1.scale(2.0) print line. What I expect it to print out is 0 1 2 3 but it instead prints out 0 2 4 6. Why is that?
This question is already too broad; your comment is a new question altogether.
But I feel like it's a simple answer. It appears to be calling scale but I don't which one and I don't know why the values are multiples of 2 instead of 1.
It might be a simple answer, but the comment section is not the appropriate place to raise new question. Besides, there's not enough room in the comment to fully explain what the problem is. You say print line, but never explain how you set line. (And do not follow this comment with something like line = Line(p0, p1); I'm not answering the question here.)
0

I'm going to add another answer here, both because I lack the reputation to comment on the other answer and because I feel this answer is unrelated to my previous answer (which addressed a different problem than what you're seeing now).

So. That said, look at this line of code:

return '%d %d' % (int(round(self.point0)), int(round(self.point1)))

round is a function that takes a numeric argument. However, self.point0 and self.point1 are not numbers. They are points. If you want the numbers from them, you'll have to refer to those explicitly (i.e. self.point0.x).

5 Comments

So are you saying that everytime I use self.point0 or self.point1 I have to instead say self.point0.x and self.point1.y?
So I changed all the point0 and 1's to point0.x and point1.y and that gets rid of the errors but the output isn't right. For example with rotate it returns the values 0 -1 but it should've returned 0 0 0 -1
No. Your line variable has 2 points (point0 and point1). Every point has 2 values (x and y). You have 4 total values that you need to print, and you're only printing 2 of them.
But how to I print out both values from point0 and 1? I'm using self.point0.x but I can't figure out how to add y in there.
I tried self.point0.x and self.point1.x and then the same with the y's but that doesn't work either. How can I make point0 and 1 point to all the values? I'm very confused about how this works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.