Python , my object claims to not have an access to a method - python

I'm writing some Python code and have a class as follows
class GO:
##irrelevant code
def getCenter(self):
xList = []
yList = []
# Put all the x and y coordinates from every GE
# into separate lists
for ge in self.GEList:
for point in ge.pointList:
xList.append(point[0])
yList.append(point[1])
# Return the point whose x and y values are halfway between
# the left- and right-most points, and the top- and
# bottom-most points.
centerX = min(xList) + (max(xList) - min(xList)) / 2
centerY = min(yList) + (max(yList) - min(yList)) / 2
return (centerX, centerY)
###more irrelevant code
def scale(self, factor):
matrix = [[factor,0,0],[0,factor,0],[0,0,1]]
for ge in self.GEList:
fpt = []
(Cx, Cy) = ge.getCenter()
for pt in ge.pointList:
newpt = [pt[0]-C[0],pt[1]-C[0],1]###OR USE TRANSLATE
spt = matrixPointMultiply(matrix, newpt)
finalpt = [spt[0]+C[0],spt[1]+C[0],1]
fpt.append(finalpt)
ge.pointList=fpt
return
Whenever I run it it says: AttributeError: circle instance has no attribute 'getCenter'.
How do I get the object to correctly the call the function upon itself?
This is kind of a noobish question and I am learning, so detailed advice would be helpful.

Have you checked your indenting to make sure it's all consistent? That's a classic Python beginner problem. You need to use consistent whitespace (either tabs or spaces, most people prefer spaces) and the right amount of whitespace.
For example, this may look OK, but it won't do what you expect:
class Dummy(object):
def foo(self):
print "foo!"
def bar(self):
print "bar!"
d = Dummy()
d.bar()
This will return:
AttributeError: 'Dummy' object has no attribute 'bar'
If that's not it, try to pare your code down to the minimum, and post that and how you're calling it. As it stands, the general form looks OK to me, unless I'm missing something.

Related

How to make a float2 Class in Python

I recently wanted to program ray marching in python using ursina engine. to do that i need a special class called float2.
in unity engine you can program float2 normally and give it into your paramater arguments, but in python there is no such class as float2, i tried doing some easy ways to make it but i have problem when i want to store variables.
basically i have a float2 class:
class float2:
def __init__(self, x, y):
self.x = x,
self.y = y
it just stores x and y.
then i have some functions where i use the class:
def length(v: float2):
return float(sqrt(v.x*v.x + v.y*v.y))
def signedDstToCircle(p: float2, centre: float2, radius: float):
return length(centre-p) - radius
this works great but i hit a roadblock.
i need to asign one variable a from a function:
def signedDstToBox(p: float2, centre: float2, size: float2):
offset = float2(abs(p-centre) - size)
# dst from point outside the box to edge (0 if inside the box)
unsignedDst = length(max(offset, 0))
# -dst from point inside the box to edge (0 if outside the box)
dstInsideBox = max(min(offset, 0))
return unsignedDst + dstInsideBox
if i try to run the program now with all it gives me an error:
offset = float2(abs(p-centre) - size)
TypeError: unsupported operand type(s) for -: 'float2' and 'float2'
i think it gives me error because it not a number, so it cant do math operations and also i think when i will fix this issue there will be another problem with storing the variable.
if anyone know how to make this possible so i can math operations and also being able to store variable by just doing offset = float2(abs(p-centre)-size) so it will be stored and i can acces it by doing offset.x and offset.y
thanks in advance, galfar(SpringPeace)

When should I use classes and self method in Python?

