Union Find algorithm in Python - python-2.7

I am trying to implement Union Find algorithm in python and I don't understand what's wrong with my code as everything seems to be in the right place.
Please help in this regard. Below is my code
class UnionFind:
def __init__(self,v):
self.parent = [-1 for i in range(v)]
self.lis=[]
def addEdge(self,i,j):
self.lis.append([i,j])
def findParent(self,i):
if self.parent[i] == -1:
return i
else :
self.findParent(self.parent[i])
def union(self,i,j):
self.parent[i]=j
def printResult(self):
print self.lis
def isBool(self):
for lisIter in self.lis:
x=self.findParent(lisIter[0])
y=self.findParent(lisIter[1])
if(x==y):
return True
self.union(x,y)
return False
uf = UnionFind(3)
uf.addEdge(0,1)
uf.addEdge(1,2)
uf.addEdge(2,0)
if uf.isBool():
print "The graph is cyclic"
else:
print "The graph is not cyclic"

Finally I got that little logic which I missed in the my code. I need to add the return statement in the else block of findParent method or else the returned value will be discarded and a none value will get returned. Uff!
def findParent(self,i):
if self.parent[i] == -1:
return i
else :
return self.findParent(self.parent[i])

Related

How do I change class value Python 3?

I'm trying to use OOP to make tic tac toe, but whenever I win/draw a game is just keeps running and won't cancel out the game?
The error seems to be something to do with my while loop not wanted to break out.
Maybe this is a really stupid and obvious error in my code, but I've only been learning Python for 3 months so unfortunately I'm not the best right now.
# The
In the p_v_p() function it checks while both players have won, could this be causing the problem?
The problem isn't that the class variable isn't changed, it's that you're not checking it frequently enough. FYI, you called it a class variable in your question, but has_won is actually an instance variable. There are two problems that need to be corrected.
Your diagonal win conditions are incorrect:
diagnol_win = [[1,4,9],[3,4,7]]
This should be diagnol_win = [[1,5,9],[3,5,7]]
As #rob-py mentioned, you need to check has_won after each move. The following should fix the issue.
def p_v_p():
print("\nWelcome to Player vs Player Game Mode\
Player 1 you are 'X' , Player 2 you are 'O'!")
while True:
print("\nPlayer Ones Turn!")
player1.move()
if player1.has_won:
return
print("\nPlayer Twos Turn!")
player2.move()
if player2.has_won:
return
Since you're new to python, I thought I could offer some suggestions. I think you're off to a good start, but I would suggest defining three main classes: Player, Board, and Game. Here's a (at least mostly) working example. Keep in mind that this was a quick edit, so there's still plenty of room for more improvement.
class Board():
class PositionError(RuntimeError):
pass
class UpdateError(RuntimeError):
pass
def __init__(self):
self.markers = [' '] * 9
def print(self):
print()
print(self.markers[:3])
print(self.markers[3:6])
print(self.markers[6:])
def update(self, position, marker):
if position < 1 or position > 9:
raise self.PositionError()
if self.markers[position - 1] != ' ':
raise self.UpdateError()
self.markers[position - 1] = marker
def __getitem__(self, index):
return self.markers[index]
def __setitem__(self, index, value):
self.update(index + 1, value)
class Player:
def __init__(self, counter):
self.has_won = False
self.counter = counter
def move(self, board):
while True:
try:
player_input = int(input("Where you you like to place your counter? (1-9): "))
board.update(player_input, self.counter)
return
except ValueError:
print("\nInvalid Input not an number,Try Again.")
continue
except Board.PositionError:
print("\nPlease enter a position between 1-9")
continue
except Board.UpdateError:
print("\nPosition {} is already taken".format(player_input))
continue
class Computer(Player):
def move(self):
raise NotImplementedError()
class Game:
DRAW = 'D'
INCOMPLETE = 'I'
HORIZONTAL_WIN = [[1,2,3],[4,5,6],[7,8,9]]
VERTICAL_WIN = [[1,4,7],[2,5,8],[3,6,9]]
DIAGONAL_WIN = [[1,5,9],[3,5,7]]
def __init__(self, player_1, player_2):
self.player_1 = player_1
self.player_2 = player_2
self.board = Board()
def reset(self):
self.board = Board()
def play(self):
index = 0
players = [self.player_1, self.player_2]
while True:
players[index].move(self.board)
self.board.print()
state = self.check_state()
if state == players[index].counter:
print("\nPlayer with counter {} has won!".format(players[index].counter))
break
if state == self.DRAW:
print("\nTHIS GAME IS A DRAW! NOBODY WINS!")
break
index = (index + 1) % len(players)
self.reset()
return
def check_state(self):
if len([c for c in self.board.markers if c in ['O', 'X']]) >= 9:
return self.DRAW
for x, y, z in self.HORIZONTAL_WIN:
if self.board[x-1] == self.board[y-1] == self.board[z-1] != " ":
return self.board[x-1]
for x, y, z in self.VERTICAL_WIN:
if self.board[x-1] == self.board[y-1] == self.board[z-1] != " ":
return self.board[x-1]
for x, y, z in self.DIAGONAL_WIN:
if self.board[x-1] == self.board[y-1] == self.board[z-1] != " ":
return self.board[x-1]
return self.INCOMPLETE
def p_v_p():
print("\nWelcome to Player vs Player Game Mode")
print("Player 1 you are 'X' , Player 2 you are 'O'!")
return Game(Player('X'), Player('O'))
def p_v_c():
print("\nWelcome to Player vs Computer")
print("Human player you are Player 1 and counter 'X'. "
"The Computer is player 2 and counter 'O'")
return Game(Player('X'), Computer('0'))
def game_selection():
while True:
game_mode = input("""\nEnter what game mode you want to play:
- Player Vs Player (PvP)
- Player vs Computer (PvC)
Type your desired game mode here: """)
if game_mode.lower() == 'pvp':
return p_v_p() # Calls function for Player vs Player
if __name__ == '__main__':
while True:
game_selection().play()
if not input('Play again? [y/N]: ').lower().startswith('y'):
break

