Dmitri Valentine
Dmitri Valentine

Reputation: 17

Convert String to Upper from Scratch

I am trying to write a function that converts a string to it's uppercase version. It mostly works, unless it gets towards the end of the alphabet or end of the input string.

Thoughts? Suggestions? Advice?

def upper(string):

    length = len(string)
    index_string = 0
    index_ucase = 0
    index_lcase = 0
    uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    lowercase = 'abcdefghijklmnopqrstuvwxyz'

    while index_string < len(string):
        index_lcase = 0
        while index_lcase < len(lowercase):
            if string[index_string] == lowercase[index_lcase]:
               string = string[:index_string] + uppercase[index_lcase] + string[index_string+1:]
               break
            else:
                index_lcase += 1
        index_string += 1

Upvotes: 1

Views: 989

Answers (9)

Garrett R
Garrett R

Reputation: 2662

x = 'hello world'
print "".join( [ chr(ord(c) - 32) if 97<=ord(c)<=122 else c for c in x ])

That should work. It use the fact that ascii lowercase fall in the range[97,122] and the corresponding uppercase letters are encoded in the range 65-90.

Upvotes: 0

Bear
Bear

Reputation: 572

You do know there is function in python called upper() that does the same thing, right?

s= "little boy doesn't cry"
print s.upper()

why are you writing it from scratch?

Upvotes: 0

Ibukun Muyide
Ibukun Muyide

Reputation: 1298

not sure why you want to do this. here is an ASCII implementation

def upper(string):
result = list()
for x in string :
    result.append(convert(x))
return ''.join(result)

# convert each character to ascii and find its uppercase value
def convert(char):
ascil_value = ord(char) 
# ascii lower case are between 97 and 122
if( ascil_value >= 97 and ascil_value < 123):
    return chr(ascil_value - 32)
else:
    return char

upper('TesTing)

Upvotes: 0

C_Quinn
C_Quinn

Reputation: 11

uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '
lowercase = 'abcdefghijklmnopqrstuvwxyz '

First you can use zip and a dictionary comprehension to map the two letter lists.

mapping = {i: j for i, j in zip(lowercase, uppercase)}

Next you can use a list comprehension to map them.

def upper(s):
    S = ''.join([mapping.get(i, i) for i in s])
    return S

Following Paul Rooney's suggestion (using mapping.get()) means that the code is robust against unexpected characters. Only the characters in the dict will change.

Upvotes: 0

Bonifacio2
Bonifacio2

Reputation: 3840

from string import ascii_lowercase as lowercase
from string import ascii_uppercase as uppercase

def upper(string):
    return ''.join([uppercase[lowercase.find(char)] for char in string])

You don't have to define the constants yourself when you can import them. What the only line in my upper function is doing is:

  1. Iterating through the input string: for char in string
  2. Finding the position of every char in the string lowercase.find(char)
  3. Mapping it to the uppercase equivalent uppercase[lowercase.find(char)]
  4. Joining each of the resulting list of uppercase chars in a single string ''.join([uppercase[lowercase.find(char)] for char in string])

Upvotes: 0

fahad daniyal
fahad daniyal

Reputation: 269

Hmmm.. I would use a simpler approach

import string 
def upper(instring='abacbba'):
    char_map = {l:u for l,u in zip(string.ascii_lowercase, string.ascii_uppercase)}
    return "".join([map[char] if char in char_map.keys() else char for char in instring])

This would work for ascii only btw...

Upvotes: 0

Marcus M&#252;ller
Marcus M&#252;ller

Reputation: 36352

Thoughts? Suggestions? Advice?

Don't do this.

Really.

Don't.

Unless you're playing. Don't. Don't do this.

Why?

Languages are hard.

Uppercase to i is I, right?

You can always go Uppercase letter -> downcase letter -> Uppercase letter, and the output is the same as the input. Right?

Nope. Nope. Nope Nope.

So first of all, your approach doesn't cover anything but ASCII letters. You know what? German has ä. ä is straight forward. Uppercase ä is Ä, lowercase Ä is ä (if you wonder: it sounds like the a in English sad).

Also, German has ß. ß is a lowercase letter. It sounds like a very sharp s. Switzerland, though partly speaking German, doesn't have ß; they simply use ss. So, in German, ß only occurs in the middle or at the end of words. This means there's no need for an uppercase version of it; and, thanks to German efficiency, there simply is no uppercase version of it.

You want to write CANDY STORE across your store's entrance? In normal capitalization, it's Süßwarengeschäft (Sweet-Ware-Store). If you transliterate that into ALL CAPS, it's right and normed to be SÜSSWARENGESCHÄFT. Notice the substitution of lowercase ß by uppercase SS. BAM. No way back. Your word just got one letter longer, and unless you know German orthography (and are sure the shop owner isn't Swiss), there's no way of knowing that if you want to translate things back to lower case, you'll need to use ß instead of ss.

That is, unless you used something that gives you much more information.

Unicode is something that gives you much more information. A greek Omega might be just that -- a long "O" sound, or it might be the unit of electrical resistance, Ohms: Ω. Different meanings (though probably looking the same), common enough for Unicode to have to different codepoints for these. If you take a big Omega in Unicode and use pythons lower() on it, it should correctly give you . Not so much if you take u"The resistance of this resistor is 5Ω" and use lower on that: u"the resistance of this resistor is 5Ω".

Hence: don't use simple letter-per-letter translation. It never worked, and it never will.

Upvotes: 3

Rockybilly
Rockybilly

Reputation: 4510

Or another way.

test = "This is a sentence."
print "".join([char if char not in lowercase else uppercase[lowercase.index(char)] for char in test])
# THIS IS A SENTENCE.

Just to clarify, it is equivalent to this;

result = ""
for char in test:
    if char not in lowercase:
        result += char
    else:
        result += uppercase[lowercase.index(char)]
print result

Upvotes: 0

Heman Gandhi
Heman Gandhi

Reputation: 1371

I suggest a dict:

letters = {'a': 'A'... 'z': 'Z'}

Then:

def upper(s):
  r = ''
  for i in s:
    if i in letters:
      r = r + letters[i]
    else:
      r = r + i
  return r

I think these should solve your problem. Where exactly does your code fail?

Upvotes: 1

Related Questions