2
## A little helper program that capitalizes the first letter of a word
def Cap (s):
    s = s.upper()[0]+s[1:]
    return s 

Giving me this error :

Traceback (most recent call last):
  File "\\prov-dc\students\jadewusi\crack2.py", line 447, in <module>
    sys.exit(main(sys.argv[1:]))
  File "\\prov-dc\students\jadewusi\crack2.py", line 398, in main
    foundit = search_method_3("passwords.txt")
  File "\\prov-dc\students\jadewusi\crack2.py", line 253, in search_method_3
    ourguess_pass = Cap(ourguess_pass)
  File "\\prov-dc\students\jadewusi\crack2.py", line 206, in Cap
    s = s.upper()[0]+s[1:]
IndexError: string index out of range
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user2894
  • 21
  • 1
  • 1
  • 2

4 Answers4

4

As others have already noted, the problem is that you're trying to access an item in an empty string. Instead of adding special handling in your implementation, you can simply use capitalize:

'hello'.capitalize()
=> 'Hello'
''.capitalize()
=> ''
shx2
  • 61,779
  • 13
  • 130
  • 153
  • The OP's error clearly indicates that the string with which he is attempting to work is empty. At the moment, this is not a solution to the problem as it ignores the real issue thus will not work either. – anon582847382 Mar 20 '14 at 16:10
  • 3
    capitalize won't throw an error though, it'll just return the empty string (which seems like reasonable behavior in the given use case), so I would argue this is a clear improvement over the approach OP presented. – Moritz Mar 20 '14 at 16:15
  • 1
    This isn't quite the same as what the OP's code does when it works, though. The OP's code capitalizes the first letter but leaves the rest alone. Calling `.capitalize()` lowercases the remaining letters too. For those of us whose family names have two capital letters, as in `MacGregor` or `O'Sullivan`, this can be very annoying. – DSM Mar 20 '14 at 16:32
3

It blows up, presumably, because there is no indexing an empty string.

>>> ''[0]
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
IndexError: string index out of range

And as it has been pointed out, splitting a string to call str.upper() on a single letter can be supplanted by str.capitalize().

Additionally, if you should regularly encounter a situation where this would be passed an empty string, you can handle it a couple of ways:

…#whatever previous code comes before your function
if my_string:
    Cap(my_string)    #or str.capitalize, or…

if my_string being more or less like if len(my_string) > 0.

And there's always ye old try/except, though I think you'll want to consider ye olde refactor first:

#your previous code, leading us to here…
try:
    Cap(my_string)
except IndexError:
    pass

I wouldn't stay married to indexing a string to call str.upper() on a single character, but you may have a unique set of reasons for doing so. All things being equal, though, str.capitalize() performs the same function.

2
>>> s = 'macGregor'
>>> s.capitalize()
'Macgregor'
>>> s[:1].upper() + s[1:]
'MacGregor'
>>> s = ''
>>> s[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>> s[:1].upper() + s[1:]
''

Why does s[1:] not bail on an empty string?

Tutorial on strings says:

Degenerate slice indices are handled gracefully: an index that is too large is replaced by the string size, an upper bound smaller than the lower bound returns an empty string.

See also Python's slice notation.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • +1 I like that. Why does `s[1:]` not bail on an empty string? –  Mar 20 '14 at 18:07
  • The error message mentioned by the OP appears also when the string is not empty. I just printed out the string argument right after entering the function and before accessing it by using `[ ]` and it printed out the string that most certainly was not empty. – rbaleksandar Nov 21 '15 at 10:44
  • @rbaleksandar: `s[0]` raises IndexError only for empty strings. – jfs Nov 21 '15 at 11:14
0

I just had the same error while I was sure that my string wasn't empty. So I thought I'd share this here, so people who get that error have as many potentional reasons as possible.

In my case, I declared a one character string, and python apparently saw it as a char type. It worked when I added another character. I don't know why it doesn't convert it automatically, but this might be a reason that causes an "IndexError: string index out of range", even if you think that the supposed string is not empty.

It might differ between Python versions, I see the original question refers to Python 3. I used Python 2.6 when this happened.

Raimund Krämer
  • 1,255
  • 1
  • 11
  • 29