1

I am playing around with a small script, just for fun. I'm trying to reverse the items in a string and witch the upper case to lower and lower to upper. The reverse part works, but the case part doesn't. What am I doing wrong here?

def reverse(s): 
    if len(s) == 0: 
        return s 
    else: 
        if s.lower():
           s.upper()
        else:
           s.lower() 
        return reverse(s[1:]) + s[0]     

mytxt = reverse("I wonder how this text looks like Backwards")
print(mytxt) 

Here is my current output.

sdrawkcab ekil skool txet siht woh rednow I
ASH
  • 20,759
  • 19
  • 87
  • 200

4 Answers4

2

str.lower does not return a boolean of whether it's lowercase or not. It returns a string in lowercase. It also doesn't change a string in place.

Since that is the case you need to check the character you are currently interested in.

In this case s[0]. Additionally, strings aren't mutable so you can't change them in place. You'll need a temp variable.

def reverse(s): 
    if len(s) == 0: 
        return s 
    else: 
        # The character of interest
        char = s[0]
        # If it's equal to the lowercase version of it
        if char == char.lower():
           # Change it to upper
           char = char.upper()
        else:
           # and vice versa
           char = char.lower() 
        return reverse(s[1:]) + char     

mytxt = reverse("I wonder how this text looks like Backwards")
print(mytxt) 
Axe319
  • 4,255
  • 3
  • 15
  • 31
2

s.lower() and s.upper() do not modify s but instead return another string with all letters converted to lowercase or uppercase, respectively. They don't return booleans, either (which is done by s.islower() and s.isupper()).

If you want to rewrite s, you must construct a new string from the return values.

def reverse(s):
    if len(s) == 0:
        return s
    else:
        s0 = s[0]
        if s0.islower():
            s0 = s0.upper()
        elif s0.isupper():
            s0 = s0.lower()
        return reverse(s[1:]) + s0

mytxt = reverse("I wonder how this text looks like Backwards")
print(mytxt)

Here I checked for both islower and isupper, because both return False in the absence of cased characters (e.g. "0".islower() and "0".isupper() are both false).

iBug
  • 35,554
  • 7
  • 89
  • 134
1

str.lower() and str.upper() return a copy of the string converted to lower and upper case. To check whether a string is lower or uppercase, use str.islower() and str.isupper()

Python also has str.swapcase() to do exactly what you want.

Reversing a string can be done simply by using the slice notation, no need for recursion or loops. Your code could be simplified to something like:

def swapcasereverse(s):
    return s[::-1].swapcase()

If you want to write your own code for swapcase as an exercise, here's a pythonic way:

def swapcasereverse(s):
    newlist = [c.upper() if c.islower() else c.lower() for c in reversed(s)]
    return "".join(newlist)

This function uses a list comprehension to

  • iterate over s in reverse order, with each character going in c
  • if c is lowercase, adds c.upper() to the list
  • otherwise, adds c.lower() to the list
  • Joins the list with "" to make a string, returns the joined string
Pranav Hosangadi
  • 23,755
  • 7
  • 44
  • 70
-1
def reverse(s):
    if len(s) == 0:
        return s
    else:
        if s.lower():
            s.upper()
        else:
            s.lower()

return reverse(s[1:]) + s[0]


mytext = reverse("I wonder how this text looks like Backwards").swapcase()
print(mytext)
JNavDev
  • 1
  • 2
  • 3
    Can you at least fix the indentation so the code runs? Thanks. – iBug Sep 10 '20 at 16:39
  • Also the `if...else...` is pointless here. Why not just remove it? – Pranav Hosangadi Sep 10 '20 at 16:46
  • Ahhhh! Now it makes sense. It's funny how you can look at the wrong thing and not see what the problem is, but when you look at the right thing you instantly realize why it's right. – ASH Sep 10 '20 at 17:17