Implementing a point class in Python - python

So I'm trying to implement a point class which creates a point and then rotate, scale and translate the point. Here's what I've currently written.
class Point:
'''
Create a Point instance from x and y.
'''
def __init__(self, x, y):
self.x = 0
self.y = 0
'''
Rotate counterclockwise, by a radians, about the origin.
'''
def rotate(self, a):
self.x0 = math.cos(this.a) * self.x - math.sin(this.a) * self.y
self.y0 = math.sin(this.a) * self.x + math.cos(this.a) * self.y
'''
Scale point by factor f, about the origin.
Exceptions
Raise Error if f is not of type float.
'''
def scale(self, f):
self.x0 = f * self.x
self.y0 = f * self.y
'''
Translate point by delta_x and delta_y.
Exceptions
Raise Error if delta_x, delta_y are not of type float.
'''
def translate(self, delta_x, delta_y):
self.x0 = self.x + delta_x
self.y0 = self.y + delta_y
'''
Round and convert to int in string form.
'''
def __str__(self):
return int(round(self.x))
Something in this code is generating an error. Now I haven't implementing error catching and I do have an error method at the top
class Error(Exception):
def __init__(self, message):
self.message = message
But how would I catch the error if a certain variable is not of type float?
Here's one of the if statements I'm using:
def __init__(self, x, y):
if not isinstance(x, float):
raise Error ("Parameter \"x\" illegal.")
self.x = x
self.y = y
if not isinstance(y, float):
raise Error ("Parameter \"y\" illegal.")
self.x = x
self.y = y
But that gets me an indentation error. So how exactly can I print out an error message that says exactly which variable is causing the problem?

If you want to raise an exception, do it in the Point's initializer:
def __init__(self, x, y):
if not isinstance(x, float) or not isinstance(y, float):
raise Error("Point's coordinates must be floats.")
self.x = x
self.y = y
Or convert the coordinates to float:
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)

If the variable is not a float, you'll get a TypeError. Pretty much you can 'catch' these error like this;
try:
pass # your stuff here.
except e as TypeError:
print e # this means a type error has occurred, type is not correct.
Also, this would be worth reading for checking for correct types at the start with assert; https://wiki.python.org/moin/UsingAssertionsEffectively

Related

Change a self attribute only for one object in a class in Python

I'm stuck on a problem in Python... (i'm an absolute beginner but i need to do a little
environmental science model..)
so the problem is I have:
class C:
def __init__(self, x, y, z):
self.x = x
self.y = self.x * 8
self.z = self.y * 9 + 0.5
self.w = self.z +2
one = C(5,8,12)
two = C(2,12,12)
three = C(1,2,3)
So... i want to change the self.z but only for the object three
(i want it to be self.z = 12 * self.x );
I have to call it in self.w so i can't modify it after my istances...
do you have any suggestion to a beginner?
Thank you so much and have a nice day!
A few notes. First you are not actually using the arguments of y or z that are passed in __init__(self, x, y, z).
To allow on the fly overloading, you may want to break out the individual assignments into their own methods so it is easier to change the behavior you want.
Below you can pass in a custom function that will be applied to the x value when calculating z.
class C:
def __init__(self, x, custum_fn_z=None):
self.x = x
self.y = self.calc_y()
self.z = self.calc_z(custum_fn_z)
self.w = self.calc_w()
def calc_y(self):
return self.x * 8
def calc_z(self, custom_fn_z=None):
if custom_fn_z:
return custom_fn_z(self.x)
return self.y * 9 + 0.5
def calc_w(self):
return self.z +2
to use it:
one = C(5)
two = C(2)
three = C(1, lambda x: 12*x)

Add methods in another method of a same class

I created 2 method (first, last) and a third one (sum); I want the sum of returned value of first and last and then stored in sum; then I want to display the returned value of the sum.
P.S. I am practicing class and object. This problem can be solved using very basic syntax but I want to learn the class and objects. I am telling this cause, you may think that why am I doing this when there are easier way to do that. ;)
Thanks
class Total:
def __init__(self, x, y):
self.x = x
self.y = y
def first(self):
if self.x < 15:
return self.x * self.y
else:
return self.x - self.y
def last(self):
if self.x < 100:
return self.x + 5
else:
return self.x - 6
def sum(self):
pass
# I need help here
# add returned value of first() and last()
p = Total(25, 5)
p.sum()
You can return the first() and last() methods accumulated sum from the sum() method like:
class Total:
def __init__(self, x, y):
self.x = x
self.y = y
def first(self):
if self.x < 15:
return self.x * self.y
else:
return self.x - self.y
def last(self):
if self.x < 100:
return self.x + 5
else:
return self.x - 6
def sum(self):
return self.first() + self.last()
p = Total(25, 5)
print(p.sum())
Output:
50

Python Classes using __init and __repr__ methods

