Flubbed it in the second interation through the string: range error... HOW?

Thomas Passin list1 at tompassin.net
Wed May 29 11:44:07 EDT 2024


On 5/29/2024 10:59 AM, MRAB via Python-list wrote:
> On 2024-05-29 15:32, Thomas Passin via Python-list wrote:
>> On 5/29/2024 8:55 AM, Kevin M. Wilson wrote:
>>> Please recall, I said the format for the email failed to retain the 
>>> proper indents.
>>> I'll attach a picture of the code!
>>> Purpose; to uppercase every other letter in a string.
>>>
>>> Thanks all, KMW
>>
>> Simpler is good, and readability is good.  For a simple conversion that
>> has a little touch of generality:
>>
>> s1 = 'this is a test'
>> def convert(i, ch):
>>       return ch.upper() if i % 2 else ch
>>
>> result = ''.join([convert(i, ch) for i, ch in enumerate(s1)])
>> print(result)  # tHiS Is a tEsT
>>
> [snip]
> Small mistake there. The original code converted to uppercase on even 
> indexes, whereas your code does it on odd ones.

I wondered if anyone would catch that :)  Anyway, I don't think the 
original question was whether to start with even or odd but ways to 
iterate character by character and do something, right?

>> However, this has a weakness: what to do about spaces.  Should they be
>> counted among the characters to be uppercased? or should they not be
>> included in the count of the alternation?  If you want to uppercase
>> every other letter that is not a space, things become a little more
>> complicated.  And then do you want this to apply to all whitespace or
>> only spaces?
>>
>> If you want to skip changing spaces, then you need to track the state of
>> converted characters in some way.  It would probably be easier (and more
>> readable) to use a "for x in t:" construction:

Actually, I did mess up the action for a space.  It should be:

def convert(convert_this, ch):
     """Convert character ch if convert_this is True.
     Don't convert spaces.
     """
     if ch == ' ':
        return (convert_this, ch)
     if convert_this:
        return (False, ch.upper())
     return (True, ch)

We should never get two printable uppercased characters in a row, even 
if there is a space between them, but my original convert(convert_this, 
ch) did.

>> def convert(convert_this, ch):
>>       """Convert character ch if convert_this is True.
>>       Don't convert spaces.
>>       """
>>       if convert_this:
>>           if ch == ' ':
>>               return (convert_this, ch)
>>           elif convert_this:
>>               return (False, ch.upper())
>>       return (True, ch)
>>
>> convert_next = False
>> result = ''
>> for ch in s1:
>>       convert_next, ch = convert(convert_next, ch)
>>       result += ch
>> print(result)  # tHiS Is A TeSt
>>
>> There could be even more complications if you allow non-ascii characters
>> but you were asking about processing character by character so I won't
>> get into that.
>>
>> (You haven't specified the problem in enough detail to answer questions
>> like those).
>>
> [snip]
> 
> 



More information about the Python-list mailing list