Im trying to calculate cartesian distance between two points using classes - python

import random
class point:
def __init__(self,p):
self.p = p
def fill_point(self):
x = random.uniform(0,100)
y = random.uniform(0,100)
z = random.uniform(0,100)
self.p = [x,y,z]
return self.p
def distance_between_points(self,p1,p2):
D = ((self.p1[0]-self.p2[0])**2 + (self.p1[1]-self.p2[1])**2 + (self.p1[2]-self.p2[2])**2)**(1/2)
return D
def main():
point1 = point(fill_point())
point2 = point(fill_point())
Distance = distance_between_points(point1,point2)
print(Distance)
main()
im quite new to classes and am having a hard time understanding what im doing wrong.

import random
from math import sqrt
class Point:
def __init__(self, name='anonym_point',x=0,y=0,z=0):
self.name = name
self.x = x
self.y = y
self.z = z
#property
def coord(self):
return (self.x, self.y, self.z)
def __repr__(self):
return ("{} has coordinate {}  {}  {}".format(self.name, self.x, self.y, self.z))
def makepoint(namepoint):
return Point(namepoint, random.uniform(0,100), random.uniform(0,100), random.uniform(0,100))
def distance_between_points(p1,p2):
dist = sqrt((p2.x-p1.x)**2 + (p2.y-p1.y)**2 + (p2.z-p1.z)**2)
print("distance between point ",p1.name," and the point ",p2.name," : ",dist)
point1 = makepoint("p1")
point2 = makepoint("p2")
print(point1)
print(point2)
Distance = distance_between_points(point1,point2)

