calling the function, checking for palindromes in a range - python

I'm trying to make a function, which recursively checks for palindromes in a given range. The range is sent to "is_palindrome_multi", which then calls "is_palindrome".
However, it doesn't work with numbers higher then 10, so the limiting step seems to be:
elif data[0]==data[-1]:
statement. Why it doesn't return true for the numbers like 11, 22 and so on? I will be grateful for explanation.
def is_palindorme_multi(beg, end):
for i in range(beg, end):
i = str(i)
if is_palindrome(i) == True:
print "Palindrome"
else:
print "Not palindrome"
def is_palindrome(data):
print data,
if len(data)==1 or len(data)==0:
return True
elif data[0]==data[-1]:
is_palindrome(data[1:-1])
else:
return False

You are not returning the result of the recursive call.
Change your elif:
elif data[0]==data[-1]:
is_palindrome(data[1:-1])
to:
elif data[0]==data[-1]:
return is_palindrome(data[1:-1])
However, I would simply change your is_palindrome method to:
def is_palindrome(data):
return data == data[::-1]
Really, no need to use recursion here.

Related

Tic Tac Toe,Python, Index already filled problem

I have been trying to solve this code from the past few days where if I by mistake place my symbol("x" or "o") in the index already containing symbol, then it should display message "index already filled!", the problem is that it is showing that message even for the indexes which aren't filled. I am a beginner, please help me with this code and please answer my question with your code since i'm kind of bad at English.
import numpy
board=numpy.array([["-","-","-"],["-","-","-"],["-","-","-"]])
numpy.matrix(board)
def pos(row,col,symbol,altr):
while(board[row][col]==symbol or board[row][col]==altr):
print("index already filled")
place(symbol,altr)
board[row][col]=symbol
return board
def place(symbol,altr):
c=int(input("enter index: "))
if(c==1):
return pos(0,0,symbol,altr)
elif(c==2):
return pos(0,1,symbol,altr)
elif(c==3):
return pos(0,2,symbol,altr)
elif(c==4):
return pos(1,0,symbol,altr)
elif(c==5):
return pos(1,1,symbol,altr)
elif(c==6):
return pos(1,2,symbol,altr)
elif(c==7):
return pos(2,0,symbol,altr)
elif(c==8):
return pos(2,1,symbol,altr)
elif(c==9):
return pos(2,2,symbol,altr)
def won(symbol):
return check_rows(symbol) or check_cols(symbol) or check_diagnols(symbol)
def check_rows(symbol):
for i in range(3):
count=0
for j in range(3):
if(board[i][j]==symbol):
count+=1
if(count==3):
return True
else:
return False
def check_cols(symbol):
for j in range(3):
count=0
for i in range(3):
if(board[i][j]==symbol):
count+=1
if(count==3):
return True
else:
return False
def check_diagnols(symbol):
if(board[0][0]==board[1][1] and board[1][1]==board[2][2] and board[2][2]==symbol):
return True
if(board[0][2]==board[1][1] and board[1][1]==board[2][0] and board[2][0]==symbol):
return True
return False
def play():
p1=input("player1,enter your name: ")
p2=input("player2,enter your name: ")
pl1="x"
pl2="o"
i=0
while(i<9):
if(i%2==0):
print(board)
print(p1,"your turn")
place(pl1,pl2)
if(won(pl1)):
print(board)
print(p1,"you won")
break
else:
if(i%2==1):
print(board)
print(p2,"your turn")
place(pl2,pl1)
if(won(pl2)):
print(board)
print(p2,"you won")
break
i+=1
if not won(pl1) and not won(pl2):
print(board)
print("draw")
The while is not appropriate: the condition's result will never change, no matter how many times you loop. So effectively it is an infinite loop: once you get in, you never get out again.
It should be an if. And secondly, when the if condition is true, you don't want the execution of board[row][col]=symbol with those values of row and col. You should let that assignment happen through the recursive call of place. That execution will come to this function with (hopefully) better values of row and col, and will take care of putting the value in the board. So, ... you need to put that assignment in an else block, so it only happens when the location is fine.
if (board[row][col]==symbol or board[row][col]==altr):
print("index already filled")
place(symbol,altr)
else:
board[row][col]=symbol
Remark: Even though it works like this, I would not have chosen for the recursive solution. You may want to look at an alternative where you have no recursion, but a while loop in the place function.
I think the problem is place call pos, and pos call place, again and again. It's not necessary to return board in both functions.
def pos(row,col,symbol,altr):
if board[row][col]==symbol or board[row][col]==altr:
print("index already filled")
return False
else:
board[row][col]=symbol
return True
def place(symbol,altr):
while True
c=int(input("enter index: "))
if 1 <= c <= 9:
c = c-1
if pos(c//3, c%3, symbol, alter):
return
I explained this with pseudo code
def pos(row, column, player_symbol, another_player_sumbol):
# Check (row, cell) if not occupied
if selected_cell not with blank syambol:
message('Cell occupied')
return input_is_NG
else:
set cell occupied
return input_is_OK
def place(symbol,altr):
while True (until position_is_OK):
input position of cell
if position is from 1 to 9:
position -= 1
if pos(position//3, position%3, symbol, alter) is OK:
return # exit from place, and next turn for another player
user_input_is_NG, while loop again

Python can't print the word from the given condition

I have this program:
def validateNumber(number):
if (count > 10) :
print('Invalid number')
return -1
elif (count < 10):
print('Invalid number')
return -1
while True:
count = 0
num = int(input('Number:'))
while num > 0:
num = num//10
count = count+1
if (count == 10) :
break
But I can't print the print('Invalid number') and it turn out to be like this:
Number:122344
Number:123442
Number:1234567890
>>>
I want it to print the print('Invalid number') when the number is less or more than 10.
Number:122344
Invalid number
Number:123442088080989098
Invalid number
Number:1234567890
>>>
Help please. Thanks
The return -1 is for if the number is missing or invalid
Firstly, you could condense your if check to one statement. Note that the easiest way to count the number of digits is to convert it to a string and check its length.
def validateNumber(number):
if len(str(number)) != 10:
return -1
Unfortunately, you do not return a legitimate value if the number is valid. Why not return a boolean value instead?
def validateNumber(number):
if len(str(number)):
return True
return False
You can further reduce this to:
def validateNumber(number):
return len(str(number)) == 10
Note that all the validation logic has now been moved to the function. You'll see how this simplifies the loop code.
Next, you have defined two loops. When you break from the inner, the outer will continue, so you come back to the inner, thus restarting the process.
As a fix, I'd recommend doing this with one loop only, like this:
while True:
x = int(input('...'))
if validateNumber(x):
break
else:
print('Invalid Number')
Since validateNumber returns a bool result, simply have the if query the return value, and break if the number is valid, otherwise the loop repeats.
The good thing about having all your validation code inside the function is that you don't have to modify your loop code if your validation logic changes.

Receiving return None value

I am doing exercise from the book where I am supposed to write program that can take a positive integer greater than 2 and write out the number of times one must repeatedly divide this number by 2 before getting a value less than 2.
def inStr():
n = -1
while n<2:
try:
n = int(input('Enter a positive integer greater than 2: '))
except:
pass
print(positive(n)) # prints None
def positive(n, step=0):
if n < 2:
# print(step) #it prints correct answer
return step #but why it returns None?
positive(n//2, step+1)
inStr()
I don't understand why def positive(n, step=0) returns None?
It seems that you forgot to add return right before positive(n//2, step+1). So your function positive sometimes returns nothing (i.e. None).
Try this:
def inStr():
n = -1
while n<2:
try:
n = int(input('Enter a positive integer greater than 2: '))
except:
pass
print(positive(n)) # prints None
def positive(n, step=0):
if n < 2:
# print(step) #it prints correct answer
return step #but why it returns None?
return positive(n//2, step+1)
inStr()
Because you don't tell it to return anything else. You need to put return in there:
def positive(n, step=0):
if n < 2:
# print(step) #it prints correct answer
return step #but why it returns None?
return positive(n//2, step+1)
There may be times when a function calls itself, but doesn' want to return the results. You need to tell Python that this time you want to. Since you didn't tell Python what to return, it returns None by default.

How to break a Python while loop from a function within the loop

while True:
input = raw_input("enter input: ")
result = useInput(input)
def useInput(input):
if input == "exit":
break #return 0 / quit / etc.. i want to break the while loop from within this function
I know I can put the "if logic" directly in the while loop, but I want it to be in the function. Is there a way to break a while loop from within a function called in the loop?
Raise an exception, that you can handle outside the While loop
Return a flag to be captured by the caller and handle accordingly. Note, "if logic" directly in the while loop,, would be the most preferred way.
Python has a cool feature in generators - these allow you to easily produce iterables for use with a for loop, that can simplify this kind of code.
def input_until(message, func):
"""Take raw input from the user (asking with the given message), until
when func is applied it returns True."""
while True:
value = raw_input(message)
if func(value):
return
else:
yield value
for value in input_until("enter input: ", lambda x: x == "exit"):
...
The for loop will loop until the iterator stops, and the iterator we made stops when the user inputs "exit". Note that I have generalised this a little, for simplicity, you could hard code the check against "exit" into the generator, but if you need similar behaviour in a few places, it might be worth keeping it general.
Note that this also means you can use it within a list comprehension, making it easy to build a list of results too.
Edit: Alternatively, we could build this up with itertools:
def call_repeatedly(func, *args, **kwargs):
while True:
yield func(*args, **kwargs)
for value in itertools.takewhile(lambda x: x != "exit",
call_repeatedly(raw_input, "enter input: ")):
...
I usually do this:
def getInput():
while True:
yield raw_input("enter input: ")
for input in getInput():
if input == 'exit':
break
result = useInput(input)
You can raise an exception and handle it outside of while ... but that will likely result in some confusing code ...
def useInput(in_):
if in_ == "exit":
raise RuntimeError
try:
while True:
input = raw_input("enter input: ")
result = useInput(input)
except RuntimeError:
pass
It's MUCH better to just return a boolean flag and then break or not depending on the value of that flag. If you're worried that you already have something you want to return, don't fret -- python will happily let your function return more than one thing:
def func()
...
return something,flag
while True:
something,flag = func()
if flag:
break
Well if its just aesthetics thats keeps you from putting it in the while loop then any of the above would work... not of fan of the try/except one though. Just know there isn't going to be any performance difference putting it in its own function though. Here's one that I believe also meets your requirements :-)
# you have to define the function first if your while isn't in a function
def UseInput():
input = raw_input("enter input: ")
if input == "exit":
return False
elif input == "pass":
return True
# Do stuff
return True
while UseInput():
pass

Python Function variable: local and global

I am struggling with local and global variables.
I was doing this:
def SomeFunc(Input):
if Input == 1:
Input = "True"
elif Input == 0:
Input = "False"
RawInput=int(raw_input("Input 1 or 0: "))
SomeFunc(RawInput)
print str(RawInput)
and it showed this:
>>> def SomeFunc(Input):
if Input ==1:
Input = "True"
elif Input ==0:
Input = "False"
>>> RawInput = int(raw_input("Input 1 or 0: "))
Input 1 or 0: 1
>>> SomeFunc(RawInput)
>>> print str(RawInput)
1
What should I do so that the input will convert to str in the function?
Input is an int which is an immutable object. In other words, you can't change it anywhere. However, you can assign it to something else. One of the tricky things about python is learning that everything is just a reference. When you assign to something, you just change the reference. Think about your variables as strings which go into boxes. When you assign to a variable, you put that string in a particular box. When you assign that variable to something else, you change the box that string goes to. Of course, when you actually do an addition, you add the contents of the box, not the strings (which is a little confusing). If you're accustomed to programming in C, it's kind of like everything is a pointer which gets automatically dereferenced (except when you do an assignment).
So, what to do? The easiest thing is to return the value from your function.
def some_func(inpt):
if inpt == 1:
return "True"
elif inpt == 0:
return "False"
else:
raise ValueError("WHAT IS THIS GARBAGE? I SAID 0 OR 1!!!!") # ;^)
Now you can call your function as:
processed_input = some_func(rw_inpt)
as a side note, your function can be condensed to:
def some_func(inpt):
return str(bool(inpt))
or
def some_func(inpt):
return "True" if inpt else "False"
Both of these pass (and return "True" if the user puts in any integer that isn't 0). If you really want to force the user to not put in something like "2", you can do:
def some_func(inpt):
return {1:"True",0:"False"}[inpt]
But I wouldn't recommend that one...
Basically you want the argument to be pass-by-reference, but that is not how Python works for basic datatypes. The pythonic way of doing this is as following:
def some_func(input):
if input == 1:
return "True"
elif input == 0:
return "False"
And then
raw_input = some_func(raw_input)
Note: You can just do this: print bool(int(raw_input("Input 1 or 0: ")))
The more pythonic way of doing it would be as follows:
def some_func(x):
if x == 1:
return "True"
elif x == 0:
return "False"
x = int(raw_input("Input 1 or 0: "))
x = some_func(x)
print x
However if you did want to use globals you could do it like this but this is really hacky and it isn't one of the good coding practices that python promotes.
def some_func():
global x
if x == 1:
x = "True"
elif x == 0:
x = "False"
x = int(raw_input("Input 1 or 0: "))
some_func()
print x
Some other notes:
Try not to use names like the bultins eg. Input and RawInput since it makes things unclear and mixes everything up.
What should I do so that the input will convert to str in the
function?
def SomeFunc(Input):
as_string = str(Input)
if Input == '1':
Input = "True"
elif Input == '0':
Input = "False"
Note that python has a native boolean type, including the values True and False already. You can use the integer value of Input as a condition all on its own.

Categories