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----|
Related
I'm trying to print my tictactoe board so it looks like
| |
-+-+-
| |
-+-+-
| |
This is my code:
def __str__(self):
result = ""
for i in range(self.nrows):
for j in range(self.ncols):
cell = str(self.gameboard[i][j])
result += cell + "|"
result += "\n"
result += "-+"
result += '\n'
return result
The result looks like
| | |
-+
| | |
-+
| | |
-+
How should I change the code so it looks like the first board? self.nrows is the number of rows, self.ncols is the number of columns, and self.gameboard is the 2d array.
That's not the most pythonic way, and you probably should diverge the code into some functions, but it's working:
def __str__(self):
result = ""
for i in range(self.nrows):
for j in range(self.ncols-1):
cell = str(self.gameboard[i][j])
result += cell + "|"
result += "\n"
if i == self.nrows - 1:
break # added the last line, which is just |
for j in range(self.ncols-1):
result += "-+"
result += '-'
result += '\n'
return result
Output for self.nrows = self.ncols = 3 and self.gameboard[i][j] = ' ' for each i,j:
| |
-+-+-
| |
-+-+-
| |
You need to change the row result += "-+" to result += "-+" * self.ncols + "-". Reason is that you print "-+" symbol only once, but need to do that as many time as your number of columns. Also, in the end you need to add one more "-" symbol to make it look symmetric. In the end just remove the last row that have 2*ncols+2 symbols.
The complete code would be:
def __str__(self):
result = ""
for i in range(self.nrows):
for j in range(self.ncols):
cell = str(self.gameboard[i][j])
result += cell + "|"
result += "\n"
result += "-+" * self.ncols + "-"
result += '\n'
# Remove the last row
result = result[:-2*ncols-2]
result += "\n"
return result
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
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.
I'm trying to write a simple program that creates a square grid like this:
+ - - - - + - - - - +
| | |
| | |
| | |
| | |
+ - - - - + - - - - +
| | |
| | |
| | |
| | |
+ - - - - + - - - - +
I want it to take an input x, which defines how many cells are in each row/column. The script is as follows:
def repeat(x, f, *args):
for i in range(x): f(*args)
def topx(x):
print x*top + '+'
def midx(x):
print x*mid + '|'
def block(f,g,*args):
f(*args)
g(*args)
top = str('+ - - - - ')
mid = str('| ')
x = 2
repeat(x,block,topx,repeat,x,4,midx,x)
topx()
I get the following error when I try to run the script:
TypeError: topx() takes exactly 1 argument (4 given)
It's something to do with the arguments in the block function, but can't figure out how to get around it.
Thanks in advance.
Edit:
Thanks for the pointers, I rewrote it slightly as follows and it works nicely. I also changed it to allow you to choose the number of columns and rows independently.
def repeat(x, f, *args):
for i in range(x): f(*args)
def topx(x):
print x*top + '+'
def midx(x):
print x*mid + '|'
def row(x):
topx(x)
repeat(4,midx,x)
top = str('+ - - - - ')
mid = str('| ')
x = 3
y = 4
repeat(y,row,x)
topx(x)
def topx(x):
print x*top + '+'
This takes one argument: x. But when you call it:
def block(f,g,*args):
f(*args) # This is what calls topx
g(*args)
You're passing it *args, which contains [x, 4, midx, x]. And that's four arguments right there.
You should probably reconsider your structure to fix this. Perhaps a class?
def grid(x, space=4):
for i in range(x):
print ("+" + "-"*space)*x + "+"
for j in range(space):
print ("|" + " "*space)*x + "|"
print ("+" + "-"*space)*x + "+"
I think this is not best way. but your script can be easily updated to be more readable and working.
cell_number = 2
top = str('+ - - - - ')
mid = str('| ')
def repeat(cell_number, f, *args):
"""
repeat call of function `f` `call_number` times
"""
for i in range(cell_number):
f(*args)
def topx(cell_number):
"""
draw horizontal edge
"""
print cell_number * top + '+'
def midx(cell_number):
"""
draw middle part with vertical edges
"""
print cell_number * mid + '|'
def block(cell_num):
"""
draw one row of `cell_num` cells
"""
topx(cell_num)
repeat((len(top) - 1)/2, midx, cell_num)
repeat(cell_number, block, cell_number)
topx(cell_number)
def box(width, height, cell=1):
print '+' + ('- ' * width + '+') * cell
for x in range(cell):
for x in range(height):
print '|' + (' ' * width + '|') * cell
print '+' + ('- ' * width + '+') * cell
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 |
| | | | | | | |
------- ------- ------- -------
>>>