Can't print a self-made matrix outside of its module - python

I have 2 modules in my project:
1- Ant.py
from threading import Thread
from Ant_farm import Ant_farm
ant_farm = Ant_farm(20, 20)
class Ant(Thread):
def __init__(self, x, y):
global ant_farm
Thread.__init__(self)
self.x = x
self.y = y
ant_farm.matrix[self.x][self.y] = True # At this point the arguments has initialized?
def move(self, x, y):
ant_farm.matrix[self.x][self.y] = False
self.x = x
self.y = y
ant_farm.matrix[self.x][self.y] = True # At this point the value has changed?
def run(self):
while True:
ant_farm.move_ant(self)
t = Ant(0, 0)
print(ant_farm[0][0])
t.move(1, 0)
2- Ant_farm.py
from threading import Condition
def matrix(x, y):
return [[False for j in range(y)] for i in range(x)]
class Ant_farm():
def __init__(self, x, y):
self.c = Condition() # I don't know if I have to put "self" before
self.matrix = matrix(x, y)
def move_ant(self, ant):
new_pos = {0: tuple(x0, y0 - 1),
1: tuple(x0 + 1, y0),
2: tuple(x0, y0 + 1),
3: tuple(x0 - 1, y0)}
x0, y0 = ant.x, ant.y
x1, y1 = new_pos[random.randrange(0, 4)]
with self.c:
try:
while self.matrix[x1][y1]:
self.c.wait()
self.matrix[x0][y0] = False
ant.move(x1, y1)
# It's not end and I have to review
except Exception: # Wich exceptions can appear?
pass
def __str__(self):
pass
In both omit the comments.
When I execute the Ant module, raises this error:
AttributeError: Ant_farm instance has no attribute '__getitem__'
in the line 27 (print(ant_farm[0][0])). Why does this?

As the error message says, you did not define what ant_farm[i] is (the function __getitem__).
You probably want something like this in your Ant_farm class:
def __getitem__(i):
return self.matrix[i]

Related

How to create a method that can be called by any instance that uses information from the instances?

