Storing and checking a boolean in a python class - python

So I was trying to create an object which basically has a constructor that takes two coordinates, xcoord and ycoord. I further created methods which shift the coordinates and I have to check if the point is valid or not(criteria for validity is if the coordinates are out of a specified range it should return False else True).
Problem:
My class only returns the validity for the initial points, not the shifted points.
What do I need to correct my code?
Code:
class Point:
MaxScreenSize=10
def __init__(self,x,y):
self.xcoord=x
self.ycoord=y
if 0>self.xcoord or self.xcoord>Point.MaxScreenSize or 0>self.ycoord or self.ycoord>Point.MaxScreenSize:
Point.isValidPt=False
else:
Point.isValidPt=True
def translateX(self,shiftX):
self.xcoord=self.xcoord+shiftX
def translateY(self,shiftY):
self.ycoord=self.ycoord+shiftY
Test Code:
I tried my code and it only returns the isValidFunction variable for my initial points (gives me True instead of False for following code)
p=Point(9,2)
p.translateX(20)
p.translateY(10)
p.isValidPt

Your isValidPt is only calculated when the class is instantiated. Instead try something like:
Code:
class Point:
MaxScreenSize = 10
def __init__(self, x, y):
self.xcoord = x
self.ycoord = y
def translateX(self, shiftX):
self.xcoord = self.xcoord + shiftX
def translateY(self, shiftY):
self.ycoord = self.ycoord + shiftY
#property
def isValidPt(self):
return (
0 <= self.xcoord <= Point.MaxScreenSize and
0 <= self.ycoord <= Point.MaxScreenSize
)
Test Code:
p = Point(9, 2)
p.translateX(20)
p.translateY(10)
print(p.isValidPt)
Result:
False

Constructor is used basically for initiate the values. In your case the constructor checks the initial value and set the validate flag. ie, isValidPt.
It will be True for the scope of p object you created. So you have to create a validate function and call the validate function on both init and shift functions.
Check the following
class Point:
MaxScreenSize=10
def __init__(self,x,y):
self.xcoord=x
self.ycoord=y
self.validate()
def validate(self):
if 0>self.xcoord or self.xcoord>Point.MaxScreenSize or 0>self.ycoord or self.ycoord>Point.MaxScreenSize:
Point.isValidPt=False
else:
Point.isValidPt=True
def translateX(self,shiftX):
self.xcoord=self.xcoord+shiftX
self.validate()
def translateY(self,shiftY):
self.ycoord=self.ycoord+shiftY
self.validate()
in the above code each time the validation will perform and update the values
of isValidPt.

Related

Overloading addition function and the result creates a new type of class

