Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > calling upper() on a string, not working?

Reply
Thread Tools

calling upper() on a string, not working?

 
 
John Salerno
Guest
Posts: n/a
 
      05-16-2006
Can someone tell me what's happening here. This is my code:



PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)

def filter_letters(original):
return ''.join(set(original) - PUNCT_SPACE_SET)



'original' is a string. The above works as expected, but when I change
it to

return ''.join(set(original.upper()) - PUNCT_SPACE_SET)

it doesn't seem to work. The full code is below if it helps to understand.



import string
import random
import itertools

PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)

def convert_quote(quote):
return encrypt_quote(quote).split('|')

def encrypt_quote(original):
original_letters = filter_letters(original)
new_letters = list(string.ascii_uppercase)
while True:
random.shuffle(new_letters)
trans_letters = ''.join(new_letters)[:len(original_letters)]
if test_code(original_letters, trans_letters):
trans_table = string.maketrans(original_letters, trans_letters)
break
return original.translate(trans_table)

def filter_letters(original):
return ''.join(set(original) - PUNCT_SPACE_SET)
#return ''.join(set(original.upper()) - PUNCT_SPACE_SET)

def test_code(original_letters, trans_letters):
for pair in itertools.izip(original_letters, trans_letters):
if pair[0] == pair[1]:
return False
return True

if __name__ == '__main__':
print convert_quote("The past is not dead. In fact, it's not even
past.|William Faulkner")
 
Reply With Quote
 
 
 
 
Felipe Almeida Lessa
Guest
Posts: n/a
 
      05-16-2006
Em Ter, 2006-05-16 Ã*s 20:25 +0000, John Salerno escreveu:
> it doesn't seem to work. The full code is below if it helps to understand.


Why doesn't it work? What does it do, what did you expect it to do?

>>> ''.join(set('hi'))

'ih'
>>> ''.join(set('HI'))

'IH'
>>> ''.join(set('hiHI'))

'ihIH'
>>> ''.join(set('hiHI'.upper()))

'IH'


--
Felipe.

 
Reply With Quote
 
 
 
 
John Salerno
Guest
Posts: n/a
 
      05-16-2006
Felipe Almeida Lessa wrote:
> Em Ter, 2006-05-16 Ã*s 20:25 +0000, John Salerno escreveu:
>> it doesn't seem to work. The full code is below if it helps to understand.

>
> Why doesn't it work? What does it do, what did you expect it to do?


If you run the whole script with the first line (the one not commented),
you get output similar to this, which is correct:

>>>

["AMN RIPQ LP WOQ SNIS. BW VIDQ, LQ'P WOQ NHNW RIPQ.", 'ULJJLIY TIZJXWNE']
>>>


But if you use the line with the upper() call, you get this:

>>>

["Bhe past is not dead. Dn fact, it's not even past.", 'Killiam Qaulkner']
>>>


Now, I know the actual upper() function works, but I can't understand if
there's a problem with *when* it's being called, or what's being done
with it to get the second result above.
 
Reply With Quote
 
Michal Kwiatkowski
Guest
Posts: n/a
 
      05-16-2006
John Salerno wrote:
> def encrypt_quote(original):
> original_letters = filter_letters(original)


You call filter_letters() which makes upper() on all letters, so
original_letters contain only uppercase letters.

> new_letters = list(string.ascii_uppercase)
> while True:
> random.shuffle(new_letters)
> trans_letters = ''.join(new_letters)[:len(original_letters)]
> if test_code(original_letters, trans_letters):
> trans_table = string.maketrans(original_letters,
> trans_letters) break
> return original.translate(trans_table)


And here you're translating 'original' (which contains a lot of
lowercase letters) with use of trans_table that maps only uppercase
characters. This return should be:

return original.upper().translate(trans_table)

mk
--
. o . >> http://joker.linuxstuff.pl <<
. . o It's easier to get forgiveness for being wrong
o o o than forgiveness for being right.
 
Reply With Quote
 
John Salerno
Guest
Posts: n/a
 
      05-16-2006
Michal Kwiatkowski wrote:

> And here you're translating 'original' (which contains a lot of
> lowercase letters) with use of trans_table that maps only uppercase
> characters. This return should be:
>
> return original.upper().translate(trans_table)


Thank you!!!
 
Reply With Quote
 
Larry Bates
Guest
Posts: n/a
 
      05-16-2006
