Discussion:
Flubbed it in the second interation through the string: range error... HOW?
(too old to reply)
Kevin M. Wilson
2024-05-29 04:33:23 UTC
Permalink
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
Kevin M. Wilson
2024-05-29 04:38:55 UTC
Permalink
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

***************************************************
"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


----- Forwarded Message ----- From: Kevin M. Wilson via Python-list <python-***@python.org>To: python-***@python.org <python-***@python.org>Sent: Tuesday, May 28, 2024 at 10:35:23 PM MDTSubject: Flubbed it in the second interation through the string: range error... HOW?
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
--
https://mail.python.org/mailman/listinfo/python-list
Thomas Passin
2024-05-29 05:14:07 UTC
Permalink
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())
Post by Kevin M. Wilson
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)
----> 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
Cameron Simpson
2024-05-29 05:52:47 UTC
Permalink
Post by Thomas Passin
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.
Chris Angelico
2024-05-29 07:14:51 UTC
Permalink
On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list
Post by Cameron Simpson
print(f'if block {name[index]} and index {index}')
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), but because most of
this looks like debugging output that can take advantage of this
feature:

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

ChrisA
MRAB
2024-05-29 11:38:17 UTC
Permalink
Post by Kevin M. Wilson
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)
----> 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]`.
Stefan Ram
2024-05-29 11:59:20 UTC
Permalink
Post by Kevin M. Wilson
The following is my effort to understand how to process a
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.
Thomas Passin
2024-05-29 11:54:09 UTC
Permalink
Post by Chris Angelico
On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list
Post by Cameron Simpson
print(f'if block {name[index]} and index {index}')
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.
Post by Chris Angelico
but because most of
this looks like debugging output that can take advantage of this
print(f"if block {name[index]=} {index=}")
ChrisA
2***@potatochowder.com
2024-05-29 13:05:16 UTC
Permalink
On 2024-05-29 at 17:14:51 +1000,
Post by Chris Angelico
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), but because most of
this looks like debugging output that can take advantage of this
print(f"if block {name[index]=} {index=}")
defsnark:

After years of getopt (and even more, if you include non-Python
experience), I'm glad I decided to wait a decade before chugging the
optparse koolaid.

(For the history-impaired, getopt existed long before Python and will
likely exist long after it, but getopt's "replacement" optparse lasted
only from 2003 until 2011.)

That said, I agree that the = thing makes f-strings eminently useful for
debugging, and I wholeheartedly agree with not fixing things that aren't
broken.
Chris Angelico
2024-05-29 13:58:09 UTC
Permalink
On Wed, 29 May 2024 at 23:06, Dan Sommers via Python-list
Post by 2***@potatochowder.com
(For the history-impaired, getopt existed long before Python and will
likely exist long after it, but getopt's "replacement" optparse lasted
only from 2003 until 2011.)
Depends on your definition of "lasted". It's not getting developed
further, but it's still there. If you started using it, you're welcome
to keep going.

https://docs.python.org/3/library/optparse.html

ChrisA
Grant Edwards
2024-05-29 14:02:03 UTC
Permalink
Post by Chris Angelico
print(f"if block {name[index]=} {index=}")
Holy cow! How did I not know about the f-string {=} thing?
--
Grant
Mats Wichmann
2024-05-29 14:05:51 UTC
Permalink
Post by Grant Edwards
Post by Chris Angelico
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.
Thomas Passin
2024-05-29 14:32:39 UTC
Permalink
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
Post by Chris Angelico
On Wed, 29 May 2024 at 16:03, Cameron Simpson via Python-list
      print(f'if block {name[index]} and index {index}')
      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.
Post by Chris Angelico
but because most of
this looks like debugging output that can take advantage of this
print(f"if block {name[index]=} {index=}")
ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
<https://mail.python.org/mailman/listinfo/python-list>
Barry Scott
2024-05-29 14:27:47 UTC
Permalink
Post by Kevin M. Wilson
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
MRAB
2024-05-29 14:59:50 UTC
Permalink
Post by Thomas Passin
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
s1 = 'this is a test'
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.
Post by Thomas Passin
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
"""Convert character ch if convert_this is True.
Don't convert spaces.
"""
return (convert_this, ch)
return (False, ch.upper())
return (True, ch)
convert_next = False
result = ''
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]
Stefan Ram
2024-05-29 18:09:07 UTC
Permalink
Post by MRAB
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.
Post by MRAB
alternate_uppercase( 'Python is awesome!' )
'PyThOn Is AwEsOmE!'
Post by MRAB
alternate_uppercase( 'ab,c,,d,,,e,,,,f' )
'Ab,C,,d,,,E,,,,f'
Post by MRAB
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()

Grant Edwards
2024-05-29 15:35:46 UTC
Permalink
Post by Mats Wichmann
Post by Grant Edwards
Post by Chris Angelico
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.
I really should make a habit of reading through the "what's new" pages
when new releases come out...

--
Grant
Thomas Passin
2024-05-29 15:44:07 UTC
Permalink
Post by MRAB
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
s1 = 'this is a test'
      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?
Post by MRAB
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
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.
Post by MRAB
      """Convert character ch if convert_this is True.
      Don't convert spaces.
      """
              return (convert_this, ch)
              return (False, ch.upper())
      return (True, ch)
convert_next = False
result = ''
      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]
Loading...