I've been trying to write a Python program to calculate a point location, based on distance from 4 anchors. I decided to calculate it as intersection points of 4 circles.
I have a question regarding not the algorithm but rather the use of classes in such program. I don't really have much experience with OOP. Is it really necessary to use classes here or does it at least improve a program in any way?
Here's my code:
import math
class Program():
def __init__(self, anchor_1, anchor_2, anchor_3, anchor_4, data):
self.anchor_1 = anchor_1
self.anchor_2 = anchor_2
self.anchor_3 = anchor_3
self.anchor_4 = anchor_4
def intersection(self, P1, P2, dist1, dist2):
PX = abs(P1[0]-P2[0])
PY = abs(P1[1]-P2[1])
d = math.sqrt(PX*PX+PY*PY)
if d < dist1+ dist2 and d > (abs(dist1-dist2)):
ex = (P2[0]-P1[0])/d
ey = (P2[1]-P1[1])/d
x = (dist1*dist1 - dist2*dist2 + d*d) / (2*d)
y = math.sqrt(dist1*dist1 - x*x)
P3 = ((P1[0] + x * ex - y * ey),(P1[1] + x*ey + y*ex))
P4 = ((P1[0] + x * ex + y * ey),(P1[1] + x*ey - y*ex))
return (P3,P4)
elif d == dist1 + dist2:
ex = (P2[0]-P1[0])/d
ey = (P2[1]-P1[1])/d
x = (dist1*dist1 - dist2*dist2 + d*d) / (2*d)
y = math.sqrt(dist1*dist1 - x*x)
P3 = ((P1[0] + x * ex + y * ey),(P1[1] + x*ey + y*ex))
return(P3, None)
else:
return (None, None)
def calc_point(self, my_list):
if len(my_list) != 5:
print("Wrong data")
else:
tag_id = my_list[0];
self.dist_1 = my_list[1];
self.dist_2 = my_list[2];
self.dist_3 = my_list[3];
self.dist_4 = my_list[4];
(self.X1, self.X2) = self.intersection(self.anchor_1, self.anchor_2, self.dist_1, self.dist_2)
(self.X3, self.X4) = self.intersection(self.anchor_1, self.anchor_3, self.dist_1, self.dist_3)
(self.X5, self.X6) = self.intersection(self.anchor_1, self.anchor_4, self.dist_1, self.dist_4)
with open('distances.txt') as f:
dist_to_anchor = f.readlines()
dist_to_anchor = [x.strip() for x in dist_to_anchor]
dist_to_anchor = [x.split() for x in dist_to_anchor]
for row in dist_to_anchor:
for k in range(0,5):
row[k] = float(row[k])
anchor_1= (1,1)
anchor_2 = (-1,1)
anchor_3 = (-1, -1)
anchor_4 = (1, -1)
My_program = Program (anchor_1, anchor_2, anchor_3, anchor_4, dist_to_anchor)
My_program.calc_point(dist_to_anchor[0])
print(My_program.X1)
print(My_program.X2)
print(My_program.X3)
print(My_program.X4)
print(My_program.X5)
print(My_program.X6)
Also, I don't quite understand where should I use self keyword and where it is needless.
Is it really necessary to use classes here or does it at least improve a program in any way?
Classes are never necessary, but they are often very useful for organizing code.
In your case, you've taken procedural code and just wrapped it in a class. It's still basically a bunch of function calls. You'd be better off either writing it as procedures or writing proper classes.
Let's look at how you'd do some geometry in a procedural style vs an object oriented style.
Procedural programming is all about writing functions (procedures) which take some data, process it, and return some data.
def area_circle(radius):
return math.pi * radius * radius
print(area_circle(5))
You have the radius of a circle and you get the area.
Object oriented programming is about asking data to do things.
class Circle():
def __init__(self, radius=0):
self.radius = radius
def area(self):
return math.pi * self.radius * self.radius
circle = Circle(radius=5)
print(circle.area())
You have a circle and you ask it for its area.
That seems a lot of extra code for a very subtle distinction. Why bother?
What happens if you need to calculate other shapes? Here's a Square in OO.
class Square():
def __init__(self, side=0):
self.side = side
def area(self):
return self.side * self.side
square = Square(side=5)
print(square.area())
And now procedural.
def area_square(side):
return side * side
print(area_square(5));
So what? What happens when you want to calculate the area of a shape? Procedurally, everywhere that wants to deal with shapes has to know what sort of shape it's dealing with and what procedure to call on it and where to get that procedure from. This logic might be scattered all over the code. To avoid this you could write a wrapper function and make sure its imported as needed.
from circle import 'area_circle'
from square import 'area_square'
def area(type, shape_data):
if type == 'circle':
return area_circle(shape_data)
elif type == 'square':
return area_square(shape_data)
else:
raise Exception("Unrecognized type")
print(area('circle', 5))
print(area('square', 5))
In OO you get that for free.
print(shape.area())
Whether shape is a Circle or a Square, shape.area() will work. You, the person using the shape, don't need to know anything about how it works. If you want to do more with your shapes, perhaps calculate the perimeter, add a perimeter method to your shape classes and now it's available wherever you have a shape.
As more shapes get added the procedural code gets more and more complex everywhere it needs to use shapes. The OO code remains exactly the same, instead you write more classes.
And that's the point of OO: hiding the details of how the work is done behind an interface. It doesn't matter to your code how it works so long as the result is the same.
Classes and OOP are IMHO always a good choice, by using them, you will be able to better organize and reuse your code, you can create new classes that derive from an existing class to extend its functionality (inheritance) or to change its behavior if you need it to (polymorphism) as well as to encapsulate the internals of your code so it becomes safer (no real encapsulation in Python, though).
In your specific case, for example, you are building a calculator, that uses a technique to calculate an intersection, if somebody else using your class wants to modify that behavior they could override the function (this is Polymorphism in action):
class PointCalculator:
def intersection(self, P1, P2, dist1, dist2):
# Your initial implementation
class FasterPointCalculator(PointCalculator):
def __init__(self):
super().__init__()
def intersection(self, P1, P2, dist1, dist2):
# New implementation
Or, you might extend the class in the future:
class BetterPointCalculator(PointCalculator):
def __init__(self):
super().__init__()
def distance(self, P1, P2):
# New function
You may need to initialize your class with some required data and you may not want users to be able to modify it, you could indicate encapsulation by naming your variables with an underscore:
class PointCalculator:
def __init__(self, p1, p2):
self._p1 = p1
self._p2 = p2
def do_something(self):
# Do something with your data
self._p1 + self._p2
As you have probably noticed, self is passed automatically when calling a function, it contains a reference to the current object (the instance of the class) so you can access anything declared in it like the variables _p1 and _p2 in the example above.
You can also create class methods (static methods) and then you don't have access to self, you should do this for methods that perform general calculations or any operation that doesn't need a specific instance, your intersection method could be a good candidate e.g.
class PointCalculator:
#staticmethod
def intersection(P1, P2, dist1, dist2):
# Return the result
Now you don't need an instance of PointCalculator, you can simply call PointCalculator.intersection(1, 2, 3, 4)
Another advantage of using classes could be memory optimization, Python will delete objects from memory when they go out of scope, so if you have a long script with a lot of data, they will not be released from memory until the script terminates.
Having said that, for small utility scripts that perform very specific tasks, for example, install an application, configure some service, run some OS administration task, etc... a simple script is totally fine and it is one of the reasons Python is so popular.