John Salerno wrote:
> Can someone tell me what's happening here. This is my code:
>
>
>
> PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)
>
> def filter_letters(original):
> return ''.join(set(original) - PUNCT_SPACE_SET)
>
>
>
> 'original' is a string. The above works as expected, but when I change
> it to
>
> return ''.join(set(original.upper()) - PUNCT_SPACE_SET)
>
> it doesn't seem to work. The full code is below if it helps to understand.
>
>
>
> import string
> import random
> import itertools
>
> PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)
>
> def convert_quote(quote):
> return encrypt_quote(quote).split('|')
>
> def encrypt_quote(original):
> original_letters = filter_letters(original)
> new_letters = list(string.ascii_uppercase)
> while True:
> random.shuffle(new_letters)
> trans_letters = ''.join(new_letters)[:len(original_letters)]
> if test_code(original_letters, trans_letters):
> trans_table = string.maketrans(original_letters, trans_letters)
> break
> return original.translate(trans_table)
>
> def filter_letters(original):
> return ''.join(set(original) - PUNCT_SPACE_SET)
> #return ''.join(set(original.upper()) - PUNCT_SPACE_SET)
>
> def test_code(original_letters, trans_letters):
> for pair in itertools.izip(original_letters, trans_letters):
> if pair[0] == pair[1]:
> return False
> return True
>
> if __name__ == '__main__':
> print convert_quote("The past is not dead. In fact, it's not even
> past.|William Faulkner")


Not exactly sure why you think its not working. When you create a set
from the original.upper() you get a smaller number of characters because
you no longer get both 'T' and 't' as well as 'I' and 'i' as you do in
the lower case version of the string.

>>> set(original.split('|')[0])

set(['a', ' ', 'c', 'e', 'd', "'", 'f', 'i', 'h', ',', 'o', 'n', 'p', 's', 'T',
'v', 'I', '.', 't'])
>>> set(original.split('|')[0].upper())

set(['A', ' ', 'C', 'E', 'D', "'", 'F', 'I', 'H', ',', 'O', 'N', 'P', 'S', 'T',
'V', '.'])
>>>


sets can only contain "unique" entries. Letters that are repeated only get
added once. When you do .upper() you convert lowercase 't' to 'T' and lower
case 'i' to 'I' so that letter only gets added to the set a single time.

Hope info helps.

Larry Bates
 
Reply With Quote
 
John Salerno
Guest
Posts: n/a
 
      05-16-2006
Bruno Desthuilliers wrote:

>> def encrypt_quote(original):

> # Since it's here that we define that the new letters
> # will be uppercase only, it's our responsability
> # to handle any related conditions and problems
> # The other functions shouldn't have to even know this.
> original = original.upper()


>> def filter_letters(original):

> # here, we *dont* have to do anything else than filtering
> # upper/lower case is *not* our problem.
>> return ''.join(set(original) - PUNCT_SPACE_SET)


Thanks, I was wondering if it only needed to be done in a single place
like that.
 
Reply With Quote
 
Scott David Daniels
Guest
Posts: n/a
 
      05-16-2006
John Salerno wrote:
<Some code, with a request to get case working.>
Others have shown you where the bug was.

You might want to change encrypt_quote like this:

XXX> def encrypt_quote(original):
def encrypt_quote(original, casemap=True):
XXX> original_letters = filter_letters(original)
if casemap:
original_letters = filter_letters(original.upper())
else:
original_letters = filter_letters(original)
XXX> new_letters = list(string.ascii_uppercase)
if len(original_letters) > 26:
new_letters = list(string.ascii_uppercase +
string.ascii_lowercase)
casemap = False
else:
new_letters = list(string.ascii_uppercase)
> while True:
> random.shuffle(new_letters)
> trans_letters = ''.join(new_letters)[:len(original_letters)]
> if test_code(original_letters, trans_letters):

XXX> trans_table = string.maketrans(original_letters,
trans_letters)
if casemap:
trans_table = string.maketrans(
original_letters + original_letters.lower(),
trans_letters + trans_letters.lower())
else:
trans_table = string.maketrans(original_letters,
trans_letters)
> break
> return original.translate(trans_table)



--Scott David Daniels

 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      05-17-2006
John Salerno a écrit :
> Can someone tell me what's happening here. This is my code:
>
> PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)
>
> def filter_letters(original):
> return ''.join(set(original) - PUNCT_SPACE_SET)
>
> 'original' is a string. The above works as expected, but when I change
> it to
>
> return ''.join(set(original.upper()) - PUNCT_SPACE_SET)
>
> it doesn't seem to work. The full code is below if it helps to understand.
>


Don't assume str.upper() is broken !-)

In fact, your problem is that you create the translation table based on
uppercase letters, and apply it to a non uppercased string :

> import string
> import random
> import itertools
>
> PUNCT_SPACE_SET = set(string.punctuation + string.whitespace)
>
> def convert_quote(quote):
> return encrypt_quote(quote).split('|')
>
> def encrypt_quote(original):

# Since it's here that we define that the new letters
# will be uppercase only, it's our responsability
# to handle any related conditions and problems
# The other functions shouldn't have to even know this.
original = original.upper()
> original_letters = filter_letters(original)
> new_letters = list(string.ascii_uppercase)
> while True:
> random.shuffle(new_letters)
> trans_letters = ''.join(new_letters)[:len(original_letters)]
> if test_code(original_letters, trans_letters):
> trans_table = string.maketrans(original_letters, trans_letters)
> break
> return original.translate(trans_table)
>
> def filter_letters(original):

# here, we *dont* have to do anything else than filtering
# upper/lower case is *not* our problem.
> return ''.join(set(original) - PUNCT_SPACE_SET)
>
> def test_code(original_letters, trans_letters):
> for pair in itertools.izip(original_letters, trans_letters):
> if pair[0] == pair[1]:
> return False
> return True
>
> if __name__ == '__main__':
> print convert_quote("The past is not dead. In fact, it's not even
> past.|William Faulkner")


["XCD ONKX AK IGX LDNL. AI WNBX, AX'K IGX DYDI ONKX.", 'UAEEANP WNREQIDS']
 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      05-17-2006
John Salerno <> writes:
> Now, I know the actual upper() function works, but I can't understand
> if there's a problem with *when* it's being called, or what's being
> done with it to get the second result above.


You are translating "original" which still has lower case letters:

return original.translate(trans_table)

You want:

return original.upper().translate(trans_table)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
c++ calling java calling c++ ... Klaus Friese C++ 7 08-15-2005 09:23 PM
calling virtual function results in calling function of base class... Andreas Lagemann C++ 8 01-10-2005 11:03 PM
calling virtual function results in calling function of base class ... tiwy C++ 0 01-09-2005 11:17 PM
Calling FormsAuthentication.SignOut() after calling Response.Flush =?Utf-8?B?TWFydGluIExlZQ==?= ASP .Net 1 09-28-2004 12:47 PM
Server Side button calling page_load before calling it's own click event. Ryan Ternier ASP .Net 4 07-29-2004 01:06 PM



Advertisments