• Re: Flubbed it in the second interation through the string: range error

    From Thomas Passin@21:1/5 to Kevin M. Wilson via Python-list on Wed May 29 01:14:07 2024
    Your code is unreadable. The lines have all run together. And after
    that, kindly explain what you want your code sample to do. "Process"
    doesn't say much.

    From what I can make out about what you are trying to do, you would do
    better to index through your string with

    for i, chr in enumerate(name):
    # do something with the character

    Also, it's 2024 ... time to start using f-strings (because they are more readable than str.format())

    On 5/29/2024 12:33 AM, Kevin M. Wilson via Python-list wrote:
    The following is my effort to understand how to process a string, letter, by letter:
    def myfunc(name):        index = 0    howmax = len(name)    # while (index <= howmax):    while (index < howmax):        if (index % 2 == 0):            print('letter to upper = {}, index {}!'.format(name[index], index))       
        name = name[index].upper()            print('if block {} and index {}'.format(name[index], index))        elif (index % 2 > 0):            print(index)            print('Start: elseif block, index is {}, letter is {}'.format(
    index, name))            # print('letter to lower = {}'.format(name[index]))            # print('Already lowercase do noting: name = {}'.format(name[index]))        index += 1        # index = name.upper()
        return name
    myfunc('capitalism')
    Error message:                        Not making sense, index is 1, letter s/b 'a'letter to upper = c, index 0!
    if block C and index 0
    1
    Start: elseif block, index is 1, letter is C --------------------------------------------------------------------------- IndexError Traceback (most recent call last) Cell In[27], line 21
    17 # index = name.upper()
    19 return name
    21 myfunc('capitalism')

    Cell In[27], line 8, in myfunc(name)
    6 while (index < howmax):
    7 if (index % 2 == 0):
    ----> 8 print('letter to upper = {}, index {}!'.format(name[index], index))
    9 name = name[index].upper()
    10 print('if block {} and index {}'.format(name[index], index))

    IndexError: string index out of range***************************************************
    So, I'm doing something... Stupid!! ***************************************************
    "When you pass through the waters, I will be with you: and when you pass through the rivers, they will not sweep over you. When you walk through the fire, you will not be burned: the flames will not set you ablaze."
    Isaiah 43:2

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cameron Simpson@21:1/5 to Thomas Passin on Wed May 29 15:52:47 2024
    On 29May2024 01:14, Thomas Passin <[email protected]> wrote:
    Also, it's 2024 ... time to start using f-strings (because they are
    more readable than str.format())

    By which Thomas means stuff like this:

    print(f'if block {name[index]} and index {index}')

    Notice the leading "f'". Personally I wouldn't even go that far, just:

    print('if block', name[index], 'and index', index)

    But there are plenty of places where f-strings are very useful.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Kevin M. Wilson on Wed May 29 11:59:20 2024
    "Kevin M. Wilson" <[email protected]> wrote or quoted:
    The following is my effort to understand how to process a
    string, letter, by letter:

    The term "process" is a description of the utmost vagueness,
    failing to elucidate your intended actions. Thus, I would
    counsel you to first articulate in the English vernacular the
    objectives you wish to attain, such that any individual could
    compose the code in accordance with said English text.

    The notion of desiring to manipulate a sequence of characters
    in a "character by character" fashion could potentially
    be a vestigial remnant of prior knowledge acquired from other
    programming languages. Perchance, one might adopt an entirely
    disparate approach in Python to accomplish what you truly aspire
    to achieve. Ergo, it is imperative that we comprehend your genuine
    objectives, so as to proffer you the most optimal assistance.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From MRAB@21:1/5 to Kevin M. Wilson via Python-list on Wed May 29 12:38:17 2024
    On 2024-05-29 05:33, Kevin M. Wilson via Python-list wrote:
    The following is my effort to understand how to process a string, letter, by letter:
    def myfunc(name):        index = 0    howmax = len(name)    # while (index <= howmax):    while (index < howmax):        if (index % 2 == 0):            print('letter to upper = {}, index {}!'.format(name[index], index))       
        name = name[index].upper()            print('if block {} and index {}'.format(name[index], index))        elif (index % 2 > 0):            print(index)            print('Start: elseif block, index is {}, letter is {}'.format(
    index, name))            # print('letter to lower = {}'.format(name[index]))            # print('Already lowercase do noting: name = {}'.format(name[index]))        index += 1        # index = name.upper()
        return name
    myfunc('capitalism')
    Error message:                        Not making sense, index is 1, letter s/b 'a'letter to upper = c, index 0!
    if block C and index 0
    1
    Start: elseif block, index is 1, letter is C --------------------------------------------------------------------------- IndexError Traceback (most recent call last) Cell In[27], line 21
    17 # index = name.upper()
    19 return name
    21 myfunc('capitalism')

    Cell In[27], line 8, in myfunc(name)
    6 while (index < howmax):
    7 if (index % 2 == 0):
    ----> 8 print('letter to upper = {}, index {}!'.format(name[index], index))
    9 name = name[index].upper()
    10 print('if block {} and index {}'.format(name[index], index))

    IndexError: string index out of range***************************************************
    So, I'm doing something... Stupid!! ***************************************************
    "When you pass through the waters, I will be with you: and when you pass through the rivers, they will not sweep over you. When you walk through the fire, you will not be burned: the flames will not set you ablaze."
    Isaiah 43:2

    I think the code is this:

    def myfunc(name):
    index = 0
    howmax = len(name)
    # while (index <= howmax):
    while (index < howmax):
    if (index % 2 == 0):
    print('letter to upper = {}, index {}!'.format(name[index], index))
    name = name[index].upper()
    print('if block {} and index {}'.format(name[index], index))
    elif (index % 2 > 0):
    print(index)
    print('Start: elseif block, index is {}, letter is {}'.format(index, name))
    # print('letter to lower = {}'.format(name[index]))
    # print('Already lowercase do noting: name = {}'.format(name[index]))
    index += 1
    # index = name.upper()
    return name

    myfunc('capitalism')


    What is:

    name = name[index].upper()

    meant to be doing?

    What it's _actually_ doing is getting the character at a given index, converting it to uppercase, and then assigning it to `name`, so `name`
    is now 1 character long.

    It doesn't this when 'index' is 0, so after the first iteration, `name`
    is a single-character string.

    On the second iteration it raises IndexError because the string is only
    1 character long and you're asking for `name[1]`.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Chris Angelico via Python-list on Wed May 29 07:54:09 2024
    On 5/29/2024 3:14 AM, Chris Angelico via Python-list wrote:
    On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list <[email protected]> wrote:
    By which Thomas means stuff like this:

    print(f'if block {name[index]} and index {index}')

    Notice the leading "f'". Personally I wouldn't even go that far, just:

    print('if block', name[index], 'and index', index)

    But there are plenty of places where f-strings are very useful.

    I wouldn't replace str.format() everywhere, nor would I replace
    percent encoding everywhere - but in this case, I think Thomas is
    correct. Not because it's 2024 (f-strings were brought in back in
    2015, so they're hardly chronologically special),

    I only meant that they have been around for 9 years and are usually more readable, so just change over already. I had some inertia over them
    myself (imagine sticking with % formatting!) so I understand.

    but because most of
    this looks like debugging output that can take advantage of this
    feature:

    print(f"if block {name[index]=} {index=}")

    ChrisA

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mats Wichmann@21:1/5 to Grant Edwards via Python-list on Wed May 29 08:05:51 2024
    On 5/29/24 08:02, Grant Edwards via Python-list wrote:
    On 2024-05-29, Chris Angelico via Python-list <[email protected]> wrote:

    print(f"if block {name[index]=} {index=}")

    Holy cow! How did I not know about the f-string {=} thing?


    It's more recent than f-strings in general, so it's not that hard to miss.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry Scott@21:1/5 to All on Wed May 29 15:27:47 2024
    On 29 May 2024, at 05:38, Kevin M. Wilson via Python-list <[email protected]> wrote:

    The format in this email is not of my making, should someone know, how to do this so that it's a readable script do tell!
    KMW


    Your mail program may have a plain-text mode to compose messages in try using that.

    Barry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From MRAB@21:1/5 to Thomas Passin via Python-list on Wed May 29 15:59:50 2024
    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.

    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:

    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]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Kevin M. Wilson on Wed May 29 10:32:39 2024
    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

    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:

    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).



    ***************************************************
    "When you pass through the waters, I will be with you: and when you pass through the rivers, they will not sweep over you. When you walk through the fire, you will not be burned: the flames will not set you ablaze." *Isaiah 43:2
    *


    On Wednesday, May 29, 2024 at 06:19:56 AM MDT, Thomas Passin via
    Python-list <[email protected]> wrote:


    On 5/29/2024 3:14 AM, Chris Angelico via Python-list wrote:
    On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list <[email protected] <mailto:[email protected]>> wrote:
    By which Thomas means stuff like this:

          print(f'if block {name[index]} and index {index}')

    Notice the leading "f'". Personally I wouldn't even go that far, just:

          print('if block', name[index], 'and index', index)

    But there are plenty of places where f-strings are very useful.

    I wouldn't replace str.format() everywhere, nor would I replace
    percent encoding everywhere - but in this case, I think Thomas is
    correct. Not because it's 2024 (f-strings were brought in back in
    2015, so they're hardly chronologically special),

    I only meant that they have been around for 9 years and are usually more readable, so just change over already.  I had some inertia over them
    myself (imagine sticking with % formatting!) so I understand.


    but because most of
    this looks like debugging output that can take advantage of this
    feature:

    print(f"if block {name[index]=} {index=}")

    ChrisA

    --
    https://mail.python.org/mailman/listinfo/python-list <https://mail.python.org/mailman/listinfo/python-list>

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to MRAB via Python-list on Wed May 29 11:44:07 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]



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to MRAB on Wed May 29 18:09:07 2024
    MRAB <[email protected]> wrote or quoted:
    Small mistake there. The original code converted to uppercase on even >indexes, whereas your code does it on odd ones.

    Here follows my humble effort.

    import doctest

    def alternate_uppercase( s ):
    """
    Alternates the case of alphabetic characters in a given string.

    Args:
    s (str): The input string.

    Returns:
    str: The string with alternating uppercase and lowercase letters.

    Examples:
    >>> alternate_uppercase( 'Python is awesome!' )
    'PyThOn Is AwEsOmE!'

    >>> alternate_uppercase( 'ab,c,,d,,,e,,,,f' )
    'Ab,C,,d,,,E,,,,f'

    >>> alternate_uppercase( '' )
    ''
    """
    result =[ None ]* len( s )
    letter_count = 0
    for char_pos, char in enumerate( s ):
    if char.isalpha():
    result[ char_pos ]=\
    ( char.lower if letter_count%2 else char.upper )()
    letter_count += 1
    else:
    result[ char_pos ]= char
    return ''.join( result )

    doctest.testmod()

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)