Python 2.7. Reading class instance property leads to error of type AttributeError: 'dict' object has no attribute. Why?

I have run into an issue when trying to wrap the boost library with python code. I have the following classes associated with a Python wrapper around the boost library.
class Edge2:
x1 = -1
y1 = -1
x2 = -1
y2 = -1
is_primary = False
site = -1
is_linear = False
def __init__(self, x1,y1,x2,y2, is_primary, site, is_linear):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
self.is_primary = is_primary
self.site = site
self.is_linear = is_linear
class VoronoiCell:
cellId = -1
segments = None
def __init__(self,cellId):
self.cellId = cellId
self.segments = []
As I am iterating through my C++ results, and convert the information I need into a python object of type Voronoi cell. And the list of segments is a collection of elements of type Edge2.
if(c_edges2[i-1].site == edge2.site):
print "Append segment to cell"
self.outputCells[-1].segments.append(edge2)
else:
print "Append segment to cell"
cell = VoronoiCell(edge2.site)
cell.segments.append(Edge2(x1,y1,x2,y2,edge2.isPrimary, edge2.site, edge2.isLinear))
self.outputCells.append(cell)
Yet, when I try to iterate through the results through an external python, my segments are marked as dictionaries, when I expect classes. And they are not even proper dictionaries since I can't even use the dictionary syntax to access the class members.
AttributeError: 'dict' object has no attribute 'x1'
cells = pv.GetCellSegments()
print "Cell Count: " + str(len(cells))
for c in cells:
print "Cell identifier: {0}".format(c.cellId)#Works fine
for s in c.segments:
print " " + str(s.x1)#Fails with error AttributeError: 'dict' object has no attribute 'x1'
I am a bit puzzled. Does anyone know why I get this error message?
Thanks Sven!
Not the exact answer but you led me on the right track... and you were close! I forgot how simple problems sometime are when you let them be for a while.
When I do self.outputCells[-1].segments.append(edge2) I am actually appending the mapped C struct, not the python class. I should have been calling my constructor like I do after wards
cell.segments.append(Edge2(x1,y1,x2,y2,edge2.isPrimary, edge2.site, edge2.isLinear))
Thanks again Sven for his comment!
Fabien

