0

I wrote the following code which runs correctly:

import math

class Point:
    """Two-Dimensional Point(x, y)"""
    def __init__(self, x=0, y=0):
        # Initialize the Point instance
        self.x = x
        self.y = y

    def __iter__(self):
         yield self.x
         yield self.y

    def __add__(self, other):
        addedx = self.x + other.x
        addedy = self.y + other.y
        return Point(addedx, addedy)

    def __mul__(self, other):
        mulx = self.x * other
        muly = self.y * other
        return Point(mulx, muly)

    def __rmul__(self, other):
        mulx = self.x * other
        muly = self.y * other
        return Point(mulx, muly)

    @classmethod
    def from_tuple(


    @property
    def magnitude(self):
        # """Return the magnitude of vector from (0,0) to self."""
        return math.sqrt(self.x ** 2 + self.y ** 2)


    def distance(self, self2):
         return math.sqrt((self2.x - self.x) ** 2 + (self2.y - self.y) ** 2)

    def __str__(self):
        return 'Point at ({}, {})'.format(self.x, self.y)

    def __repr__(self):
        return "Point(x={},y={})".format(self.x, self.y)

I want to add a @classmethod called from_tuple to the Point class that allows creation of Point instances from a tuple containing the x and y values. I want to make it so the tuple input is required. I am lost on the syntax of how to do something like this. The following is the expected output:

location = 2, 3
print(location)
    (2, 3)
point = Point.from_tuple(location)
print(point)
    Point(x=2, y=3)
point = Point.from_tuple()
Traceback (most recent call last):
[...]
TypeError: from_tuple() missing 1 required positional argument: 'coords'

2 Answers 2

3

A classmethod is very similar to an instance method, except that:

  • You can call it on the class itself without getting an "unbound method" that needs an extra argument, and
  • Whether you call it on the class itself or on an instance, you get the class object as your first parameter.

Traditionally, you name that parameter cls. So:

@classmethod
def from_tuple(cls, tup):
    x, y = tup
    return cls(x, y)

You may be wondering why you need cls at all here. After all, couldn't you just write this as a staticmethod?

@staticmethod
def from_tuple(tup):
    x, y = tup
    return Point(x, y)

Yes, you can—but that doesn't play nice with inheritance. If I make a subclass of Point, and call MyPoint.from_tuple(2, 3), I'd expect to get a MyPoint back, not a Point. By using a classmethod and constructing an instance of cls instead of hardcoding Point, I get a MyPoint, because cls is MyPoint.

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

2 Comments

Thanks for the explanation. Just a follow up question, how would one create a method that allows updating the x, y values of a Point instance from a tuple. I want to do this such that if point = Point(3, 4) and i say for example point.loc_tuple((5, 6)) the output would be Point(x=5, y=6).
@user10200421 You want to modify it in-place? Then just write a method that does that: def loc_tuple(self, tup): self.x, self.y = tup.
3

It's just

@classmethod
def from_tuple(cls, location):
    return cls(*location)

Comments

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.