I am getting an error 'string object is not callable'

I am a beginner in python..I am learning decorators and all that stuff..
This is my code
def addone(myfunc):
def addsand():
return (str(myfunc())+'sand')
return addsand()
#addone
def oldfunc():
return 'ham'
print oldfunc()
The decorator should return a function, not a function's result. Replace return addsand() with return addsand.

Using dict like C switch

class checkevent:
def __init__(self,fromuser):
self.fromuser = fromuser
def openid_check(self):# use sqlalchemy
exist_user = User.query.filter_by(openid = self.fromuser).first()
if exist_user is None:
text = u'请绑定后在使用'
return text
def grade(self):
openid_check()
exist_user = User.query.filter_by(openid = self.fromuser).first()
geturp = urp(exist_user.username, exist_user.password_urp) #the function
return geturp #return the grades as text
def key_check(self,x): # use dict like switch
{'grade': self.grade
}
contents = checkevent('ozvT4jlLObJWzz2JQ9EFsWSkdM9U').key_check('grade')
print contents
It's always return None,I want to get a value
and it's the right way to use dict?
There's no return statement in key_check, so naturally it doesn't return anything. You're basically missing the last bit of the implementation: once you look up the appropriate function by name, you need to call that function and return the result.
def key_check(self, key): # "x" is a meaningless name; use something meaningful
lookup = {
'grade': self.grade
}
func = lookup[key] # Look up the correct method
return func() # Call that method and return its result
Technically you could in-line all that into one statement if you really wanted to, but unless performance is at a premium I wouldn't recommend it as the readability suffers.

How can you make a timer run simultaneously with the rest of the code in Python?

I am making a simple math test for my friend's class. The students will only have 45 seconds to solve each answer. Is there a way to make a timer that will count at the same time as the rest of the code runs and when it reaches 45 stops?
The test looks like this:
test = raw_input("How much is 62x5-23?")
if test == '287':
print "Well done!"
Here's some code I used once (lifted off some page on the web which is now in the hands of a domain squatter, so no credit where credit is due, sadly):
import signal
class TimeoutException(Exception):
pass
def timeout(timeout_time, default = None):
def timeout_function(f):
def f2(*args, **kwargs):
def timeout_handler(signum, frame):
raise TimeoutException()
old_handler = signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout_time) # triger alarm in timeout_time seconds
try:
retval = f(*args, **kwargs)
except TimeoutException, e:
if default == None:
raise e
return default
finally:
signal.signal(signal.SIGALRM, old_handler)
signal.alarm(0)
return retval
return f2
return timeout_function
# use like this:
#timeout(45)
def run():
test = raw_input("How much is 62x5-23? ")
if test == '287':
print "Well done!"
# alternatively, pass a value that will be returned when the timeout is reached:
#timeout(45, False)
def run2():
test = raw_input("How much is 62x5-23? ")
if test == '287':
print "Well done!"
if __name__ == '__main__':
try:
run()
except TimeoutException:
print "\nSorry, you took too long."
# alternative call:
if run2() == False:
print "\nSorry, you took too long."
EDIT: probably works on Unix-type OS'es only.

Overload get_FIELD_display() function

Is there a way to overload Django's get_FIELD_display() function properly? When I call the function from inside itself, the result is a recursion. But I can't call it using super() either, as it's not a parent class' method but a method created by the metaclass...
The goal is to have a common interface for getting a displayable version of a CHOICE field (which is given by get_FIELD_display), but with the possibility to customize it in some specific cases.
Example:
# This does not work because it results in recursion
def get_opposition_state_display(self):
"""Overloading of default function."""
value = self.get_opposition_state_display()
if self.opposition_state == 4:
return '%s %s' % (value, self.opposition_date.strftime('%d.%m.%Y'))
return value
updated
field = self._meta.get_field('opposition_state')
value = self._get_FIELD_display(field)
To override get_FOO_display you need something like this:
field_name = models.PositiveSmallIntegerField('Field', choices=some_choices)
def _get_FIELD_display(self, field):
f_name = field.name
if f_name == 'field_name':
return 'what_you_need'
return super(YourModelName, self)._get_FIELD_display(field=field)