The issue is that you are accessing the class method just as a normal method, you need to initialize class object first then call the method by class object you created, again use only the variables you are sure you need,. keeping code easy for you because I think you already know what you needed I did this
import random
class Point:
def fill_point(self):
x = random.uniform(0,100)
y = random.uniform(0,100)
z = random.uniform(0,100)
p = [x,y,z]
return p
def distance_between_points(self,p1,p2):
D = ((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2 + (p1[2]-p2[2])**2)**(1/2)
return D
def main():
obj = Point()
point1 = obj.fill_point()
point2 = obj.fill_point()
distance = obj.distance_between_points(point1,point2)
print(distance)
main()
it would not kill if you try to understand python classes better, python best naming, etc...

i think that what you are trying to do is something like this.
import math
class Point():
def __init__(self,x,y,z):
self.coordinates = (x,y,z)
def distance(self,point):
return math.sqrt((point.coordinates[0] - self.coordinates[0])**2 + (point.coordinates[1] - self.coordinates[1])**2 + (point.coordinates[1] - self.coordinates[1])**2)
a = Point(4,2,8)
b = Point(2,7,3)
print(a.distance(b))
what you are doing by executing this python code is simply creating a "Point" class, this point class has an attribute (coordinates) that contains its coordinates into a tuple.
so to create a point object you just have to use this code point = Point(x_coordinates,y_coordinates,z_coordinates).
In the last line the code calculates the distance between two points, in that case you are calculating the distance of "b" respect to "a", but you could also do viceversa by doing something like this: print(b.distance(a))
to calculate the distance between random point all you have to do is this:
import math, random
class Point():
def __init__(self,x,y,z):
self.coordinates = (x,y,z)
def distance(self,point):
return math.sqrt((point.coordinates[0] - self.coordinates[0])**2 + (point.coordinates[1] - self.coordinates[1])**2 + (point.coordinates[1] - self.coordinates[1])**2)
r = lambda: random.uniform(0,100)
a = Point(r(),r(),r())
b = Point(r(),r(),r())
print(a.distance(b))
this is how to do that, but i really don't understand why you should calculate the distance between two random numbers

Related

adding two values from different classes

class PolygonInteriorAngle(object):
def __init__(self, x):
self.x = self
def FindInteriorAngle(self):
degrees = int((x - 2) * 180)
interior = int(degrees / x)
return interior
def PrintInterior(self):
print("interior angle: " + str(self.FindInteriorAngle()))
class PolygonExteriorAngle(object):
def __init__(self, x):
self.x = self
def FindExteriorAngle(self):
exterior = int(360 / x)
return exterior
def PrintExterior(self):
print("exterior angle: " + str(self.FindExteriorAngle()))
class AngleAddition(object):
def __init__(self, x):
self.x = self
def Add(self):
sum = int(interior + exterior)
return sum
def PrintAdd(self):
print("sum of interior and exterior: " + str(self.Add()))
if __name__ == "__main__":
x = int(input("enter: "))
intObj = PolygonInteriorAngle(x)
intObj.FindInteriorAngle()
intObj.PrintInterior()
extObj = PolygonExteriorAngle(x)
extObj.FindExteriorAngle()
extObj.PrintExterior()
addObj = AngleAddition(x)
addObj.Add()
addObj.PrintAdd()
both classes (PolygonInteriorAngle and PolygonExteriorAngle) work fine, they print what they're expected to. what i want to do in the AngleAddition class is to add both of the final values (interior and exterior) that you get from the other two classes. i think it's pretty inefficient putting them in different classes, but that's what my computer science teacher asked me to and i'm not sure how to use a value from another class in a new class. if you do x = 6, you'll get 120 and 60. with AngleAddition i want to print 180.
General comments:
You need to check very carefully the variables in your instance methods. example:
def Add(self):
sum = int(interior + exterior)
return sum
Both interior and exterior are not specified in the instance method arguments.
I agree with User: Tim Roberts's comment. Either you make a base class "angle" and let the "interior/exterior angle" class inherit from the "angle" class, or just use angle class for both interior/exterior angles. It depends on how you want to write the __init__ method for interior/exterior angle classes.
Note that I overrode the magic method to perform the sum of two angles. There are other ways of doing that cause in my way the + operator is being redefined.
Anyways:
class AngleBase:
def __init__(self,angle):
self.angle=angle
def __add__(self,angleobj):
return int(self.angle+angleobj.angle)
class PolygonInteriorAngle(AngleBase):
def __init__(self, side):
degrees = int((side - 2) * 180)
interior = int(degrees / side)
AngleBase.__init__(self,interior)
def FindInteriorAngle(self):
return self.angle
def PrintInterior(self):
print("interior angle: " + str(self.angle))
class PolygonExteriorAngle(AngleBase):
def __init__(self, side):
exterior = int(360 / side)
AngleBase.__init__(self,exterior)
def FindExteriorAngle(self):
return self.angle
def PrintExterior(self):
print("exterior angle: " + str(self.angle))
class AngleAddition:
def __init__(self, x):
pass
def Add(self,interior, exterior):
sum = int(interior + exterior)
return sum
def PrintAdd(self,interior, exterior):
print("sum of interior and exterior: " + str(self.Add(interior, exterior)))
if __name__ == "__main__":
x = int(input("enter: "))
intObj = PolygonInteriorAngle(x)
print(intObj.angle)
intObj.FindInteriorAngle()
intObj.PrintInterior()
extObj = PolygonExteriorAngle(x)
extObj.FindExteriorAngle()
extObj.PrintExterior()
addObj = AngleAddition(x)
addObj.Add(extObj,intObj)
addObj.PrintAdd(extObj,intObj)

Best Practice for passing arguments in a class Python

I'm new to OOP and pretty sure the way I'm about to solve something is not the smartest.
I'm building a custom K-means Algorithm and want to give options for different distance functions.
The way I am about to solve it, is building if statements and calculate the distances respectively.
For Example:
class ExampleDist():
def __init__(self, measure="euklid"):
self.measure = measure
def euklid_distance(x_1,x_2):
dist = np.linalg.norm(x_1-x_2)
return dist
def abs_distance(x_1,x_2):
dist = np.absolute(x_1-x_2)
return dist
def dist(self, x_1, x_2):
if(self.measure == "euklid"):
self.dist = euklid_distance(x_1,x_2)
elif(self.measure == "abs"):
self.dist = abs_distance(x_1,x_2)
dist1 = ExampleDist(measure = "euklid")
dist1.dist(np.array([1,1]),np.array([0,2]))
However in the K-Mean Algorithm I would have to copy-paste the whole loop where the distances between the datapoints and centroid is calculated and only change the distances.
Copy pasting is never a good solution, so I would hope to have a solution that automatically passes on which distance measure I want to use.
Like so (pseudo code):
class ExampleDist():
def __init__(self, measure="euklid"):
self.measure = measure
def euklid_distance(x_1,x_2):
dist = np.linalg.norm(x_1-x_2)
return dist
def abs_distance(x_1,x_2):
dist = np.absolute(x_1-x_2)
return dist
def dist(self, x_1, x_2):
self.dist = [self.meassure]_distance(x_1,x_2)
dist1 = ExampleDist(measure = "euklid")
dist1.dist(np.array([1,1]),np.array([0,2]))
Why not just create a single dist function, like:
class ExampleDist():
def __init__(self, measure="euklid"):
self.measure = measure
def dist(self, x_1, x_2):
if self.measure == 'euklid':
return np.linalg.norm(x_1-x_2)
elif self.measure == 'absolute':
return np.absolute(x_1-x_2)
else:
return None
Assuming that all the distance functions you are going to have will accept the same arguments (x1 and x2), you can use a dict to map between the distance type and the distance function.
This is one of the most expandable and flexible ways to achieve this.
class ExampleDist():
_distance_funcs = {'euclid': np.linalg.norm,
'abs': np.absolute}
# or implement your own wrappers as in your example
def dist(self, x1, x2, measure):
try:
return self._distance_funcs[measure](x1, x2)
except KeyError:
raise ValueError(f"`measure` should be one of {', '.join(self._distance_funcs.keys())}")

how to make a temporary object from withing the class function in python?

I'm writing this code and there is a need to send objects as parameters in functions. My problem is one of the objects needs to be resued with its original values but as I need to return an object from the functions.
I don't know how I can send the answer and keep the original values in the object
safe for reuse. Is there any way to make an object from the class declaration itself?
import math
class Points(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __sub__(self, no):
no.x = no.x - self.x
no.y = no.y - self.y
no.z = no.z - self.z
return(no)
def dot(self, no):
ans = (self.x * no.x)+(self.y * no.y)+(self.z * no.z)
return ans
def cross(self, no):
x = (self.y * no.z)-(self.z * no.y)
y = (self.x * no.z)-(self.z * no.x)
z = (self.x * no.y)-(self.y * no.x)
self.x = x
self.y = y
self.z = z
return(self)
def absolute(self):
return pow((self.x ** 2 + self.y ** 2 + self.z ** 2), 0.5)
if __name__ == '__main__':
points = list()
for i in range(4):
a = list(map(float, input().split()))
points.append(a)
a, b, c, d = Points(*points[0]), Points(*points[1]), Points(*points[2]), Points(*points[3])
x = (b - a).cross(c - b)
y = (c - b).cross(d - c)
angle = math.acos(x.dot(y) / (x.absolute() * y.absolute()))
print("%.2f" % math.degrees(angle))
I want to do something like:
def function_name(self,other)
temp.x = self.x + other.x
temp.y = self.y + other.y
return temp
This way both input objects will have their original values but I don't know how to get that temp.
Thanks everyone who helped. I got the answer to what I was looking. I wanted an object to act as a container that can store the class variables,
and I didn't knew I can just make a new object of the class from within it!
import math
class Points(object):
def __init__(self, x, y, z):
self.x=x
self.y=y
self.z=z
def __sub__(self, no):
return Points((self.x-no.x),(self.y-no.y),(self.z-no.z))
def dot(self, no):
return (self.x*no.x)+(self.y*no.y)+(self.z*no.z)
def cross(self, no):
return Points((self.y*no.z-self.z*no.y),(self.z*no.x-self.x*no.z),(self.x*no.y-self.y*no.x))
def absolute(self):
return pow((self.x ** 2 + self.y ** 2 + self.z ** 2), 0.5)
As you can see using points, i.e the constructor for class Points, I can store the result of any operations and can return it as an object while not altering my input objects.
If what you're trying to do is reuse a variable that you have passed to a class object, you can just duplicate it in your __init__ statement, or in the function where you use it.
e.g
class Foo:
def __init__(self, my_var1, my_var2):
self.my_var1 = my_var1
self.my_var2 = my_var2
def bar(self):
bar_var1 = self.my_var1
bar_var2 = self.my_var2
bar_var1 = bar_var1 + bar_var2
return bar_var1
Although, I am a little confused by why you are attempting to return self in your cross function, as self is a class parameter, and you don't seem to be using it in its intended purpose. If you're confused about how you should be using self, a brief read through the python class tutorial might be helpful. However, barring that, I hope this answers your question.

Cannot grab returned x, y float values from list to use in point distance

I'm new to python, and programming in general and am struggling to understand why I can't access the x, y coordinates of the list I created ranlist to use as variables in my math module distance formula.
Here is the entirety of my code, however the step of defining the function closestpt is where I am hung up, and within the function, ranlist.x, ranlist.y is where I get an
AttributeError: list object has no attribute 'x'
Can someone explain to me why ranlist does not have 'x' and 'y' as attributes, and how I can access the x,y points in the list ranlist? When I step through the code and debug I can see the random float values generated
import math
class Point():
def __init__(self, x, y, z=0):
self.x=x
self.y=y
self.z=z
self.dem=2
if (z!=0):
self.dem=3
def print_coordinate(self):
print "The x coordinate is %s, the y coordinate is %s, and the z coordinate is %s" % (self.x, self.y, self.z)
def calc_distance(self, next1):
try:
if (self.z==0):
dx = self.x - next1.x
dy = self.y - next1.y
return math.hypot(dx,dy)
else:
threedist = ((self.x - next1.x)^2 + (self.y - next1.y)^2 + (self.z - next1.z)^2)
return math.sqrt(threedist)
except(SyntaxError, IndexError, TypeError) as e:
print e
cord1 = Point(0,1,4)
cord2 = Point(0,4,0)
print cord1.print_coordinate()
print cord1.calc_distance(cord2)
import random
a = 10
b = 20
val = random.uniform(a,b)
ranlist = []
def ranpoint(num_point, dimension, lower_bound, upper_bound):
for i in range(num_point):
x = random.uniform(lower_bound, upper_bound)
y = random.uniform(lower_bound, upper_bound)
ranlist.append(Point(x,y,0))
return ranlist
print ranpoint
print ranpoint(100, "2d", 0, 100)
rantest = ranpoint(100, '2d', 0, 100)
def closestpt():
cordt = Point(50,50)
dist1 = []
for i in range(0, 100):
ndx = cordt.x - ranlist.x
ndy = cordt.y - ranlist.y
dist2 = math.hypot(ndx,ndy)
dist1.append(dist2)
return dist1
print closestpt()
You have ranlist which is a list. You append a Point to it. So now ranlist has 1 object inside it of type Point.
To access this object you could run ranlist[0].x and ranlist[0].y which will access the first member of the list (in index 0) and retrieve the value of x and y respectively.

How can I improve calling my methods/functions from a class in Python3?

I've got a class called Point with many functions. I put an extract code:
#/usr/bin/env python3
# -*- coding: utf-8 -*-
from math import sqrt, pow, hypot, atan2, cos, sin
class Point(object):
__slots__ = ['x', 'y', 'z']
def __init__(self, x=0, y=0, z=None):
self.x = x
self.y = y
self.z = z
def __del__(self):
#del P destroy (delete) a point
class_name = self.__class__.__name__
def dist(self, P):
if self.z is not None:
d = sqrt(pow(self.x - P.x, 2) + pow(self.y - P.y, 2) +
pow(self.z - P.z, 2))
return d
else:
d = sqrt(pow(self.x - P.x, 2) + pow(self.y - P.y, 2))
return d
def pto_medio(self, P):
Q = Point(self.x, self.y)
if self.z is not None:
Q = Point(self.x, self.y, self.z)
else:
Q = Point(self.x, self.y)
R = (1. / 2.) * (P + Q)
return R
def entrada(self):
point = raw_input('Introduce un punto:\n')
point = point.replace('(', '')
point = point.replace(')', '')
l1 = point.rsplit(',')
self.x = float(l1[0])
self.y = float(l1[1])
if len(l1) == 3:
self.z = float(l1[2])
l1 = []
def __repr__(self):
if self.z is not None:
return('({}, {}, {})'.format(self.x, self.y, self.z))
else:
return('({}, {})'.format(self.x, self.y))
When I call the functions I put this code:
def main():
p = Point()
q = Point()
Point.entrada(p)
Point.entrada(q)
s = p + q
r = p - q
m = 5 * p
print(('Distancia = {}'.format(p.dist(q))))
print(('Punto Medio = {}'.format(p.pto_medio(q))))
if __name__ == '__main__':
main()
I put p.dist(q) and p.pto_medio(q) but I want to write dist(p, q) and pto_medio(p, q), respectivily. I've seen several solutions about that but all solutions give me error.
Thanks!
I don't know why you want to do this… but if you want to, it's easy.
In Python, an unbound method (that is, a method accessed as a member of the class object) can be called just like a function, by passing the self argument explicitly. So:
dist = Point.dist
pto_medio = Point.pto_medio
dist(p, q)
pto_medio(p, q)
In other words, the unbound method is the function you def'd in the class definition, with no magic whatsoever.*
If you want to know how this all works under the covers, see the Descriptor HOWTO and how methods work.
And there are plenty of cases where this is useful, beyond just adapting two pieces of code that were written incompatibly. For example, map and filter don't take a function, they take any callable. Sometimes it makes sense to pass them an unbound method:
with open(path) as f:
strippedlines = map(str.strip, f)
If you couldn't pass unbound methods around like functions, you'd have to write that as:**
with open(path) as f:
strippedlines = map(lambda line: line.strip(), f)
* In Python 2.x, this isn't true; an unbound method is instead a bound method with None for the bound instance, and there's special magic to make it work. But in 3.0+, unbound methods are just plain functions.
** Well, actually you could just use a comprehension: (line.strip() for line in f). But if you wanted to use map, you'd have to build a wrapper.

Categories

Resources