Time for another Python challenge. This time it’s the palindrome challenge. What is a palindrome? A palindrome is a word, number, phrase, or other sequence of characters which reads the same backward as forward. Some examples are level, radar, stats.

The goal is to take a string the user inputs, reverse the string and see if it’s identical backward as forward. I will divide my code into two functions:

  • get_string
  • check_palindrome

The first function simply takes the string that is input. The second function checks if it’s a palindrome and prints the result.

As always, let’s first start with a docstring:

"""Program to check if string is a palindrome"""

Then we create a function to get the string from the user. This code should look familiar if you went through the divisors challenge.

def get_string():
    """Get a string from user to be used in function to check for palindrome"""
    # Get string from user with input() and return result 
    user_string = input("Please enter a string to check if it's a palindrome: ")
    return user_string

Now for the more interesting part, to check if a string is a palindrome. To do that, we need to reverse the string. How can we do that? The easiest way is probably to use slicing. Let’s give an example using the REPL:

First we create a string, the word radar:

[email protected]:~/DevAsc$ python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> word = "radar"
>>> 

If we want to access a specific letter of this word, we can use access it by index. For example, to access the first letter:

>>> word[0]
'r'

Notice that counting starts from from zero. If we want to access the last letter, it is accessible at -1:

>>> word[-1]
'r'

We can also access a range of letters, a slice, by specifying a start and stop with a colon in between. For example, the three first ones, with a range from 0 to 3, because the stop index is not inclusive:

>>> word[0:3]
'rad'

It’s also possible to use a stepping. What if we want to access the entire string but only every other letter? We can do that by specifying 0:6:2. Start at index 0, stop at 6 not inclusive, with a stepping of 2.

>>> word[0:6:2]
'rdr'

The drawback here though is that this is not a generic approach since we have specified the stop manually. There are defaults when using slicing that we can leverage to write this more efficiently. The defaults, when using a positive stepping, are these:

  • Start at index 0
  • End where the string ends
  • Stepping of 1

This means that we can access the slice with ::2, where we are using the default values for start and stop, as indicated by the colon, meaning to start at 0 and end where the string ends.

>>> word[::2]
'rdr'

Awesome! So how do we then find the reverse of a string? The trick is to use a negative stepping. This is where things can get a bit confusing. When using a negative stepping, the defaults for start and stop change. The defaults are then these:

  • Start at the end of the string
  • Stop at the beginning of the string

This means that we can reverse a string by using ::-1 where the first colon means to start at the end of string, go to the start of the string, with a stepping of -1, that is, go one step backward each time.

>>> word[::-1]
'radar'

Great. Now let’s write this as a function:

def check_palindrome(user_string):
    """Reverse string from user and check if palindrome"""
    user_string_reverse = user_string[::-1]
    if user_string_reverse == user_string:
        print("It's a palindrome!")
    else:
        print("It's NOT a palindrome!")

We store the user_string in reverse in user_string_reverse. Then we check if they are equal. If they are, it’s a palindrome!

We must, of course, run the functions:

if __name__ == "__main__":
    user_string = get_string()
    check_palindrome(user_string)

When we run the code, this is what it looks like:

[email protected]vasc:~/DevAsc$ python3 palindrome.py 
Please enter a string to check if it's a palindrome: radar
It's a palindrome!
[email protected]:~/DevAsc$ python3 palindrome.py 
Please enter a string to check if it's a palindrome: boat
It's NOT a palindrome!
[email protected]:~/DevAsc$ 

Finally, here’s the entire code:

"""Program to check if string is a palindrome"""

def get_string():
    """Get a string from user to be used in function to check for palindrome"""
    # Get string from user with input() and return result 
    user_string = input("Please enter a string to check if it's a palindrome: ")
    return user_string

def check_palindrome(user_string):
    """Reverse string from user and check if palindrome"""
    user_string_reverse = user_string[::-1]
    if user_string_reverse == user_string:
        print("It's a palindrome!")
    else:
        print("It's NOT a palindrome!")

if __name__ == "__main__":
    user_string = get_string()
    check_palindrome(user_string)

It is available via Github as well.

Bonus: There’s another way of solving this challenge, with a For loop, although slicing is the preferred method. It looks like this:

[email protected]:~/DevAsc/Python-challenges$ python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> word = "radar"
>>> reverse = ""
>>> for i in range(len(word)):
...     reverse += word[len(word)-1-i]
... 
>>> print(reverse)
radar
>>> 

We have the string radar stored in word. We also have an empty string called reverse. We can iterate through word. To do this, we use a for loop that loops through range(len(word)), that is, the length of the word.

We then add letters to reverse, starting at the end. Why do we have len(word)-1? Because of the zero index. Otherwise we would try to access an index that is not available. Why -i at the end? So that we move towards the start of the string. Note that the iterator is 0 when it starts, then it’s 1, 2, 3, and so on.

Happy coding!

DevAsc – Python Palindrome Challenge
Tagged on:             

Leave a Reply

Your email address will not be published. Required fields are marked *