Iam trying to create a class that should accept two arguments, x and y, and be represented by a string 'Point(x, y)' with appropriate values for x and y
class Point(object):
def __init__(self, x, y):
self.x = 0
self.y = 0
def __repr__(self):
return "Point(%s,%s)"%(self.x, self.y)
Error:
Point(0,0) is not of type 'string'
Failed validating 'type' in schema['items']:
{'type': 'string'}
On instance[0]:
Point(0,0)
"self.x" is the value of the instance of your class. So, if you set "self.x = 0", it means whenever you create an object for that class, the "x" value of that object will always be 0 instead of what you pass in the parameter.
"x" is the value of what you pass in the parameter.
self.x = x
self.y = y
Code:
class MyClass():
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Point(%s,%s)"%(self.x, self.y)
thiss = MyClass(0, 0)
print(thiss.__repr__())
thiss = MyClass(20, 20)
print(thiss.__repr__())
Output:
daudn$ python3 point.py
Point(20,20)
daudn$ python3 point.py
Point(0,0)
When declaring your init function, you initialized self.x and self.y to always be 0. If you look at the code I've posted, whatever number you pass to the class will become the values or Point.

Python: Unexpected identifier when calling method of class

I would like to write a class Calculator including:
a function called add that takes two parameters containing double values and returns their sum
a function called subtract that takes two parameters containing double values and returns their difference (subtract the second from the first)
a function called multiply that takes two parameters containing double values and returns their product
a function called divide that takes two parameters containing double values and returns the value of the first divided by the second. If the second number is a zero, do not divide, and return "You can't divide by zero!"
This is my attempt, but apparently it's not correct.
class Calculator:
def add(x,y):
return x+ y
def subtract(x,y):
return x - y
def multiply(x,y):
return x * y
def divide(x,y):
if y==0:
return "You can t divide by zero!"
else:
return x/y
From the results, I get unexpected identifier x and y.
Object methods in python need to explicitly define the 'this' parameter you know from 'C', or the argument referring to the object itself. In Python it is usually called 'self'. For example:
class Calc:
def add(self,x,y): return x+y
Since all your methods do not really need self, and the calculator is more of a container of methods, you can define them as class methods, so Calc.add(3,4) works without creating an object:
class Calc:
#staticmethod
def add(x,y): return x+y
If you're new to python please note indentation is very important as well.
This answer will be accepted by the programming lab system:
class Calculator:
def add(self, x, y):
self.x = x
self.y = y
a = self.x + self.y
return a
def subtract(self, x, y):
self.x = x
self.y = y
a = self.x - self.y
return a
def multiply(self, x, y):
self.x = x
self.y = y
a = self.x * self.y
return a
def divide(self, x, y):
self.x = x
self.y = y
if (y == 0):
a = "You can't divide by zero!"
else:
a = self.x / self.y
return a
There are more simple soutions but this will be accepted by the programming lab editor. It can be a bit picky at times.
class Calculator:
def add(self,num1,num2):
print(num1+num2)
def subtract(self,num1,num2):
print(num1-num2)
def multiply(self,num1,num2):
print(num1*num2)
def divide(self,num1,num2):
print(num1 / num2)
object1 = Calculator()
object2 = Calculator()
object3 = Calculator()
object4 = Calculator()
object1.add(100,200)
object2.subtract(50,30)
object3.multiply(10,3)
object4.divide(250,5)

Is it possible to instantiate an object of one class in two different ways?

Here is an example which creates a point as p=Point(x, y). Assume that I have some array ppp=(x, y) where x and y are numbers and I want to make it of class Point but in the way: p=Point(ppp). I can do either one or another way but not both simultaneously. Is it possible to have both ways?
There are two different ways to acquire the result, the first is to analyse arguments that you pass to __init__ and in dependence of their quantity and type - choose a decision what are you using to instantiate class.
class Point(object):
x = 0
y = 0
def __init__(self, x, y=None):
if y is None:
self.x, self.y = x, x
else:
self.x, self.y = x, y
The other decision is to use classmethods as instantiators:
class Point(object):
x = 0
y = 0
#classmethod
def from_coords(cls, x, y):
inst = cls()
inst.x = x
inst.y = y
return inst
#classmethod
def from_string(cls, x):
inst = cls()
inst.x, inst.y = x, x
return inst
p1 = Point.from_string('1.2 4.6')
p2 = Point.from_coords(1.2, 4.6)
If you know that you have a tuple/list while creating the instance, you can do: p = Point(*ppp), where ppp is the tuple.
class Point:
def __init__(self, x, y=None):
if isinstance(x, tuple):
self.x, self.y = x
else:
self.x = x
self.y = y
Yes:
class Point(object):
def __init__(self, x, y=None):
if y is not None:
self.x, self.y = x, y
else:
self.x, self.y = x
def __str__(self):
return "{}, {}".format(self.x, self.y)
print Point(1,2)
# 1, 2
print Point((1,2))
# 1, 2
I would guess that your looking for a way to overload your constructor, as is common in statically typed languages such as C++ and Java.
This is not possible in Python. What you can do is provide different keyword argument combinations, something like:
class Point(object):
def __init__(self, x=None, y=None, r=None, t=None):
if x is not None and y is not None:
self.x = x
self.y = y
elif r is not None and t is not None:
# set cartesian coordinates from polar ones
Which you would then use as:
p1 = Point(x=1, y=2)
p2 = Point(r=1, t=3.14)

Categories