from math import pi
class Circle(object):
'Circle(x,y,r)'
def __init__(self, x=0, y=0, r=1):
self._r = r
self._x = x
self._y = y
def __repr__(self):
return 'Circle({},{},{})'.\
format(self.getx(), self.gety(),\
self.getr())
#silly, but has a point: str can be different from repr
def __str__(self):
return 'hello world'
def __contains__(self, item):
'point in circle'
px, py = item
return (self.getx() - px)**2 + \
(self.gety() - py)**2 < self.getr()**2
def getr(self):
'radius'
return self._r
def getx(self):
'x'
self._lst.append(self._x)
return self._x
def gety(self):
'y'
self._lst.append(self._y)
return self._y
def setr(self,r):
'set r'
self._r = r
def setx(self,x):
'set x'
self._x = x
def sety(self,y):
'set y'
self._y = y
def move(self,x,y):
self._x += x
self._y += y
def concentric(self, d):
d = self._list
def area(self):
'area of circle'
return (self.getr())**2*pi
def circumference(self):
'circumference of circle'
return 2*self.getr()*pi
My question is worded kinda awkwardly but what I am trying to do is check if 2 different circles have the same center (x,y). I think the easiest way to solve this would be to input the 2 points into a list but I am not sure how to compare the 2 lists as every time i try my code it adds everything to the same list
Add the following method to your Circle class.
def equal_center(self, other):
'check if another circle has same center'
return (self._x == other._x) & (self._y == other._y)
Usage
C1 = Circle(3, 5, 8)
C2 = Circle(3, 5, 10)
C3 = Circle(3, 2, 1)
C1.equal_center(C2) # True
C1.equal_center(C3) # False
I would recommend creating a function which takes two circle objects and returns if the coordinates are the same or not by comparing the x and y values of each object:
def same_center(circle_1, circle_2):
if circle_1.getx() == circle_2.getx() and circle_1.gety() == circle_2.gety():
return True
else:
return False
This solution is much easier than using lists and should be easy to implement.
If you have two instances of the class...
a = Circle(0,0,1)
b = Circle(0,0,1)
You could add them to a list of circles...
circles = [a,b]
And loop through the list, checking their values...
for i in circles:
for j in filter(lambda x : x != i, circles):
if i._x == j._x and i._y == j._y:
return True #two circles have same center
This should work for n instances of the class, though if its only two you want to check
if a._x == b._x and a._y == a._y:
return True
I create a class named point as following:
class point:
def __init__(self):
self.x = 0
self.y = 0
and create a list of point instances:
p1 = point()
p1.x = 1
p1.y = 1
p2 = point()
p2.x = 2
p2.y = 2
p_list = []
p_list.append(p1)
p_list.append(p2)
Now I'd like remove from the list the instance which x = 1 and y = 1, how can I do this?
I try to add a __cmp__ method for class point as following:
class point:
def __init__(self):
self.x = 0
self.y = 0
def __cmp__(self, p):
return self.x==p.x and self.y==p.y
But the following code does not work
r = point()
r.x = 1
r.y = 1
if r in p_list:
print('correct')
else:
print('wrong') # it will go here
p_list.remove(r) # it reports 'ValueError: list.remove(x): x not in list'
Your __cmp__ function is not correct. __cmp__ should return -1/0/+1 depending on whether the second element is smaller/equal/greater than self. So when your __cmp__ is called, it returns True if the elements are equal, which is then interpreted as 1, and thus "greater than". And if the elements are non-equal, it returns False, i.e. 0, which is interpreted as "equal").
For two-dimensional points, "greater than" and "smaller than" are not very clearly defined, anyway, so you can just replace your __cmp__ with __eq__ using the same implementation. Your point class should be:
class point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __eq__(self, p):
return self.x==p.x and self.y==p.y
When you're checking if r is in p_list you create a new instance of point, thus that instance of point will not be in the list (it has a different location in memory).
This function works to remove a point where x and y are 1:
for idx, p in enumerate(p_list):
if p.x==1 and p.y==1:
del p_list[idx]
I'm trying to practice OOP and recursion but I'm having some trouble. I think the recursive aspects of it are correct but the way I'm structuring class is wrong.
How it should work:
It should subtract 1 from 6, until x = 0. Each time adding 1 to index. When x is equal to 0 the function should return index.
Where I'm Getting Errors:
The following code says I have an error because divide accepts three arguements while I've only supplied two. But I thought that self wasn't really an argument. It was just something that had to be done in a class.
How do I make the below code work as intended?
class Division(object):
def __init__(self, x, y):
self.index = 0
self.x = x
self.y = y
def divide(self, x, y):
self.index += 1
if self.x <= 0:
return self.index
return divide(self.x-self.y, self.y)
print(Division.divide(6,1))
Edit (Revised Code):
Now I'm getting an error that divide is not defined?
class Division(object):
def __init__(self):
self.index = 0
def divide(self, x, y):
self.index += 1
if x <= 0:
return self.index
return divide(x-y, y)
print(Division().divide(6,1))
Second Edit:
I think I figured it out. I had to add create an instance of Division again on the divide methods recursive return. My output is wrong though. It's saying self.index is equal to one. Probably because when I create a new instance of the class the index is set to 0. How do I overcome this problem?
Final Code:
class Division(object):
def __init__(self):
self.index = 0
def divide(self, x, y):
self.index += 1
if x <= y:
return self.index
return self.divide(x-y, y)
print(Division().divide(6,1))
I don't understand why you want to have an object here... What does it models ? So here is a solution without object
def divide(a, b, q = 0):
if a < b:
return q
return divide(a-b, b, q+1)
I am trying to get values from my dictionary VALUES. My program creates combination of possible positions and gets the last position. Then I want to get the value. Everything works well here except indicated .get_value method. When I execute this code I receive:
AttributeError: 'Combination' object has no attribute 'get_value'
Theoretically it should be easy but I am new to OOP and I don't see what is wrong here.
X = ['A','B','C']
Y = ['1','2','3']
VALUES = {'A':10, 'B': 50, 'C':-20}
class Combination:
def __init__(self,x,y):
if (x in X) and (y in Y):
self.x = x
self.y = y
else:
print "WRONG!!"
def __repr__ (self):
return self.x+self.y
def get_x(self):
return self.x
def get_y(self):
return self.y
class Position:
def __init__(self):
self.xy = []
for i in X:
for j in Y:
self.xy.append(Combination(i,j))
def choose_last(self):
return self.xy.pop()
def __str__(self):
return "List contains: " + str(self.xy)
class Operation1:
def __init__(self):
self.operation1 = []
def __str__(self):
s = str(self.operation1)
return s
def get_value(self):
V = VALUES.get(self)
return V
pos = Position()
print pos
last_item = pos.choose_last()
print "Last item:", last_item, pos
last_value = last_item.get_value() # <---- Here is a problem
How can I obtain value of my position? Value is determined by the X value - this is A,B or C. In the dictionary I have a numeral value for the letter.
You are appending objects of Combination into xy of Position. When you say choose_last, it will return the last Combination object inserted into xy. And you are trying to invoke get_value method on a Combination object, which doesnt have that method. Thats why you are getting that error.
Always use new style classes.
I'm writing a class for a simple game of 4 in a row, but I'm running into a problem calling a method in the same class. Here's the whole class for the sake of completeness:
class Grid:
grid = None
# creates a new empty 10 x 10 grid
def reset():
Grid.grid = [[0] * 10 for i in range(10)]
# places an X or O
def place(player,x,y):
Grid.grid[x][y] = player
# returns the element in the grid
def getAt(x,y):
return Grid.grid[x][y]
# checks for wins in a certain direction
def checkLine(player,v,count,x,y):
x = x+v[0]
y = y+v[1]
if x < 0 or x > 9:
return
if y < 0 or y > 9:
return
if Grid.grid[x][y] == p:
count = count+1
if count == 4:
return True
checkLine(player,v,count,x,y)
return False
# returns the number of the player that won
def check():
i = 'i'
for x in range(0,10):
for y in range(0,10):
if Grid.grid[x][y] > 0:
p = Grid.grid[x][y]
f = checkLine(p,0,array(i,[1,0]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[0,1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[1,1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,0]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[0,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[1,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,1]),x,y)
if f:
return p
return 0
reset = staticmethod(reset)
place = staticmethod(place)
getAt = staticmethod(getAt)
check = staticmethod(check)
checkLine = staticmethod(checkLine)
I'm trying to call checkLine() from check(), but I get the error "NameError: global name 'checkLine' is not defined". When I call Grid.checkLine() instead, I get "TypeError: 'module' object is not callable"
How do I call checkLine()?
EDIT:
#beer_monk
class Grid(object):
grid = None
# creates a new empty 10 x 10 grid
def reset(self):
Grid.grid = [[0] * 10 for i in range(10)]
# places an X or O
def place(self,player,x,y):
Grid.grid[x][y] = player
# returns the element in the grid
def getAt(self,x,y):
return Grid.grid[x][y]
# checks for wins in a certain direction
def checkLine(self,player,v,count,x,y):
x = x+v[0]
y = y+v[1]
if x < 0 or x > 9:
return
if y < 0 or y > 9:
return
if Grid.grid[x][y] == p:
count = count+1
if count == 4:
return True
checkLine(self,player,v,count,x,y)
return False
# returns the number of the player that won
def check(self):
i = 'i'
for x in range(0,10):
for y in range(0,10):
if Grid.grid[x][y] > 0:
p = Grid.grid[x][y]
for vx in range(-1,2):
for vy in range(-1,2):
f = self.checkLine(p,0,array(i,[vx,vy]),x,y)
if f:
return p
return 0
reset = staticmethod(reset)
place = staticmethod(place)
getAt = staticmethod(getAt)
check = staticmethod(check)
checkLine = staticmethod(checkLine)
Get rid of the class. Use plain functions and module level variable for grid.
The class is not helping you in any way.
PS. If you really want to call checkline from within the class, you'd call Grid.checkline. For example:
class Foo:
#staticmethod
def test():
print('Hi')
#staticmethod
def test2():
Foo.test()
Foo.test2()
prints
Hi
Syntax:
class_Name.function_Name(self)
Example:
Turn.checkHoriz(self)
A reworked example (hopefully showing a better use of classes!)
import itertools
try:
rng = xrange # Python 2.x
except NameError:
rng = range # Python 3.x
class Turn(object):
def __init__(self, players):
self.players = itertools.cycle(players)
self.next()
def __call__(self):
return self.now
def next(self):
self.now = self.players.next()
class Grid(object):
EMPTY = ' '
WIDTH = 10
HEIGHT = 10
WINLENGTH = 4
def __init__(self, debug=False):
self.debug = debug
self.grid = [Grid.EMPTY*Grid.WIDTH for i in rng(Grid.HEIGHT)]
self.player = Turn(['X','O'])
def set(self, x, y):
if self.grid[y][x]==Grid.EMPTY:
t = self.grid[y]
self.grid[y] = t[:x] + self.player() + t[x+1:]
self.player.next()
else:
raise ValueError('({0},{1}) is already taken'.format(x,y))
def get(self, x, y):
return self.grid[y][x]
def __str__(self):
corner = '+'
hor = '='
ver = '|'
res = [corner + hor*Grid.WIDTH + corner]
for row in self.grid[::-1]:
res.append(ver + row + ver)
res.append(corner + hor*Grid.WIDTH + corner)
return '\n'.join(res)
def _check(self, s):
if self.debug: print("Check '{0}'".format(s))
# Exercise left to you!
# See if a winning string exists in s
# If so, return winning player char; else False
return False
def _checkVert(self):
if self.debug: print("Check verticals")
for x in rng(Grid.WIDTH):
winner = self._check([self.get(x,y) for y in rng(Grid.HEIGHT)])
if winner:
return winner
return False
def _checkHoriz(self):
if self.debug: print("Check horizontals")
for y in rng(Grid.HEIGHT):
winner = self._check([self.get(x,y) for x in rng(Grid.WIDTH)])
if winner:
return winner
return False
def _checkUpdiag(self):
if self.debug: print("Check up-diagonals")
for y in rng(Grid.HEIGHT-Grid.WINLENGTH+1):
winner = self._check([self.get(d,y+d) for d in rng(min(Grid.HEIGHT-y, Grid.WIDTH))])
if winner:
return winner
for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
if winner:
return winner
return False
def _checkDowndiag(self):
if self.debug: print("Check down-diagonals")
for y in rng(Grid.WINLENGTH-1, Grid.HEIGHT):
winner = self._check([self.get(d,y-d) for d in rng(min(y+1, Grid.WIDTH))])
if winner:
return winner
for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
if winner:
return winner
return False
def isWin(self):
"Return winning player or False"
return self._checkVert() or self._checkHoriz() or self._checkUpdiag() or self._checkDowndiag()
def test():
g = Grid()
for o in rng(Grid.WIDTH-1):
g.set(0,o)
g.set(Grid.WIDTH-1-o,0)
g.set(Grid.WIDTH-1,Grid.HEIGHT-1-o)
g.set(o,Grid.HEIGHT-1)
print(g)
return g
g = test()
print g.isWin()
Unlike java or c++, in python all class methods must accept the class instance as the first variable. In pretty much every single python code ive seen, the object is referred to as self. For example:
def reset(self):
self.grid = [[0] * 10 for i in range(10)]
See http://docs.python.org/tutorial/classes.html
Note that in other languages, the translation is made automatically
There are multiple problems in your class definition. You have not defined array which you are using in your code. Also in the checkLine call you are sending a int, and in its definition you are trying to subscript it. Leaving those aside, I hope you realize that you are using staticmethods for all your class methods here. In that case, whenever you are caling your methods within your class, you still need to call them via your class's class object. So, within your class, when you are calling checkLine, call it is as Grid.checkLine That should resolve your NameError problem.
Also, it looks like there is some problem with your module imports. You might have imported a Module by name Grid and you have having a class called Grid here too. That Python is thinking that you are calling your imported modules Grid method,which is not callable. (I think,there is not a full-picture available here to see why the TypeError is resulting)
The best way to resolve the problem, use Classes as they are best used, namely create objects and call methods on those objects. Also use proper namespaces. And for all these you may start with some good introductory material, like Python tutorial.
Instead of operating on an object, you are actually modifying the class itself. Python lets you do that, but it's not really what classes are for. So you run into a couple problems
-You will never be able to make multiple Grids this way
the Grid can't refer back to itself and e.g. call checkLine
After your grid definition, try instantiating your grid and calling methods on it like this
aGrid = Grid()
...
aGrid.checkLine()
To do that you, you first need to modify all of the method definitions to take "self" as your first variable and in check, call self.checkLine()
def check(self):
...
self.checkLine()
...
Also, your repeated checking cries out for a FOR loop. You don't need to write out the cases.
Java programmer as well here, here is how I got it to call an internal method:
class Foo:
variable = 0
def test(self):
self.variable = 'Hi'
print(self.variable)
def test2(self):
Foo.test(self)
tmp = Foo()
tmp.test2()