user2909869
user2909869

Reputation: 125

Two objects in a method from a class?

I'm having a small issue with this code, I am currently learning about classes and trying to separate the two objects I have created to use both of them in a method from the class.

import math

class Segment:

    def __init__(self, xcoord = 0, ycoord = 0):
        self.x = xcoord
        self.y = ycoord

    def get(self):
        return (self.x, self.y)

    def setx(self, xcoord):
        self.x = xcoord

    def sety(self, ycoord):
        self.y = ycoord

    def length(self, xcoord, ycoord):
        return math.sqrt(math.pow(xcoord-ycoord,2)+(xcoord-ycoord,2))

p1 = Segment(3,4)
p2 = Segment()
p2.setx(5)
p2.sety(5)
s = Segment(p1,p2)
print(Segment.get(p1))
print(Segment.get(p2))
print(s.length())

I know that I am missing parameters in my length() method, or perhaps I have not? I would like to understand how I am able to have the objects interact with on another after I have defined them.

For further clarity, I am trying to print the distance between the two objects using the parameters I have assigned to them.

Upvotes: 0

Views: 2466

Answers (3)

Ewan
Ewan

Reputation: 15058

Lets walk through this:

  • p1 is an instance of the Segment class with attributes x=3, y=4.
  • p2 is an instance of the Segment class with attributes x=0, y=0,
  • When you set p2 to (5, 5) you could do it with p2 = Segment(5, 5),
  • s will have attributes x=p1 (an instance of Segment, not a coordinate) and y=p2 (another instance of Segment).

Calculating the length.

Your length method should look like this:

def length(self, xcoord, ycoord):
    return math.sqrt(math.pow(xcoord - self.x,2)+math.pow(ycoord - self.y,2))

This now uses the x and y coordinates of the class instance (in the example below, p1) and calculates the length between them, and the xcoord and ycoord parameters provided.

And you would call this with:

p2x, p2y = p2.get()
print(p1.length(p2x, p2y))

Upvotes: 1

roippi
roippi

Reputation: 25964

Okay, let's forget the code for a second. Firstly, let's talk about naming things. Your Segment class is not a class of segments - it's a class of points. So let's start by renaming your class Point.

class Point:
    def __init__(self, xcoord = 0, ycoord = 0):
        self.x = xcoord
        self.y = ycoord

Better already, no?

Now, imagine you're looking at someone else's code, trying to use that. Their Points have a length() method that you can call. What do you expect that to do? What could that... possibly do? A number of things, all because length is an awful descriptor for something that a Point is doing. It's certainly not a property of the Point - a point is 0-dimensional.

So let's rethink that function. There are two obvious ways to make this API - your Point class could have a distance_to(other_point) method, that would accept one argument - another Point. Optionally, you could have a module-level function segment_length(point1, point2) that would give you the length of the segment defined by the two Point objects.

So, the module-level function:

def segment_length(p1, p2):
   return math.sqrt((p2.x-p1.x)**2 + (p2.y-p1.y)**2)

I'll leave the Point method to you, should you wish to attempt it. It looks very similar, just using self in lieu of one of the points.

Upvotes: 3

Vikram Saran
Vikram Saran

Reputation: 1143

Firstly, you're missing a second math.pow() in your line:

return math.sqrt(math.pow(xcoord-ycoord,2)+(xcoord-ycoord,2))

Secondly with your call s = Segment(p1, p2) the x and y values of your Segment s are equal to the segments p1 and p2.

At the moment your values should read:

p1.get()
> (3, 4)
p2.get()
> (5, 5)

After the assignment of s you get:

s.get()
> ((3, 4), (5, 5))

This is problematic, because math.pow() has no idea what to do with a Segment object.

Upvotes: 0

Related Questions