I need to overload the addition function so that it takes in the first point and the end point as the left and right side of the equation and outputs the equation. This is what my code looks right now. I'm not sure how to involve the line class?
import math
class Point:
'''Class that creates points. Attributes: Eastings and Northings'''
def __init__(self,x,y):
self.eastings = x
self.northings = y
def getCoords(self):
self.coords = (self.eastings,self.northings)
return self.coords
def setCoords(self,other_x,other_y):
self.eastings = float(other_x)
self.northings = float(other_y)
def __str__(self):
return f"{self.eastings},{self.northings}"
def __add__(self,new_point):
pass
#creates a line (new class)
class Line(Point):
'''Class that creates line object based on two points'''
def __init__(self,start,end):
self.start = start #Type:Point (x1,y1)
self.end = end #Type:Point (x2,y2)
self.latitude = abs(self.end.eastings - self.start.eastings)
self.departure = abs(self.end.northings - self.start.northings)
self.distance = math.sqrt((self.latitude)**2 + (self.departure)**2)
self.azimuth = math.degrees(math.atan2(self.departure,self.latitude))
def __getitem__(self,key):
if key == 0:
ans = self.start
elif key == 1:
ans = self.end
else:
print("invalid index")
return ans
#test code
a = Point(0,0)
b = Point(1,1)
c = Point(1,0.5)
line1 = a+b
print((type(line1))
The test code is supposed to print out the type as class line.
There's nothing that says the __add__() method has to return a the same type as the instance — which means you could this:
class Point:
...
def __add__(self, other):
if isinstance(other, Point):
return Line(self, other) # Line from this Point to the other.
else:
raise TypeError(f"Can't add a non-Point to a Point}")
Be careful doing this however, because the Line class will inherit the method (so you probably need to modify its version of it).
Add a self.getCoords() call to your Point.__init__() method.
Add return Line(self, new_point) to your Point.__add__() method.
Testing:
a = Point(0,0)
b = Point(1,1)
c = Point(1,0.5)
line1 = a+b
print(type(line1)) # I have removed a round bracket on the left
Output: <class '__main__.Line'>
In case you want to run a block of code, where a function/method has not one line in it, you have to add a pass to it. Otherwise you will get an error, because the structure requires it. Or you comment the function declaration out.

python - Trouble calculating manhatan distance, TypeError

So I have a school project where we need to make a few classes for a GPS system. I'm having an issue figuring out the function dist(self,other): shown at the bottom of my code. Other definitions later in the project heavily rely on it, but i'm stumped at this point. The dist function calculates the Manhattan distance (x1-x2)+(y1-y2) of a location defined by instance variables x and y, and another location other which is given as a Tuple
class GPS_Location:
def __init__(self,x,y):
self.x=x
self.y=y
def __str__(self):
return '(%s,%s)' % (self.x,self.y)
def __repr__(self):
return 'GPS_Location(%s,%s)' % (self.x,self.y)
def __eq__(self,other):
self.other = other
if (self.x,self.y) == other:
return True
else:
return False
def dist(self,other):
self.other = other
return abs(self.x - (other[0])) + abs(self.y - (other[1])) #TypeError
When testing the code, I keep getting "TypeError: 'GPS_Location' object is not iterable". I have tried so many tweaks, and I just can't figure out what i'm doing wrong.
Any help would be greatly appreciated!
Ensure that line 8 is indented by 4 spaces like the rest of the methods.
There doesn't seem to be any reason to assign other to self.other in __eq__() and dist().
The only other issue you might be having could be related to how you are calling these methods (you mentioned that the argument other is just a tuple), this works:
x = GPS_Location(1, 1)
x == (1, 1)
# True
x == (2, 2)
# False
x.dist((1, 1))
# 0
x.dist((2, 2))
# 2
If you in fact need to pass a second GPS_Location as the other argument to dist, then it needs to be updated as follows:
def dist(self, other):
return abs(self.x - other.x) + abs(self.y - other.y)
Call it like so:
x = GPS_Location(1, 1)
y = GPS_Location(2, 2)
x.dist(y)
# 2

Python Class method to ID intersection of Point w Rectangle uwing set() and Intersection() not working

..trying to define a method within my Point Class that checks interaction with objects of my Rectangle class on interior or boundary using type based dispatch. I tried the code below, but yields: AttributeError: 'set' object has no attribute 'intersects'.
Also, seeking a way to clearly set what intersects at boundary vs. interior. Please advise.
class Point(object):
def __init__(self, x, y, height=0):
self.x = float(x)
self.y = float(y)
self.height = float(height)
def intersects(self, other):
if isinstance(other, Point):
s1=set([self.x, self.y])
s2=set([other.x, other.y])
if s1.intersection(s2):
return True
else:
return False
elif isinstance(other, Rectangle):
s1=set([self.x, self.y])
s2=set(other.pt_ll, other.pt_ur)
if s1.intersection(s2):
return True
else:
return False
class Rectangle(object):
def __init__(self, pt_ll, pt_ur):
"""Constructor.
Takes the lower left and upper right point defining the Rectangle.
"""
self.ll = pt_ll
self.lr = Point(pt_ur.x, pt_ll.y)
self.ur = pt_ur
self.ul = Point(pt_ll.x, pt_ur.y)
these are my calling statements:
pt0 = (.5, .5)
r=Rectangle(Point(0, 0),Point(10, 10))
s1 = set([pt0])
s2 = set([r])
print s1.intersects(s2)
it would be intersection() s1.intersection(s2), you are using a set not a Point object:
s1 = set([pt0]) # <- creates a python set
To use your intersects method you need Point objects:
p = Point(3,5) # <- creates a Point object that has intersects method
p2 = Point(3,5)
print(p.intersects(p2))
So using your example, you need to access the Point objects using the attributes of the Rectangle class:
r = Rectangle(Point(0, 0),Point(10, 10))
print(r.lr.intersects(r.ul)) # <- the Rectangle attributes lr and ul are Point objects because you passed in Point's when you initialised the instance r
You can simplify the assignments in Rectangle:
class Rectangle(object):
def __init__(self, pt_ll, pt_ur):
"""Constructor.
Takes the lower left and upper right point defining the Rectangle.
"""
self.lr = Point(pt_ur.x, pt_ll.y)
self.ul = Point(pt_ll.x, pt_ur.y)
You can also just use set literals:
s1 = {self.x, self.y}
s2 = {other.x, other.y}

How to call method of other object in Python?

I am new in python, and I have small problem, I have two classes, and it wrotes this : set_gyro_angle() takes exactly 1 argument (2 given) how can I call set_gyro_angle() method from Machine method?
class Gyro(object):
"""gyroskop senzor"""
def __init__(self,gyro_start_angle = 0):
self.gyro_angle = 0
def get_gyro_angle():
return self.gyro_angle
def set_gyro_angle(angle):
self.gyro_angle = angle
return 0
class Maschine(object):
def __init__(self, state = "normal",length = 10,width = 15):
self.length = length
self.width = width
self.gyro = Gyro()
def setPoint(self,alpha):
self.gyro.set_gyro_angle(alpha)
return 0
Main:
maschine = Maschine()
maschine.setPoint()
If you want to create an instance method, you need to add an extra argument that will be a pointer to your instance. Usually it's self:
class Gyro(object):
"""gyroskop senzor"""
def __init__(self,gyro_start_angle = 0):
self.gyro_angle = 0
def get_gyro_angle(self):
return self.gyro_angle
def set_gyro_angle(self, angle):
self.gyro_angle = angle
return 0
And i think you want setPoint to be like this:
def setPoint(self, alpha):
self.gyro.set_gyro_angle(alpha)
All of your instance methods should have another parameter, self, before the others; this is the instance itself, and is passed automatically:
def set_gyro_angle(self, angle):
Alternatively, skip the setter:
self.gyro.gyro_angle = alpha
Machine.gyro.set_gyro_angle(45)
However you need to fix your code by adding the self parameter as the first parameter of your class methods.

issues with calling a superclass's method and adding the returned value to an array

When I try to enter the code below, I get [None, None] printed on the console rather than the expected [3, 3] and was wondering what would help to fix this.
class Blah(object):
def track(self,dot):
self.dot = dot
class Second(Blah):
def __init__(self,arg):
self.blocky = []
x = 0
while x < 2:
self.blocky.append(Blah.track(self,arg))
x += 1
bleh = Second(3)
print bleh.blocky
Among other more minor issues, your track method doesn't return anything, so you're passing the returned value of a function that returns nothing (None in other words) into that list.
The following worked for me:
class Blah(object):
def track(self, dot):
self.dot = dot
return self.dot
class Second(Blah):
def __init__(self, arg):
self.blocky = []
x = 0
while x < 2:
self.blocky.append(self.track(arg))
x += 1
Blah.track doesn't have a return statement, so it returns None.
You could fix this by doing:
class Blah(object):
def track(self, dot):
self.dot = dot
return dot
Also, you're calling Blah.track(self, dot) when you could just be calling self.track(dot), since self is a Second, which is a subclass of Blah.
That might look like this:
class Second(Blah):
def __init__(self,arg):
self.blocky = []
x = 0
while x < 2:
self.blocky.append(self.track(arg))
x += 1
The track method isn't returning anything. Perhaps you meant this?
def track(self, dot):
self.dot = dot
return dot
Also, since Second inherits from Blah you can replace
Blah.track(self, arg)
with
self.track(arg)

Categories

Resources