-1
def is_palindrome(x, pos_index, neg_index):
    if x[pos_index] == x[neg_index]:
        print("")
    else:
        return False

    pos_index += 1
    neg_index -= 1

    is_palindrome(x, pos_index, neg_index)


print(is_palindrome("racecar", 0, -1))
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • Welcome to StackOverflow. Please explain in more detail what is not working. Just pasting the code is not enough. Also have a look at [how to ask a good question](https://stackoverflow.com/help/how-to-ask) – Dominik Mar 10 '21 at 15:25
  • Am sorry Dominik this is my first question, I am getting an index out of range error when I run that particular code in pycharm? – Ronnie Atuhaire Mar 10 '21 at 15:29

5 Answers5

0

Your end condition is missing. You recall the function every time, so your pos_index becomes 6 ('r'). After that you should stop, but instead you add one and start the function again. So you get a String index out of range.

And a little note, for your next question some addition information or a specific question would be nice.

Doluk
  • 476
  • 2
  • 9
0

The reason you get an error is because is_palindrome() calls is_palindrome() continuously and there is no stop if the word is a palindrome. The function will only return if the word is not a palindrome. Since there is no stopping point, eventually, both the positive and negative indexes will exceed the maximum index of the string. I would try using this:

def is_palindrome(phrase):
    phrase = "".join(phrase.lower().split())
    index, imax = 0, len(phrase)-1
    while index < imax-index:
        if phrase[index] != phrase[imax-index]:
            return False
        index += 1
    return True

Note that this only checks until index is as close to the halfway through the string as possible (which can be observed by putting print(index) inside the while loop). That way, the code doesn't "double-check" the second half of the string.

Below are a few test runs:

>>> is_palindrome("racecar")
True
>>> is_palindrome("bus")
False
>>> is_palindrome("a man a plan a canal panama")
True
>>> is_palindrome("AABBAA")
True

However, if you wanted to conserve the recursive nature, you can try using this:

def is_palindrome(phrase, positive=0, negative=-1):
    phrase = ''.join(phrase.lower().split())
    if positive >= len(phrase):
        return True
    if phrase[positive] == phrase[negative]:
        return is_palindrome(phrase, positive+1, negative-1)
    return False

A few test runs:

>>> is_palindrome("racecar")
True
>>> is_palindrome("bus")
False
>>> is_palindrome("A man a plan a canal panama")
True
>>> is_palindrome("AABBAA")
True
Jacob Lee
  • 4,405
  • 2
  • 16
  • 37
  • The OP's solution is recursive in nature and they tagged [recursion] but your solution doesn't appear to recurse. – cdlane Mar 10 '21 at 17:10
0

If I were to fix your code, and preserve most of it, I would do something like:

def is_palindrome_recursive(x, pos_index, neg_index):
    if -neg_index >= len(x):
        return True

    if x[pos_index] != x[neg_index]:
        return False

    pos_index += 1
    neg_index -= 1

    return is_palindrome_recursive(x, pos_index, neg_index)

def is_palindrome(string):
    return is_palindrome_recursive(string, 0, -1)

print(is_palindrome("racecar"))

Where the major changes are: an additional return case when we've recursively reduced the input to one letter or less; deal with the result of our recursive call -- a common recursion beginner error.

Since this is not an inherently mathematical problem, my inclination would be to get the numbers and mathematical operators out of the solution. I would also treat the argument as a sequence, rather than a string, to allow fluid transition between a str and a list of characters:

def is_palindrome(sequence):
    if sequence:
        first, *rest = sequence

        if rest:
            *middle, last = rest

            if first != last:
                return False

            return is_palindrome(middle)

    return True

if __name__ == "__main__":
    print(is_palindrome("racecar"))
    print(is_palindrome("radar"))
    print(is_palindrome("ABBA"))
    print(is_palindrome("pop"))
    print(is_palindrome("cc"))
    print(is_palindrome("I"))
    print(is_palindrome(""))

I expect a recursive predicate function for this problem to have three return possibilities: return True on success; return False on failure; return is_palindrome(...) a recursive I don't know, yet.

cdlane
  • 40,441
  • 5
  • 32
  • 81
-1

Try this:

def is_palindrome(x, pos_index, neg_index):
    if x[pos_index] == x[neg_index]:
         print("")
    else:
        return False
    if pos_index==len(x)-1:
        exit()
    else:
         pos_index += 1
         neg_index -= 1
    
    is_palindrome(x, pos_index, neg_index)
     


print(is_palindrome("racecar", 0, -1)) 
JACKDANIELS777
  • 339
  • 1
  • 14
  • 2
    From the name `is_*`, I would expect a predicate function, i.e. one that returns `True` or `False`. This function does one of *three* things, it may return `False`, it might return `None`, or it might kick you out of Python! – cdlane Mar 10 '21 at 17:07
-1

Recursion is a functional heritage and so using it with functional style yields the best results. This means avoiding things like mutations, variable reassignments, and other side effects -

  1. if the input string, s, is less than 2 characters, we always have a palindrome. Return true.
  2. (inductive) s is 2 characters or more. If the first character does not match the last character, return false
  3. (inductive) s is 2 characters or more and the first character matches the last character. Return the result of the sub-problem, s[1:-1]
def is_palindrome(s):
  if len(s) < 2:
    return True                    #1
  elif s[0] != s[-1]:
    return False                   #2
  else:
    return is_palindrome(s[1:-1])  #3
is_palindrome("racecar")
is_palindrome("aceca")
is_palindrome("cec")
is_palindrome("e")
True

We can collapse the bottom two logical branches into one -

def is_palindrome(s):
  if len(s) < 2:
    return True
  else:
    return s[0] == s[-1] and is_palindrome(s[1:-1])

Finally we could collapse the if altogether and simply use logical operators for the entire expression -

def is_palindrome(s):
  return len(s) < 2 or s[0] == s[-1] and is_palindrome(s[1:-1])
Mulan
  • 129,518
  • 31
  • 228
  • 259