This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 7 years ago.
I have a very simply code looks like following:
def divider(numberA, numberB):
numberC = numberA%numberB
if numberC != 0:
divider(numberB, numberC)
else:
print numberB
return numberB
if __name__=="__main__":
print divider(60,25)
I know I should put a return inside the numberC !=0 loop. However, if I stick to my current code (without return) I will get output like this:
5
None
My question is why these two numbers in the output are different in values ?
You are ignoring the return value of the recursive call:
if numberC != 0:
divider(numberB, numberC)
You need to explicitly return that result:
if numberC != 0:
return divider(numberB, numberC)
You see None as the return value of divider(60, 25) because your outermost call never returned anything, so the default behaviour is to return None instead.
Your code does this:
divider(60, 25)
| numberC = 60 % 25 = 10
| numberC != 0 is True:
| divider(25, 10)
| | numberC = 25 % 10 = 5
| | numberC != 0 is True:
| | divider(10, 5)
| | | numberC = 10 % 5 = 0
| | | numberC != 0 is False
| | | print numberB -> "5"
| | \ return numberB = 5
| \ function ends, return None
\ function ends, return None
Related
I have a program :
def mid(a, b):
if a == 0:
print(b)
r = b
r = r + 1
return r
while b != 0:
if a > b:
a = a - b
print(a)
r = a
return r
So I wanna use exec function to execute this program, like that :
exec('%s(*(tests[i]))' % funName)
with funName is "mid", tests[i] = (3,2) so when (a,b) = (3,2) the while loop become infinite loop and I can't get out of this loop at exec . Any suggest for me ?
This has nothing to do with exec, your function just has a bug which causes an infinite loop.
You can see what your function is doing using snoop:
from snoop import snoop
#snoop
def mid(a, b):
...
mid(3, 2)
Output:
.. a = 3
.. b = 2
| def mid(a, b):
| if a == 0:
| while b != 0:
| if a > b:
| a = a - b
.............. a = 1
| while b != 0:
| if a > b:
| while b != 0:
| if a > b:
| while b != 0:
...
etc.
a = 1 and b = 2, so b != 0 is always True, a > b is always False, and nothing changes.
I am trying to draw a fake 3x3 tic tac toe board. I am new to python and I don't understand why this does not work. Help would be appreciated. Thanks!
def draw():
for i in range(4):
board = (" ___ " * 3)
for i in board:
("| " * 4).join(board)
print(board)
draw()
EDIT:
Final code:
def draw():
board = ''
for i in range(-1,6):
if i%2==0:
board += '| ' * 4
board += '\n| | | |'
else:
board += ' _____ ' * 3
board += '\n'
print (board)
draw()
output:
_____ _____ _____
| | | |
| | | |
_____ _____ _____
| | | |
| | | |
_____ _____ _____
| | | |
| | | |
_____ _____ _____
Double Edit:
Another way:
def drawsmall():
a = (' ___' * 3 )
b = ' '.join('||||')
print('\n'.join((a, b, a, b, a, b, a, )))
drawsmall()
output:
___ ___ ___
| | | |
___ ___ ___
| | | |
___ ___ ___
| | | |
___ ___ ___
I found it easier to do this in one loop, printing a row of the board each iteration. You can alternate between vertical and horizontal bars by checking if the current iteration is an even or odd number using the % operator.
With strings you don't need to use join -- it can be more clear to append with the += operator.
def draw():
# initialize an empty board
board = ""
# there are 5 rows in a standard tic-tac-toe board
for i in range(5):
# switch between printing vertical and horizontal bars
if i%2 == 0:
board += "| " * 4
else:
board += " --- " * 3
# don't forget to start a new line after each row using "\n"
board += "\n"
print(board)
draw()
Output:
| | | |
--- --- ---
| | | |
--- --- ---
| | | |
If you don't want to use variables/functions/loops and want a simple one-liner solution based on Print command:
print("__|__|__", "__|__|__", " | | ", sep='\n')
Try this code instead:
def draw():
a=('\n _____ _____ _____ ')
b= ('\n| | | |')
print(a,b,b,a,b,b,a,b,b,a)
draw()
Output:
_____ _____ _____
| | | |
| | | |
_____ _____ _____
| | | |
| | | |
_____ _____ _____
| | | |
| | | |
_____ _____ _____
for Better view use:
def print_tic_tac_toe():
print("\n")
print("\t | |")
print("\t | | ")
print('\t_____|_____|_____')
print("\t | |")
print("\t | | ")
print('\t_____|_____|_____')
print("\t | |")
print("\t | | ")
print("\t | |")
print("\n")
print_tic_tac_toe()
Output :
| |
| |
_____|_____|_____
| |
| |
_____|_____|_____
| |
| |
| |
Look up how the join function works. First, it takes the given string and uses that for the "glue", the string that connects the others. Second, it returns the constructed string; your join operation fails to save the result.
Try doing this first with nested loops: print a row of boxes, then the horizontal divider, etc. Then, bit by bit, convert that to the single-string output you want.
You can try this:
def draw():
return [["__" for b in range(3)] for i in range(3)]
Now you have a list of lists which contains your board. To print it out, you can do this:
the_board = draw()
for i in the_board:
for b in i:
print('|'.join(i), end="")
print()
print(" | | ")
I thought I'd simplify things so that I could understand it myself. This code produces the same output as above:
def draw_board():
v = '| | | |'
h = ' ____ ____ ____ '
for i in range(0,10):
if i%3==0:
print(h)
else:
print(v)
draw_board()
Output:
____ ____ ____
| | | |
| | | |
____ ____ ____
| | | |
| | | |
____ ____ ____
| | | |
| | | |
____ ____ ____
You can try this:
find below python code for end-to-end interactive Tic-Tac-Toe board game.
Code looks lengthy which can be optimized, but it works perfect as interactive Tic-Tac-Toe board game.
#Function code to clear the output space (screen)
from IPython.display import clear_output
#code to display just board-
def ttt_borad(board):
cl = clear_output()
print('Your Tic-Tac-Toe board now:\n')
print(board[1] + "|" + board[2] + "|" + board[3])
print("________")
print(board[4] + "|" + board[5] + "|" + board[6])
print("________")
print(board[7] + "|" + board[8] + "|" + board[9])
#function code to accept player key choices-
def player_key():
player_choice = ''
play1 = ''
play2 = ''
while player_choice not in ('Y', 'N'):
player_choice = input("Player-1 would like to go first ? Enter Y/N: ")
player_choice = player_choice.upper()
if player_choice not in ('Y', 'N'):
print("Invalid Key")
else:
pass
if player_choice == 'Y':
while play1 not in ('X', 'O'):
play1 = input("Select your Key for Player-1 X or O: ")
play1 = play1.upper()
if play1 not in ('X', 'O'):
print("Invalid Key")
else:
pass
else:
while play2 not in ('X', 'O'):
play2 = input("Select your Key for Player-2 X or O: ")
play2 = play2.upper()
if play2 not in ('X', 'O'):
print("Invalid Key")
else:
pass
if play1 == 'X':
play2 = 'O'
elif play1 == 'O':
play2 = 'X'
elif play2 == 'X':
play1 = 'O'
elif play2 == 'O':
play1 = 'X'
print(f'Key for Player-1 is: {play1} and Key for Player-2 is: {play2}')
return play1, play2
#function code to accept key strokes to play game
def enter_key(key, bp):
play1, play2 = key
ind = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
i = 1
while i < 10:
j = 0
k = 0
print(f'Game Move: {i}')
while j not in ind:
j = input("Player-1: Select position (1-9) for your Move: ")
if j not in ind:
print("Invalid Key or Position already marked")
else:
pass
x = ind.index(j)
ind.pop(x)
j = int(j)
bp[j] = play1
ttt_borad(bp)
i = i + 1
tf = game_winner(key, bp)
if tf == 1:
print("The Winner is: Player-1 !!")
break
print(f'Game Move: {i}')
if i == 10:
break
while k not in ind:
k = input("Player-2: Select position (1-9) for your Move: ")
if k not in ind:
print("Invalid Key or Position already marked")
else:
pass
y = ind.index(k)
ind.pop(y)
k = int(k)
bp[k] = play2
ttt_borad(bp)
i = i + 1
ft = game_winner(key, bp)
if ft == 2:
print("The Winner is: Player-2 !!")
break
return bp
#function code to calculate and display winner of the game-
def game_winner(key, game):
p1, p2 = key
p = 0
if game[1] == game[2] == game[3] == p1:
p = 1
return p
elif game[1] == game[4] == game[7] == p1:
p = 1
return p
elif game[1] == game[5] == game[9] == p1:
p = 1
return p
elif game[2] == game[5] == game[8] == p1:
p = 1
return p
elif game[3] == game[6] == game[9] == p1:
p = 1
return p
elif game[4] == game[5] == game[6] == p1:
p = 1
return p
elif game[3] == game[5] == game[7] == p1:
p = 1
return p
elif game[1] == game[2] == game[3] == p2:
p = 2
return p
elif game[1] == game[4] == game[7] == p2:
p = 2
return p
elif game[1] == game[5] == game[9] == p2:
p = 2
return p
elif game[2] == game[5] == game[8] == p2:
p = 2
return p
elif game[3] == game[6] == game[9] == p2:
p = 2
return p
elif game[4] == game[5] == game[6] == p2:
p = 2
return p
elif game[3] == game[5] == game[7] == p2:
p = 2
return p
else:
p = 3
return p
#Function code to call all functions in order to start and play game-
def game_play():
clear_output()
entry = ['M', '1', '2', '3', '4', '5', '6', '7', '8', '9']
ttt_borad(entry)
plk = player_key()
new_board = enter_key(plk, entry)
tie = game_winner(plk, new_board)
if tie == 3:
print("Game Tie !!! :-( ")
print('Would you like to play again? ')
pa = input("Enter Y to continue OR Enter any other key to exit game: ")
pa = pa.upper()
if pa == 'Y':
game_play()
else:
pass
game_play()
#Try this entire code in any Python3 editor and let me know your feedback.
I have attached sample board how code displays.Sample Tic-Tac-Toe board by code
Thanks
def create_board():
board_size = int(input("What size game board they want to draw? "))
horizontal = " ---"
vertical = "| "
for i in range(board_size):
print(horizontal * board_size)
print(vertical * (board_size + 1))
return print(horizontal * board_size)
create_board()
I'm trying to somehow rectify why I cannot get any satisfying results calling one method after another.
at start I have a 2-dim table [7x9] with cards that create a maze.
for instance:
, A. , B. , C. , D. , E. , F. , G. ,
+-----+-----+-----+--#--+-----+-----+-----+
0. | | | :#####: | | |
+-----+-----+-----+--#--+-----+-----+-----+
1. | | | | # | | | |
+-----+-----+-----+--#--+-----+-----+-----+
2. | | | | #########: | |
+-----+-----+-----+--#--+--#--+-----+-----+
3. | | | | | # | | |
+-----+-----+-----+-----+--#--+-----+-----+
4. | | | | | #########: |
+-----+-----+-----+-----+--#--+-----+-----+
5. | | | | | # | | |
+-----+-----+-----+-----+--#--+-----+-----+
6. | | | :#################: |
+-----+-----+-----+-----+--#--+--#--+-----+
7. | | | | | | # | |
+-----+-----+-----+-----+-----+--#--+-----+
8. | | | | | :#####: |
+-----+-----+-----+-----+-----+--#--+-----+
starting with point D0 I want to check if the path made of cards reached point F8
I don't need shortest way or anything, just to know, that the path exists.
I successfully coded a couple simple functions that are checking that within a class, but the main class method is not returning the True / False to the place where it was called from.
You can judge me by my way of coding, but I never wrote anything that big in Python ;P
Classes:
Board
class Board(object):
board = []
def __init__(self):
for y in range(0,9):
#...
def print_board(self):
# implemented
def getBoard(self):
return self.board
GameBoard
class short idea:
class GameBoard(Board):
def __init__(self, cardsInHand):
def gameView(self):
def checkPath(self):
def right(poz, pa):
def left(poz, pa):
def down(poz, pa):
def up(poz, pa):
def doNext(poz, pa):
def pushCard(self, pos, newCard , force = False):
and the important methods:
def __init__(self, cardsInHand):
Board.__init__(self)
self.cards = cardsInHand
def checkPath(self):
poz = [0,3] # Starting position
conns = [] # skip this
tPath = [] # temporary path
ret = False
test = 0
def right(poz, pa):
if len(self.board[0]) - 1 > poz[1]: # can be checked right
if 1 in self.board[poz[0]][poz[1]].entries: # has route to the right
if 3 in self.board[poz[0]][poz[1] + 1].entries: #the next has matching route
nl = [poz[0], poz[1] + 1]
if nl not in pa:
pa.append(nl)
doNext(nl , pa)
else :
pa = []
def left(poz, pa):
if poz[1] > 0:
if 3 in self.board[poz[0]][poz[1]].entries:
if 1 in self.board[poz[0]][poz[1] - 1].entries:
nl = [poz[0], poz[1] - 1]
if nl not in pa:
pa.append(nl)
doNext(nl, pa)
else:
pa = []
def down(poz, pa):
if len(self.board) - 1 > poz[0]:
if 2 in self.board[poz[0]][poz[1]].entries:
if 0 in self.board[poz[0] + 1][poz[1]].entries:
nl = [poz[0] +1, poz[1]]
if nl not in pa:
pa.append(nl)
doNext(nl , pa)
else :
pa = []
def up(poz, pa):
if poz[0] > 0:
if 2 in self.board[poz[0]][poz[1]].entries:
if 0 in self.board[poz[0] - 1][poz[1]].entries:
nl = [poz[0] - 1, poz[1]]
if nl not in pa:
pa.append(nl)
doNext(nl , pa)
else :
pa = []
def doNext(poz, pa):
ways = []
output = None
if poz == [8, 5]: # the point '**F8**'
ways.append(pa)
output = True
else:
if 1 in self.board[poz[0]][poz[1]].entries:
right(poz, pa)
if 2 in self.board[poz[0]][poz[1]].entries:
down(poz, pa)
if 3 in self.board[poz[0]][poz[1]].entries:
left(poz, pa)
if 0 in self.board[poz[0]][poz[1]].entries:
up(poz, pa)
output = False
return output
#print 'Expect False or True: ', str(doNext(poz, tPath))
return str(doNext(poz, tPath))
As the last checkPath() print eventually should return (print) True at some point but it never does.
further in this class I have method:
def pushCard(self, pos, newCard, force = False):
...
...
win = False
...
# unimportant code
...
if force == True:
allow = True
if allow == True:
self.board[pY][pX] = newCard
if self.checkPath():
print "The path exists"
win = True
else:
#cannot put card here
win = False
return wynik
Following, I cannot also get right result during gameplay:
for num in range(0, 12):
input = str(raw_input( str(num + 1) + ". Card position and identity: 'An T' "))
inPar = input.split(" ")
if len(inPar) == 2:
if gra.pushCard(inPar[0], Karta(inPar[1])):
print ("end of the game")
break
else:
print ("try again")
gra.gameView()
else:
print("bad input")
The function doNext() never returns True, but during testing I got many times a feedback, that the path has been found.
I'm using Python 2.6.6, not able to upgrade.
Any help would be appreciated.
Here is a function that I wrote:
def conc(i,s,y):
if sheet.cell(i+1,0).value != sheet.cell(2,0).value :
# print s
rtrns = s
# print rtrns
return rtrns
else:
if i==list1[len(list1)-1]:
while i<(sheet.nrows):
# print i
s = s + " " + unicode(sheet.cell(i,y).value).encode('cp1252', 'replace')
i+=1
# print s
rtrns = s
# print rtrns
return rtrns
else:
s = s + " " + unicode(sheet.cell(i+1,y).value).encode('cp1252', 'replace')
#return s
conc(i+1,s,y)
In the above function, when I print the value of rtrns in the first if block, it displays the value that I need.
But when I make a call to the function
c = conc(x,c,2) #where x fetches an integer value as an index from a list
print c
it returns None
The return statement is missing in the else part of your code
else:
s = s + " " + unicode(sheet.cell(i+1,y).value).encode('cp1252', 'replace')
#return s
conc(i+1,s,y)
So, there is one code path, where nothing is returned from your recursive function conc.
Change the code and add a return
else:
s = s + " " + unicode(sheet.cell(i+1,y).value).encode('cp1252', 'replace')
#return s
return conc(i+1,s,y)
A recursive call always returns back to the caller. So, when you recursively call conc, and one of the code path issues a return statement, the call gets back to from where you invoked. Another important thing is, a function without an explicit return has an implicit return with None.
The Following ASCII Art should be self explanatory of what might be going wrong
foo() <------------------------------------------------------------------------
| |
| |
|->def conc(...): |
else: (None)
......... |
conc(i+1,s,y) <-------------------------------------------\ |
return None ----------------------------------------------U--- -|
| |
| |
\----->def conc(...): |
else: (None)
......... |
conc(i+1,s,y) <----------------------\ |
return None ------------------------U--|
| |
| |
| |
\----------->def conc(...): (rtrns)
if ... : |
.......... |
return rtrns----|
I am current building a simple card matching game in python, with a 5x4 (row*column) grid, in which two players try to match a deck of twenty cards (2,10 of only suit Hearts) * 2.
The problem I am running into is in iterating through the deck, printing the cards out in a grid fashion so it would look like this:
----- ----- ----- -----
- - - - - - - -
4-H 6-H 7-H 8-H
- - - - - - - -
----- ----- ----- -----
The code I currently have is below:
#needed import for shuffle function
from random import shuffle
#class for my deck
class Deck:
#constructor starts off with no cards
def __init__( self ):
self._deck = []
#populate the deck with every combination of suits and values
def Populate( self ):
#Heart, Diamond, Spades, Clubs
for suit in 'HDSC':
#Jack = 11, Queen = 12, King = 13, Ace = 14
for value in range(2, 15):
if value == 11:
value = 'J'
elif value == 12:
value = 'Q'
elif value == 13:
value = 'K'
elif value == 14:
value = 'A'
#add to deck list
self._deck.append(str(value) + '-' + suit)
#populate the deck with only hears hearts and all cards except face cards and aces (2, 3, 4, 5, 6, 7, 8, 9, 10) twice
def gamePop( self ):
suit = 'H'
for x in range(2):
for value in range(2, 11):
self._deck.append(str(value) + '-' + suit)
#shuffle the deck with the random import
def Shuffle( self ):
shuffle( self._deck )
#length of the deck
def len( self ):
return len( self._deck )
def stringIt( self ):
#Returns the string representation of a deck
result = ''
for c in self._deck:
result = result + str(c) + '\n'
return result
#class for a single card
class Card:
#constructor for what type of card it is
def __init__( self, value, suit ):
self._value = value
self._suit = suit
self._card = self._value + self._suit
#print the type of card
def Description( self ):
return ( self._card )
#overloaded ==
def __eq__( self, another ):
if ( self._card == another.Description() ):
return True
else:
return False
#main function which plays the game
def main():
#sets player counters to zero,
pOneCount = 0
pTwoCount = 0
#creates the deck to be put on the board
gameDeck = Deck()
gameDeck.gamePop()
gameDeck.Shuffle()
print(gameDeck._deck)
currentCard = 0
for row in range(5):
for card in range(0,4+i):
mystring =
print ('------- ' * 4)
print ('| | ' * 4)
for x in range(4):
print ('| ' +gameDeck._deck[currentCard]+'|'),
currentCard += 1
print ('| | ' * 4)
print ('------- ' * 4)
Edit: I cleared up the code which I've tried.
The current output is this:
------- ------- ------- -------
| | | | | | | |
| 7-H|
| 5-H|
| 7-H|
| 9-H|
| | | | | | | |
------- ------- ------- -------
the problem is in the def main():
def main():
print ('------- ' * 4)
print ('| | ' * 4)
for x in range(4):
print ('| ' +gameDeck._deck[currentCard]+'|'),
currentCard += 1
print ('| | ' * 4)
print ('------- ' * 4)
the * 4 just mean that this:
print ('------- ' * 4)
will become this:
print ('------- ' + '------- ' + '------- ' + '------- ' )
it can also be type as:
print ('------- ------- ------- ------- ' )
so. your problem is here:
for x in range(4):
print ('| ' +gameDeck._deck[currentCard]+'|'),
currentCard += 1
this would print as:
| 7-H|
| 5-H|
| 7-H|
| 9-H|
you need to put it as something like this:
print ('| ' +gameDeck._deck[currentCard]+'|'+'| ' +gameDeck._deck[currentCard+1]+'|'+'| ' +gameDeck._deck[currentCard+2]+'|'+'| ' +gameDeck._deck[currentCard+3]+'|')
so it would print in one line like how you want it:
| 7-H| | 5-H| | 7-H| | 9-H|
here is the code that i clean up a little. if it work like it should, it should work:
def main():
#sets player counters to zero,
pOneCount = 0
pTwoCount = 0
#creates the deck to be put on the board
gameDeck = Deck()
gameDeck.gamePop()
gameDeck.Shuffle()
print(gameDeck._deck)
currentCard = 0
for row in range(5):
for card in range(0,4+i):
print (' ------- ' * 4)
print (' | | ' * 4)
print (' | ' +gameDeck._deck[currentCard]+' | '+' | ' +gameDeck._deck[currentCard+1]+' | '+' | ' +gameDeck._deck[currentCard+2]+' | '+' | ' +gameDeck._deck[currentCard+3]+' | ')
print (' | | ' * 4)
print (' ------- ' * 4)
oh, and like John Y say (copy and paste):
The main function has a dangling mystring =, which is a blatant syntax error
here what i use to test, because the whole code don't work for me, i just tested the print part:
print (' ------- ' * 4)
print (' | | ' * 4)
print (' | ' +"1-H"+' | '+' | ' +"2-H"+' | '+' | ' +"3-H"+' | '+' | ' +"4-H"+' | ')
print (' | | ' * 4)
print (' ------- ' * 4)
that got me:
------- ------- ------- -------
| | | | | | | |
| 1-H | | 2-H | | 3-H | | 4-H |
| | | | | | | |
------- ------- ------- -------
>>>