0

So I'm going through the 'Google crash course for Python' and one of the problems was to compare a string to see if it was a palindrome (same backwards as forwards). I assumed that I would need a .lower on the new_string but it was giving me a 'False' on obvious ones like 'kayak' and 'radar', and a 'True' on 'Never Odd or Even'. When I took the .lower out of the code, it all worked. What gives?? Why does Python suddenly not care about case??

Here's the code that worked:

def is_palindrome(input_string):
new_string = ""
reverse_string = ""
for range in input_string:
        if input_string.isalpha():
        new_string = (input_string)
        reverse_string = ''.join(reversed(input_string))
        print(reverse_string)
# Compare the strings
if new_string==reverse_string:
    return True
return False

and the one that didn't:

def is_palindrome(input_string):
new_string = ""
reverse_string = ""
for range in input_string:
        if input_string.isalpha():
        new_string = (input_string.lower)
        reverse_string = ''.join(reversed(input_string))
        print(reverse_string)
# Compare the strings
if new_string==reverse_string:
    return True
return False
  • 3
    Please indent your code properly. – thebjorn Aug 24 '22 at 18:01
  • Your reverse_string is wrong, you should use reverse_string = ''.join(reversed(new_string)), because you are using the lower over new_string but comparing with the original – nacho Aug 24 '22 at 18:02
  • To reverse string in general: https://stackoverflow.com/questions/931092/reverse-a-string-in-python. But not an answer to your specific question. – Nic3500 Aug 24 '22 at 18:02
  • `input_string.lower` -> `input_string.lower()`, you're not calling the method; I'm surpirsed you're not getting `TypeError: 'builtin_function_or_method' object is not reversible` if this is indeed your code – G. Anderson Aug 24 '22 at 18:12
  • .. `.lower` is a function and must be called, i.e. `"Kayak".lower()`, not `"Kayak".lower` (but that is the least of your problems...) – thebjorn Aug 24 '22 at 18:14

3 Answers3

0

To answer your actual question "what gives":

You're missing a () following .lower - so you're actually comparing the string against a method pointer. This is a pretty common pitfall if you're used to languages where the line between properties and methods is hazy.

Also, you're iterating through the characters (range) but then performing your checks on the whole string (input_string), not the characters.

You could also replace the whole thing with:

def is_palindrome(input_string):
    only_alpha = ''.join([x for x in input_string if x.isalpha()]).lower()
    return ''.join(reversed(only_alpha)) == only_alpha

This takes care of the case-insensitivity as well as skipping non-alpha characters in comparison. If you take into account all characters, the method's even shorter.

simpassi
  • 1
  • 3
  • I appreciate the input, I’m a full on n00b to this. I’m sure I’ll learn how to condense my code better as time goes on. – Nick DePuy Aug 25 '22 at 19:13
0

The proper way to write is_palindrome(..) is:

def is_palindrome(s):
    t = s.lower()
    return t == t[::-1]

where t[::-1] reverses the string.

If you want to write loop yourself (as an exercise):

def is_palindrome(s):
    t = s.lower()
    r = ''
    for i in range(len(t) - 1, -1, -1):
        r += t[i]
    return t == r

where range(len(t) - 1, -1, -1) gives you the indices in reverse order (you could also do for i in reversed(range(len(t))): to get the indices in reverse order, although that seems a bit silly).

Other exercise versions include:

def is_palindrome(s):
    for i in range(len(s)):
        if s[i].lower() != s[len(s) - 1 - i].lower():
            return False
    return True

which uses almost none of Python's conveniences...

thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • Wow! That is so much easier! I am trying to be ‘good’ and use the coding they have taught me. Thanks so much! Hopefully I’ll never have to use it though. XD – Nick DePuy Aug 25 '22 at 19:18
0

You are using the .lower() wrong

all you need to do is adding a rounded brackets after the word lower so it would be something like

new_string = input_string.lower()

your code should look something like this

def is_palindrome(input_string):

reverse_string = ""
if input_string.isalpha():
    input_string = input_string.lower()
    reverse_string = ''.join(reversed(input_string))
    print(reverse_string)
# Compare the strings
if input_string==reverse_string:
    return True
return False

Hope you find this helpful!

Ahmad Othman
  • 853
  • 5
  • 18
  • I may have been using the input_string.lower() originally. I was frustrated and confused so I overwrote my code once I found what worked for the answer. Then I pasted it into my question here and modified the copy. Also, I have no Idea why it didn’t paste properly with all my indents. So much to learn… – Nick DePuy Aug 25 '22 at 19:21