TypeError: 'numpy.ndarray' object is not callable on Euler's method LTE calculation

Before anything, sorry any sppeling, english issues, english is not my mother tongue.
I'm doing an assgment on Euler's Method to calculate ODEs, and in the calculatrion of the LTE(Local truncation error) I keep receiving this error:
TypeError: 'numpy.ndarray' object is not callable
I took a look at previous questions with the same subject, but I didn't find exactly what I was looking for. Below the code for the euler's method and the error calculation.
def euler(f,y0,a,b,h):
t,y = a,y0
vet_s = np.array([])
vet_err = np.array([])
while t <= b:
#print t , y
vet_s = np.append(vet_s, y)
t += h
y += h * f(t,y)
vet_err = np.append(vet_err, erro(yn, y, t)) # The problem is here
return vet_s, vet_err
def y(t, y):
return lbd*y
def yn(t):
return np.exp(-1*t)
def erro(yn, un, t):
erro_local = abs(yn(t) - un)
return erro_local
When I call the error calculation inside the vet_err assigment function I receive the error displayed above.
I think that it's a simple fix, but i can't find it myself.
The main call for the Euler's method is this:
h = 30./60.
lbd = -1.0
t = np.arange(0, 30, h)
sol = erro = np.array([])
sol, erro = euler(y, 1.0, 0.0, 30.0, h)
Is there any syntax, code issue? Also any pointer in order to improve the code would be of great help. Thanks.
Some issues I see in your code -
I am assumming you have defined the function named erro first and then afterwards you are also doing -
erro = np.array([])
This causes the name erro to point to a np.array , which is what is causing the issue you are having, you should use a different name here , maybe something like erro1 (or some other good meaningful name).
Then in the function - euler(f,y0,a,b,h) - you are defining variable with name - y . But there is also a y function outside, (This does not directly cause issues, since you passed the reference to function y as the first argument to this function) .
But I would advice against doing this (As you may encounter issues later on). Always use different meaningful names, I do not think there is a shortage of words/letters in English for use :) .
Also there is no need to do -
sol = erro = np.array([])
Since you reassign it to return value of euler() functio in next line, you do not need to even define them before that (unless you want to use them , which does not seem like the case).

python class property trouble

I have the following code:
class tile:
def __init__(self, value):
self.value = value
class map_2d:
def __init__(self, xsize, ysize):
self.dimx = xsize
self.dimy = ysize
self.canvas = [[tile(0)] * xsize for i in range(ysize)]
for yc in range(ysize):
for xc in range(xsize):
self.canvas[yc][xc].x = xc
self.canvas[yc][xc].y = yc #CHECKPOINT
#TEST:
mymap = map_2d(10, 10)
for line in mymap.canvas:
print ' | '.join('%d:%d' % (cell.x, cell.y) for cell in line)
I expect to have a map_2d instance with .canvas property, that is a 2d array of tile instances with x and y properties corresponding to the tile coordinates. Like 0:0, 1:0, 2:0, ...
Problem is, in the end ALL my tiles have an x property of xsize-1, 9 in the test above. It is utterly confusing, since at the moment marked by #CHECKPOINT everything is right and all tiles have their actual coordinates as x and y properties. Nothing is wrong with my visualization method either.
I would welcome any hints to help with this mystery. Any suggestions about achieving my goal (which is assigning coordinates to cells) more efficiently will be appreciated as well.
Moreover, if anyone reading this feels like "what the hell is this guy doing", I'd be grateful for any sound advice on how to deal with simple map generation, which is my ultimate goal in this case. I did all this to have a way of addressing tiles adjacent to another tile by coordinates, but my approach feels quite suboptimal.
This line doesn't do what you expect:
self.canvas = [[tile(0)] * xsize for i in range(size)]
Even though it seems to create a list of lists, you're actually getting lists that contain a reference to the same object tile(0). So when you modify canvas[0][0], you're also modifying canvas[0][1], canvas[0][2] and so on.
For example:
>>> [tile(0)] * 5
[<__main__.Tile instance at 0x10200eea8>, <__main__.Tile instance at 0x10200eea8>, <__main__.Tile instance at 0x10200eea8>, <__main__.Tile instance at 0x10200eea8>, <__main__.Tile instance at 0x10200eea8>]
Each object has the same memory address so it's a list of five elements which are actually all the same object.
You can solve this by explicitly creating new objects:
self.canvas = [[tile(0) for j in range(xsize)] for i in range(ysize)]

Categories

Resources