Karan Thakkar
Karan Thakkar

Reputation: 1027

How to convert characters of a string from lowercase to upper case and vice versa without using string functions in python?

Write a function which accepts an input string and returns a string where the case of the characters are changed, i.e. all the uppercase characters are changed to lower case and all the lower case characters are changed to upper case. The non-alphabetic characters should not be changed. Do NOT use the string methods upper(), lower(), or swap().

This is my code:

def changing_cases (input_str):
    new_string = []
    for i in range(0, len(input_str)):
        convert = input_str[i]
        value = ord(convert)
        if (value >= 65 and value <= 90 ):
            value += 32
            new_string.append(chr(value))
        elif (value >= 97 and value <= 122):
            value -= 32
            new_string.append(chr(value))
    return (str(new_string))   

#Main Program
input_str = "Hello"
result = changing_cases (input_str)
print (result)

This code works as expected but there are two major problems with this.

  1. Firstly the output which it returns to the Main is a list, I want it as a string.
  2. Second, how to check whether the string contains special cases and by pass it if there is a special character. Special characters are scattered all over the ASCII table.

Any help would be appreciated.

Upvotes: 0

Views: 3881

Answers (6)

Frederick
Frederick

Reputation: 47

How about a cipher? It's not quite as readable but it seriously reduces the line count.

def swap_cases(data):#ONLY INTENDED FOR USE WITH ASCII! EBCDIC OR OTHER INTERCHANGE CODES MAY BE PROBLEMATIC!
    output = list(data);
    for i in range(0,len(data)):
        if ord(output[i]) > 64 < 123: output[i] = chr(ord(data[i]) ^ ord(list(" "*70)[i % len(" "*70)]));
    return "".join(output);
print(swap_cases(input("ENTRY::")))

No effecting special characters or anything not in the alphabet, 6 lines of code, relatively fast algorithm no external modules, doesn't use swap() or others string functions and contains only one if block, returning a string as requested not a list. EDIT: Come to think of it you can reduce a lot of the clutter by doing this:

if ord(output[i]) > 64 < 123: output[i] = chr(ord(data[i]) ^ 32);

instead of:

if ord(output[i]) > 64 < 123: output[i] = chr(ord(data[i]) ^ ord(list(" "*70)[i % len(" "*70)]));

Upvotes: 0

Deepak Nagarajan
Deepak Nagarajan

Reputation: 131

In python3, one option is to use str.translate.

First, use string methods - string.ascii_uppercase and string.ascii_lowercase to build strings with entire character sets 'A..Z' and 'a..z'. Use str.maketranslate to make a translation table, one for upper case letters to lower case and another for lower case to upper case letters. Finally, loop through the required string, and use str.translate to build the converted string.

import re
import string

test_str = r'The Tree outside is gREEN'
new_str = ''

str_lower = string.ascii_lowercase
#'abcdefghijklmnopqrstuvwxyz'

str_upper = string.ascii_uppercase
#'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

tr_to_upper = str.maketrans(str_lower, str_upper)
tr_to_lower = str.maketrans(str_upper, str_lower)

for char in test_str:
    if re.findall(r'[A-Z]', char):
        new_str = new_str + char.translate(tr_to_lower)
    elif re.findall(r'[a-z]', char):
        new_str = new_str + char.translate(tr_to_upper)
    else:
        new_str = new_str + char

print('{}'.format(new_str))

Output:

tHE tREE OUTSIDE IS Green

Upvotes: 0

Rockybilly
Rockybilly

Reputation: 4510

The string method .join() can help you to unite a list and return a string. But without that knowledge, you could have done this string concatenation.(For that you need to initialize new_string with "", not [])

Join usage:

"".join(["h","e","l","l","o"])
# "hello"

To your second question. You could check if an input is from the alphabet with the .isalpha() method. Which returns a boolean value.

"a".isalpha()
# True

"&".isalpha()
# False

And a suggestion about the solution, You could import the uppercase and lowercase alphabets from the string module. After that, iterating over the term and swapping letters using the alphabet strings is very easy. Your solution is fine for understanding how ascii table works. But with the way I mentioned, you can avoid facing problems about special cases. It is a poor method for cryptology though.

Upvotes: 3

CoMartel
CoMartel

Reputation: 3591

You are close:

def changing_cases (input_str):
    new_string = []
    for i in range(0, len(input_str)):
        convert = input_str[i]
        value = ord(convert)
        if (value >= 65 and value <= 90 ):
            value += 32
            new_string.append(chr(value))
        elif (value >= 97 and value <= 122):
            value -= 32
            new_string.append(chr(value))
        else: #if special character
            new_string.append(chr(value))
    return (''.join(new_string))   

#Main Program
input_str = "Hello"
result = changing_cases (input_str)
print (result)

Upvotes: 1

Alex
Alex

Reputation: 1151

def changing_cases (input_str):
    new_string = []
    for i in range(0, len(input_str)):
        convert = input_str[i]
        value = ord(convert)
        if 65 <= value <= 90:
            value += 32
            new_string.append(chr(value))
        elif 97 <= value <= 122:
            value -= 32
            new_string.append(chr(value))
        else:
            return
    return ''.join(new_string)

So this function will return None if there are any special characters in string and you simply add if conditon to check if result is None then you just skip this word

Upvotes: 1

userzg
userzg

Reputation: 13

Concerning the first problem. I've found it may be possible to use:

print ','.join(result)

or

print str(result).strip('[]')

Good luck!

Upvotes: 1

Related Questions