Suppose I want to create a class called "Point". Suppose I only ever plan on making two points because that's important. I want to create a method that can be called by either instance or "point" that gives the distance between the two points. How would I go about doing that?
This is what my code looks like.
import math
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self): # Just filler code
return math.sqrt((self_2.x - self_1.x)**2+(self_2.y - self_1.y)**2) # Just filler code
point_1 = Point(0,0)
point_2 = Point(3,4)
print(point_1.distance()) # Should return 5.0
print(point_2.distance()) # Should return 5.0
Obviously I know what I made here doesn't work, but I'm just trying to give an idea of what the print statement should do. How would I go about doing this?
import math
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self,other):
return math.sqrt((self.x - other.x)**2+(self.y - other.y)**2)
point_1 = Point(0,0)
point_2 = Point(3,4)
print(point_1.distance(point_2)) # Should return 5.0
print(point_2.distance(point_1)) # Should return 5.0
You should use a second class that specifically represents two points.
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def distance_to(self, other):
return abs(complex(self.x, self.y) - complex(other.x, other.y))
class PointPair:
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def distance(self):
return self.p1.distnace_to(self.ps2)
point_1 = Point(0,0)
point_2 = Point(3,4)
pair = PointPair(point_1, point_2)
print(pair.distance()
or a regular function
def distance(p1, p2):
return abs(complex(p1.x, p1.y) - complex(p2.x, p2.y))
print(distance(point_1, point_2))

how can i swap these two variable

i have to swap the two variable using setter and getter but its giving the same exact answer
class Thing:
def __init__(self, thing1=0, thing2=0):
self._thing1 = thing1
self._thing2 = thing2
def get_assignThings(self) :
return self._thing1, self._thing2
def set_assignThings(self, x, y):
self._thing1 = x
x = y
self._thing2 = y
obj = Thing()
obj.set_assignThings(2, 3)
print(obj.get_assignThings())
try this,
def set_assignThings(self, x, y):
self._thing1, self._thing2 = y,x
Change the order how they are returned or set:
ie here : return self._thing2, self._thing1
or self._thing1 = y
self._thing2 = x
Full code:
class Thing:
def __init__(self, thing1=2, thing2=3):
self._thing1 = thing1
self._thing2 = thing2
def get_assignThings(self):
return self._thing2, self._thing1
def set_assignThings(self, x, y):
self._thing1 = x
self._thing2 = y
obj = Thing()
obj.set_assignThings(2, 3)
print(obj.get_assignThings())
Out:
(3, 2)

finding distance between two points in python, passing inputs via two different objects

I have to write a code to find the different between two point by passing value via two objects as below.
But I am getting TypeError: init() missing 3 required positional arguments: 'x', 'y', and 'z'
class Point:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return '(point: {},{},{})'.format(self.x, self.y, self.z)
def distance(self, other):
return sqrt( (self.x-other.x)**2 + (self.y-other.y)**2 + (self.z -other.z)**2 )
p = Point()
p1 = Point(12, 3, 4)
p2 = Point(4, 5, 6)
p3 = Point(-2, -1, 4)
print(p.distance(p1,p3))
The problem comes from this line:
p = Point()
When you defined you class, you specified it has to be passed 3 parameters for it to be initialised (def __init__(self, x, y,z)).
If you still want to be able to create this Point object without having to pass those 3 parameters, you can make them optional like this :
def __init__(self, x=0, y=0, z=0):
self.x = x
self.y = y
self.z = z
This way, if you were to not specify these parameters (as you did), it will create a point with coordinates {0, 0, 0} by default.
You are not passing the required 3 arguments for p = Point()
fixed your errors
from math import sqrt
class Point:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return '(point: {},{},{})'.format(self.x, self.y, self.z)
def distance(self, other):
return sqrt( (self.x-other.x)**2 + (self.y-other.y)**2 + (self.z -other.z)**2 )
# p = Point() # not required
p1 = Point(12, 3, 4)
p2 = Point(4, 5, 6)
p3 = Point(-2, -1, 4)
print(p1.distance(p3)) # use this to find distance between p1 and any other point
# or use this
print(Point.distance(p1,p3))
class Point:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return '(point: {},{},{})'.format(self.x, self.y, self.z)
def distance(self, other):
return math.sqrt( (self.x-other.x)**2 + (self.y-other.y)**2 + (self.z -other.z)**2 )
p1 = Point(12, 3, 4)
p2 = Point(4, 5, 6)
p3 = Point(-2, -1, 4)
print(Point.distance(p1,p3))
It works like this.You should not define a P point seperate than the other three points. Every point is a seperate instance. But when you try to use the function just call the class.

'int' object has no attribute 'x'

I'm trying to make a program to add vectors using __add __:
class vects:
def __init__(self,x,y):
self.x = x
self.y = y
def __add__(self, vect):
total_x = self.x + vect.x
total_y = self.y + vect.y
return vects(total_x, total_y)
plusv1 = vects.__add__(2,5)
plusv2 = vects.__add__(1,7)
totalplus = plusv1 + plusv2
The error produced is as follows:
line 12, in <module> plusv1 = vects.__add__(2,5)
line 7, in __add__ total_x = self.x + vect.x
AttributeError: 'int' object has no attribute 'x'
You don't use __add__ like that! :-) __add__ will get implicitly invoked when + is used on an instance of the Vects class.
So, what you should first do is initialize two vector instances:
v1 = Vects(2, 5)
v2 = Vects(1, 7)
and then add them:
totalplus = v1 + v2
If you add a nice __str__ to get a nice representation of your new vector:
class Vects:
def __init__(self,x,y):
self.x = x
self.y = y
def __add__(self, vect):
total_x = self.x + vect.x
total_y = self.y + vect.y
return Vects(total_x, total_y)
def __str__(self):
return "Vector({}, {})".format(self.x, self.y)
You can get a view of totalplus by printing it:
print(totalplus)
Vector(3, 12)

python randomwalk not walking

my professor has given me this code and the only part im suppose to do is the TODO area. i am rather new to python still and have never touched on this type of project so i am rather confused. all this project is for is to get the plotted graph image.
import math, random, pylab
class Location(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def move(self, xc, yc):
return Location(self.x+float(xc), self.y+float(yc))
def getCoords(self):
return self.x, self.y
def getDist(self, other):
ox, oy = other.getCoords()
xDist = self.x - ox
yDist = self.y - oy
return math.sqrt(xDist**2 + yDist**2)
class CompassPt(object):
possibles = ('N', 'S', 'E', 'W')
def __init__(self, pt):
if pt in self.possibles: self.pt = pt
else: raise ValueError('in CompassPt.__init__')
def move(self, dist):
if self.pt == 'N': return (0, dist)
elif self.pt == 'S': return (0, -dist)
elif self.pt == 'E': return (dist, 0)
elif self.pt == 'W': return (-dist, 0)
else: raise ValueError('in CompassPt.move')
class Field(object):
def __init__(self, drunk, loc):
self.drunk = drunk
self.loc = loc
def move(self, cp, dist):
oldLoc = self.loc
xc, yc = cp.move(dist)
self.loc = oldLoc.move(xc, yc)
def getLoc(self):
return self.loc
def getDrunk(self):
return self.drunk
class Drunk(object):
def __init__(self, name):
self.name = name
def move(self, field, time = 1):
if field.getDrunk() != self:
raise ValueError('Drunk.move called with drunk not in field')
for i in range(time):
pt = CompassPt(random.choice(CompassPt.possibles))
field.move(pt, 1)
here is the part that i need to do and have tried to do. so far my graph does not move lol. i get a dot in the middle of the graph, unless its randomly walking in one location if that's possible lol.
# TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
def performTrial(time, f):
start = f.getLoc()
# TODO
distances = [0.0]
for t in range(1, time + 1):
# TODO
f.getDrunk().move(f)
newLoc = f.getLoc()
distance = newLoc.getDist(start)
distances.append(distance)
xcoords, ycoords = distances[::2], distances[1::2]
return xcoords,ycoords
# END OF TODOEND OF TODO END OF TODO END OF TODO END OF TODO
the rest here is also provided by the professor
drunk = Drunk('Homer Simpson')
for i in range(1):
f = Field(drunk, Location(0, 0))
coords = performTrial(500, f)
print(coords)
pylab.plot(coords[0],coords[1],marker='^',linestyle=':',color='b')
pylab.title('Homer\'s Random Walk')
pylab.xlabel('Time')
pylab.ylabel('Distance from Origin')
pylab.show()
update: fixed the coordinates but now i get an error:
in _xy_from_xy(self, x, y)
235 y = np.atleast_1d(y)
236 if x.shape[0] != y.shape[0]:
--> 237 raise ValueError("x and y must have same first dimension")
238 if x.ndim > 2 or y.ndim > 2:
239 raise ValueError("x and y can be no greater than 2-D")
ValueError: x and y must have same first dimension
def move(self, xc, yc):
return Location(self.x+float(xc), self.y+float(yc))
this does not move anything, it just returns new coordinates. Also casting xc and yc to a float should not be needed.
If this function is intended to move the Location, you have to add this:
def move(self, xc, yc):
self.x += xc
self.y += yc
return Location(self.x, self.y)

Categories