Python language-center of a circle using OOP

前端 未结 3 1627
悲哀的现实
悲哀的现实 2021-01-28 07:33
class Point:

    def __init__(self, initX, initY):
        \"\"\" Create a new point at the given coordinates. \"\"\"
        self.x = initX
        self.y = initY

            


        
相关标签:
3条回答
  • 2021-01-28 08:03

    You don't need getters or setters in python nor is it pythonic to use them, you should access the attributes directly:

    def cencd(p1, p2, p3):
        """calculating the center of a circle"""
        ma = (p2.y - p1.y) / (p2.x - p1.x)
        mb = (p3.y - p2.y) / (p3.x - p2.x)
        hw = p1.halfway(p2)
        x = (ma * mb * (p1.y - p3.y) + mb * (p1.x + p2.x) - ma * (p2.x + p3.x)) / 2 * (mb - ma)
        ya = -(1 / ma) * ((x - hw.x) + hw.y)
        return x, ya
    
    0 讨论(0)
  • 2021-01-28 08:09

    As Padraic Cunningham said, we don't need getters or setters in Python, but as mu said we can make getters if we want, but normally they are used to get "fake" attributes that are actually computed from true attributes. For example, in the code below I've added a fake norm attribute to your Point class.

    I've also added a few more double-underscore methods (aka dunder methods or magic methods) to your class. These methods are discussed in the official Python docs.

    One of the most common dunder methods is __repr__() which should return a string that corresponds to how you create an instance of the class. This is especially handy when you're using a class in the interactive interpreter. FWIW, if a class doesn't define a __str__() method its __repr__() method will be used if you attempt to turn a class instance into a string. If a __repr__() method hasn't been defined a default one will be used.

    The other dunder methods I've added make it easier to perform arithmetic operations on points; this can make code easier to write and to read. I think you'll agree that it makes the cencd() function a little clearer. (I'm not sure exactly what that function's supposed to do; I assume you've got the algebra correct :) ).

    This code was tested on Python 2.6.6; it should run ok on Python 3 without modification.

    #!/usr/bin/env python
    
    ''' Point class demo
    
        From http://stackoverflow.com/q/28602056/4014959
    
        Written by koseph, Padraic Cunningham, and PM 2Ring
        2015.02.19
    '''
    
    from __future__ import print_function
    from __future__ import division
    
    class Point(object):
        def __init__(self, initX, initY):
            """ Create a new point at the given coordinates. """
            self.x, self.y = initX, initY
    
        @property
        def norm(self):
            return self.x ** 2 + self.y ** 2
    
        def distance_from_origin(self):
            return self.norm ** 0.5
    
        def __repr__(self):
            return 'Point({self.x}, {self.y})'.format(self=self)
    
        def __str__(self):
            return 'x={self.x}, y={self.y}'.format(self=self)
    
        def __add__(self, other):
            return Point(self.x + other.x, self.y + other.y)
    
        def __mul__(self, scale):
            return Point(self.x * scale, self.y * scale)
    
        __rmul__ = __mul__
    
        def __neg__(self):
            return -1 * self
    
        def __sub__(self, other):
            return self + -other
    
        def weighted_mean(self, other, weight):
            cweight = 1.0 - weight
            x = cweight * self.x + weight * other.x
            y = cweight * self.y + weight * other.y
            return Point(x, y)
    
        def halfway(self, other):
            return self.weighted_mean(other, 0.5)
    
    
    def cencd(p1, p2, p3):
        """ Calculate the center of a circle """
        a = p2 - p1
        b = p3 - p2
        ma = a.y / a.x
        mb = b.y / b.x
        hw = p1.halfway(p2)
        x = ma * mb * (p1 - p3).y + mb * (p1 + p2).x - ma * (p2 + p3).x
        x /= 2.0 * (mb - ma)
        y = -(x - hw.x + hw.y) / ma
        return Point(x, y)
    
    
    p1 = Point(3, 4)
    print(p1)
    print('p1 is {0!r}, its norm is {1}'.format(p1, p1.norm))
    print('and its distance from the origin is', p1.distance_from_origin(), end='\n\n')
    
    p2 = Point(7, 2)
    print('p2 is', repr(p2), end='\n\n')
    
    print('p1 + p2 is', repr(p1 + p2))
    print('p1 * 0.1 is', repr(p1 * 0.1))
    print('p2 - p1 is', repr(p2 - p1), end='\n\n')
    
    p3 = 4 * p1
    print('p3 is', repr(p3), end='\n\n')
    
    print('Weighted means from p1 to p3')
    for i in range(5):
        weight = i / 4.0
        print('{0} {1:4.2f} {2!r}'.format(i, weight, p1.weighted_mean(p3, weight)))
    print()
    
    print('center of a circle for p1, p2, & p3:', repr(cencd(p1, p2, p3)))
    

    output

    x=3, y=4
    p1 is Point(3, 4), its norm is 25
    and its distance from the origin is 5.0
    
    p2 is Point(7, 2)
    
    p1 + p2 is Point(10, 6)
    p1 * 0.1 is Point(0.3, 0.4)
    p2 - p1 is Point(4, -2)
    
    p3 is Point(12, 16)
    
    Weighted means from p1 to p3
    0 0.00 Point(3.0, 4.0)
    1 0.25 Point(5.25, 7.0)
    2 0.50 Point(7.5, 10.0)
    3 0.75 Point(9.75, 13.0)
    4 1.00 Point(12.0, 16.0)
    
    center of a circle for p1, p2, & p3: Point(8.22727272727, 12.4545454545)
    
    0 讨论(0)
  • 2021-01-28 08:14

    Both getX and getY are methods in your code, not attributes. So you will need to call them using getX() and getY().

    So ma=(p2.getY-p1.getY)/(p2.getX-p1.getX) becomes:

    ma = (p2.getY()-p1.getY())/(p2.getX()-p1.getX())
    

    And so on, the other code changes.

    Otherwise, you can also define your methods as @property:

    class Point:
        ...
        ...
        @property
        def getX(self):
            return self.x
        @property
        def getY(self):
            return self.y
        ...
    

    And now you can access these as p1.getX and p2.getY and so on.

    Note that the above @property decorator turns the method into a getter, which makes sense to use only with private variables (variables defined to start with _).

    As such, since both x and y are normal attributes of your class, you can access them directly without using and property decorators or using getter methods, like p1.x and p2.y, as @Padraic points in his post.

    0 讨论(0)
提交回复
热议问题