I create an instance of class Vector2 with line AB = Vector2.from_points(A, B)
But python errors out with TypeError: object() takes no parameters
on line AB = Vector2.from_points(A,B)
and on line return Vector2(cls, P2[0]-P1[0], P2[1]-P1[1])
so I figured maybe the book is wrong (I'm looking at examples in a book). I subtract the Vector2 and cls from the def from_points statement so that...
this is how the new line reads: return (P2[0]-P1[0], P2[1]-P1[1])
When I do this a receive the vector value from def from_points equal too (5, 10)
But then python errors out on:
print AB.get_magnitude()
with AttributeError: 'tuple' object has no attribute 'get_magnitude'
so without the code related to Vector2 and cls the program won't read AB as a class object but it seems that I'm not formatting it right so it won't go through.
I have been stuck on this for days.
#Vector Test
import math
class Vector2(object):
def _init_(self, x=0.0,y=0.0):
self.x = x
self.y = y
def _str_(self):
return"(%s,%s)"%(self.x,self.y)
#classmethod
def from_points(cls, P1, P2):
return Vector2(cls, P2[0]-P1[0],P2[1]-P1[1])
def get_magnitude(self):
return math.sqrt(self.x**2 + self.y**2)
A = (15.0, 20.0)
B = (20.0, 30.0)
AB = Vector2.from_points(A, B)
print AB
print AB.get_magnitude()
CHANGED CODE:
#Vector Test
import math
class Vector2(object):
def _init_(self, x=0.0,y=0.0):
self.x = x
self.y = y
def _str_(self):
return"(%s,%s)"%(self.x,self.y)
#classmethod
def from_points(cls, P1, P2):
return (P2[0]-P1[0],P2[1]-P1[1])
def get_magnitude(self):
return math.sqrt(self.x**2 + self.y**2)
A = (15.0, 20.0)
B = (20.0, 30.0)
AB = Vector2.from_points(A, B)
print AB
print AB.get_magnitude()
that's (probably) what you mean.
#Vector Test
import math
class Vector2(object):
def __init__(self, x=0.0,y=0.0):
self.x = x
self.y = y
def __str__(self):
return"(%s,%s)"%(self.x,self.y)
#classmethod
def from_points(cls, P1, P2):
return Vector2(P2.x-P1.x,P2.y-P1.y)
def get_magnitude(self):
return math.sqrt(self.x**2 + self.y**2)
A = Vector2(15.0, 20.0)
B = Vector2(20.0, 30.0)
AB = Vector2.from_points(A, B)
print( AB )
print( AB.get_magnitude() )
Related
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
I am having a problem in simple code I wrote
Class Point has x and y values
Class square (Point) includes 4 points : p1,p2,p3,p4
I am trying to update x value of p1 for example with sq1.p1.set_x(num1) and failed.
I tried to work with public defnition but also failed
Whot is my problem ? Thanks
class Point:
def __init__(self,x=0,y=0):
self.__x = x
self.__y = y
def get_x(self):
return self.__x
def get_y(self):
return self.__y
def set_x(self,x=0):
self.__x = x
def set_y(self,y=0):
self.__y = y
class Square (Point):
def __init__(self,p1,p2,p3,p4):
self.__p1 = p1
self.__p2 = p2
self.__p3 = p3
self.__p4 = p4
def get_p1(self):
return self.__p1
def get_p2(self):
return self.__p2
def get_p3(self):
return self.__p3
def get_p4(self):
return self.__p4
def set_p1(self,p1):
self.__p1 = p1
def set_p2(self,p2):
self.__p2 = p2
def set_p3(self,p1):
self.__p3 = p3
def set_p4(self,p4):
self.__p4 = p4
def main():
p1 = Point(2,0)
p2 = Point(2,2)
p3 = Point(0,2)
p4 = Point(0,0)
sq1 = Square(p1,p2,p3,p4)
sq1.p1.set_x(4) # this line failing
if __name__ == "__main__":
main()
Replace
sq1.p1.set_x(4) # this line failing
with
sq1.get_p1().set_x(4)
This is because class Square doesn't have a p1 property (it has a __p1 property, but not p1).
I have been working on an assignment for one of my introductory classes. I am almost done with my code and but I keep getting "AttributeError: 'tuple' object has no attribute 'dist'." I understand that the problem starts from midpt function and that I need to return an instance of the class instead of the tuple; however, I have not been able to do that. Could you please take a look at my code? It would be much appreciated.
'''
import math
class Point(object):
# The contructor for Point class
def __init__(self, x = 0, y = 0):
self.x = float(x)
self.y = float(y)
# The getter for x
#property
def x(self):
return self._x
# The setter for x
#x.setter
def x(self, value):
self._x = value
# The getter for y
#property
def y(self):
return self._y
# The setter for y
#y.setter
def y(self, value):
self._y = value
# Function for getting the distance between two points
def dist(self, other):
xVar = (other.x - self.x) ** 2
yVar = (other.y - self.x) ** 2
equation = xVar + yVar
distance = math.sqrt(equation)
return distance
# Function for getting the midpoint
def midpt(self, other):
xVar = (other.x - self.x) / 2
yVar = (other.y - self.y) / 2
midpoint = (xVar,yVar)
return midpoint
# Magic function for printing
def __str__(self):
return "({},{})".format(self.x, self.y)
##########################################################
# ***DO NOT MODIFY OR REMOVE ANYTHING BELOW THIS POINT!***
# Create some points
p1 = Point()
p2 = Point(3, 0)
p3 = Point(3, 4)
# Display them
print("p1:", p1)
print("p2:", p2)
print("p3:", p3)
# Calculate and display some distances
print("distance from p1 to p2:", p1.dist(p2))
print("distance from p2 to p3:", p2.dist(p3))
print("distance from p1 to p3:", p1.dist(p3))
# Calculate and display some midpoints
print("midpt of p1 and p2:", p1.midpt(p2))
print("midpt of p2 and p3:", p2.midpt(p3))
print("midpt of p1 and p3:", p1.midpt(p3))
# Just a few more things...
p4 = p1.midpt(p3)
print("p4:", p4)
print("distance from p4 to p1:", p4.dist(p1))
You might want to change midpoint = (xVar,yVar) to midpoint = Point(xVar, yVar).
In this way, p4 is a Point (and not a tuple!) instance, and you can call the dist method on it.
So I have a point class and a line class that both have a scale method.
class Point:
def __init__(self, x, y):
if not isinstance(x, float):
raise Error("Parameter \"x\" illegal.")
self.x = x
if not isinstance(y, float):
raise Error ("Parameter \"y\" illegal.")
self.y = y
def scale(self, f):
if not isinstance(f, float):
raise Error("Parameter \"f\" illegal.")
self.x = f * self.x
self.y = f * self.y
def __str__(self):
return '%d %d' % (int(round(self.x)), int(round(self.y)))
class Line:
def __init__(self, point0, point1):
self.point0 = point0
self.point1 = point1
def scale(self, factor):
if not isinstance(factor, float):
raise Error("Parameter \"factor\" illegal.")
self.point0.scale(factor)
self.point1.scale(factor)
def __str__(self):
return "%s %s" % (self.point0, self.point1)
So one of the tests I do on this code is to check for a shallow copy which I do in this test code.
p0.scale(2.0)
p1.scale(2.0)
print line
The problem is the print line gives me 0 2 4 6 and it should give me 0 1 2 3. So why is it printing multiples of 2 instead? The scale method is supposed to return the scaled values and for all the other test cases it prints the expected values however just with this test code it prints values I didn't expect. Here's how the values of p0 and p1 are set up:
print '********** Line'
print '*** constructor'
p0 = Point(0.0, 1.0)
p1 = Point(2.0, 3.0)
line = Line(p0,p1)
print line
In your __init__ method for Line, you are assigning the names self.point0 and self.point1 to the two points that are passed in. This does not make a new copy, only gives the objects in memory another name. If you change this method to
def __init__(self, point0, point1):
self.point0 = Point(point0.x, point0.y)
self.point1 = Point(point1.x, point1.y)
then everything should work as intended. Or, you can use the copy module:
from copy import copy
class Line:
def __init__(self, point0, point1):
self.point0 = copy(point0)
self.point1 = copy(point1)
You could also define your own __copy__ and __deepcopy__ methods on your Point class.
def __copy__(self):
return type(self)(self.x, self.y)
def __deepcopy__(self, memo):
return type(self)(self.x, self.y)
You can look at this question for more information.
Printing line after scaling p0,p1 by 2 multiply x,y pairs for p0, p1. Line instance values of point0 and point1 pointing to instances of Point which is p0 and p1 appropriately, as result of print line you can see updated value of x,y of each point.
p0 = Point(0,1)
p1 = Point(2,3)
line = Line(p0, p1)
print line # 0 1 2 3
p0.scale(2.0)
p1.scale(2.0)
print line # 0 2 4 6
I solve a system of two equations in a class property, and it returns the solution -- values of two variables. I'd like both values be a properties of the class -- how do I achieve this without solving the system twice? Here's an example
#!/usr/bin/python3
class Test(object):
pass
def ab(self):
print("Calc!")
a = 1
b = 2
return [a,b]
#property
def a(self):
return self.ab()[0]
#property
def b(self):
return self.ab()[1]
test = Test()
print(test.a)
print(test.b)
It outputs:
Calc!
1
Calc!
2
so it actually "solved" the system of equations (ab property) twice. If it had solved it once, than the output would be:
Calc!
1
2
How do I achieve this?
Edit
Example with a system:
#!/usr/bin/python3
import scipy
from scipy.optimize import fsolve
class Test(object):
def __init__(self, c, d):
self.c = c
self.d = d
def ab(self):
print("Calc!")
result = fsolve(lambda x: [
x[0] + 2*x[1] + self.c
, 3*x[0] - x[1] + self.d
], [1,1])
return result
#property
def a(self):
return self.ab()[0]
#property
def b(self):
return self.ab()[1]
test = Test(-5,2)
print(test.a)
print(test.b)
Gives:
Calc!
0.142857142857
Calc!
2.42857142857
I want it to solve a system only once:
Calc!
0.142857142857
2.42857142857
Edit 2
Real code:
#!/usr/bin/env python3
import argparse, os, sys
# ==============
## parsing args:
parser = argparse.ArgumentParser()
argsLip = parser.add_argument_group('Properties of lipid:')
argsLip.add_argument('-A', '--area',
help = "incompressible area, Ų (default to %(default)s)",
dest = 'A_n',
action = 'store',
type = float,
default = 20.0,
)
argsLip.add_argument('-L',
help = "basic length in Å (default to %(default)s)",
dest = 'L',
action = 'store',
type = float,
default = 15.0,
)
argsLip.add_argument('-K', '--K-coef',
help = "bending rigidity in kTL (default to %(default)s)",
dest = 'K_f_coef',
action = 'store',
type = float,
default = 0.33,
)
argsMem = parser.add_argument_group('Properties of membrane:')
argsMem.add_argument('-g', '--gamma',
help = "surface tension, erg/cm² (default to %(default)s)",
dest = 'γ',
action = 'store',
type = float,
default = 30.0,
)
argsEnv = parser.add_argument_group('Properties of environment:')
argsEnv.add_argument('-T', '--temperature',
help = "temperature, K (default to %(default)s)",
dest = 'T',
action = 'store',
type = float,
default = 323.0,
)
argsCalc = parser.add_argument_group('Calc options:')
argsCalc.add_argument('-a', '--a-trial',
help = "trial value of a to be used in nsolve (default to %(default)s)",
dest = 'a_trial',
action = 'store',
type = float,
default = 2.0,
)
args = parser.parse_args()
# =========
## imports:
# symbolic:
import sympy
from sympy import symbols, solve, nsolve, pprint, diff, S, Function
from sympy import sqrt as Sqrt
sympy.init_printing(pretty_print=True, use_unicode=True, wrap_line=False, no_global=True)
# numeric:
import scipy
from scipy import sqrt
from scipy.optimize import fsolve
# constants:
from scipy import pi as π
from scipy.constants import k as k_SI
k = k_SI * 10**7 # J/K → erg/K
# =========
## program:
class MonoFlexible_symbolic(object):
"This class initiates common symbolic expressions to be used in all MonoFlexible classes."
def __init__(self):
a, l = symbols("a l", real=True, positive=True)
b = Function('b')(a, l)
ν = Function('ν')(l)
equation = (
3 / (4 * b)
+ 1 / ( 2 * Sqrt(2) * b**(S(3)/4) )
- ν * ( Sqrt(a) - 1 )**2
)
equation_diff_a = equation.diff(a)
equation_diff_a2 = equation_diff_a.diff(a)
equation_diff_l = equation.diff(l) .subs(ν.diff(l) , -3*ν)
equation_diff_l2 = equation_diff_l.diff(l) .subs(ν.diff(l,2), 12*ν)
equation_diff_al = equation_diff_a.diff(l) .subs(ν.diff(l) , -3*ν)
db_da = solve( equation_diff_a , b.diff(a) )[0]
d2b_da2 = solve( equation_diff_a2 , b.diff(a,2) )[0]
db_dl = solve( equation_diff_l , b.diff(l) )[0]
d2b_d2l = solve( equation_diff_l2 , b.diff(l,2) )[0]
d2b_dadl = solve( equation_diff_al , b.diff(a).diff(l) )[0]
# print("db_da =")
# pprint(
# db_da
# )
# print("d2b_da2 =")
# pprint("d2b_da2 =",
# d2b_da2
# )
# print("db_dl =")
# pprint(
# db_dl
# )
# print("d2b_dl2 =")
# pprint(
# d2b_d2l
# )
# print("d2b_dadl =")
# pprint(
# cancel(d2b_dadl[0])
# )
self.db_da_func = lambda aa, bb, νν: db_da.subs({
a: aa
, b: bb
, ν: νν
}).evalf()
self.d2b_da2_func = lambda aa, bb, νν: d2b_da2.subs({
a: aa
, b: bb
, ν: νν
}).evalf()
self.db_dl_func = lambda aa, bb, νν: db_dl.subs({
a: aa
, b: bb
, ν: νν
}).evalf()
self.d2b_d2l_func = lambda aa, bb, νν: d2b_dl2.subs({
a: aa
, b: bb
, ν: νν
}).evalf()
self.d2b_dadl_func = lambda aa, bb, νν: d2b_dadl.subs({
a: aa
, b: bb
, ν: νν
}).evalf()
class MonoFlexible(MonoFlexible_symbolic):
def __init__(self,
γ : "Surface tension of the membrane, erg/cm²",
T : "Temperature, K",
L : "Length of the hydrocarbon chain, Å",
A_n : "Non-compressible area of the lipid, Ų",
a_trial : "Initial value for fsolve, default to 2.0" = None,
K_f_coef : "K_f = k T L * K_f_coef, default to 1/3" = None,
) -> "Calculates thermodynamic properties of flexible string":
super().__init__()
self.__γ = γ
self.__T = T
self.__L = L
self.__A_n = A_n
self.__a_trial = a_trial
self.__K_f_coef = K_f_coef
#property
def A_n_Å2(self):
return self.__A_n
#property
def A_n(self):
return self.__A_n * 10**(-16) # Ų → cm²
#property
def L_Å(self):
return self.__L
#property
def L(self):
return self.__L * 10**(-8) # Å → cm
#property
def γ(self):
return self.__γ
#property
def T(self):
return self.__T
#property
def a_trial(self):
"Initial value for numerical equation solving function to find area per lipid."
a_trial = self.__a_trial or 2.0
return a_trial
#property
def K_f_coef(self):
K_f_coef = self.__K_f_coef or 1/3
return K_f_coef
#property
def K_f(self):
"Rigidity of the string."
return k * self.T * self.L * self.K_f_coef
#property
def ν(self):
return self.K_f * self.A_n / (
π * k * self.T * self.L**3
)
#property
def ab(self):
print("Calc!")
ab = fsolve( lambda x: [
3 / ( 4 * x[1] )
+ 1 / ( 2 * sqrt(2) * x[1]**(3/4) )
- self.ν * (sqrt(x[0]) - 1)**2
,
- k * self.T / self.A_n * self.db_da_func(x[0], x[1], self.ν) * self.ν * (sqrt(x[0]) - 1)**2
- self.γ
]
, [2., 300.] )
return ab
#property
def a(self):
return self.ab[0]
#property
def b(self):
return self.ab[1]
# ======
## calc:
def main():
flexible_kwargs = {
"γ" : args.γ,
"T" : args.T,
"L" : args.L,
"A_n" : args.A_n,
"a_trial" : args.a_trial,
"K_f_coef" : args.K_f_coef,
}
flexible = MonoFlexible(**flexible_kwargs)
print( "ν = {ν:.5f}".format(ν=flexible.ν) )
print( "a = {a:.2f}".format(a=flexible.a) )
print( "b = {b:.2f}".format(b=flexible.b) )
# python code run faster in a function:
if __name__ == "__main__":
main()
Works with default parameters, so in order to test it -- just run it.
Sounds to me like you're just trying to cache the solution. Here's a way to do that that involves creating another property:
class Test(object):
def __init__(self):
pass
#property
def solution(self):
try:
return self._solution
except AttributeError:
self._solution = self.ab()
return self._solution
def ab(self):
print("Calc!")
a = 1
b = 2
return [a,b]
#property
def a(self):
return self.solution[0]
#property
def b(self):
return self.solution[1]
test = Test()
print(test.a)
print(test.b)
Output:
Calc!
1
2
Update!
In Python 3.8 a built-in decorator to do this was added to the standard library named functools.cached_property() that makes implementing this scheme in an easier and more succinct way (plus it's thread-safe):
import functools
class Test(object):
def __init__(self):
pass
#functools.cached_property
def ab(self):
print("Calc!")
a = 1
b = 2
return [a,b]
#property
def a(self):
return self.ab[0]
#property
def b(self):
return self.ab[1]
assigning the properties as the results are created could be a way to go
#!/usr/bin/python3
class Test(object):
def __init__(self):
pass
def ab(self):
print("Calc!")
self._a = a = 1
self._b = b = 2
return [a,b]
#property
def a(self):
return self._a
#a.setter
def a(self, value):
self._a = value
#property
def b(self):
return self._b
#b.setter
def b(self, value):
self._b = value
test = Test()
results = test.ab()
print(test.a)
print(test.b)
Your current class doesn't have any statefulness at all, so it doesn't seem like an example of good class design. Its exact operation is completely hard-coded...it is hard to know what advantage you get from having it.
Perhaps what you want is something more along the lines of
class Test(object):
def __init__(self):
self.a, self.b = fsolve(lambda x: [
x[0] + 2*x[1] - 5
, 3*x[0] - x[1] + 2
], [1,1])