What is IndexError? I keep Getting It - python

Here is my code:
quote = input("Enter a Sentence: ")
a = len(quote)
counter = 0
counter1 = 0
reverse = a
print("The Length of the sentence is",a,"characters long!")
for x in range(0,a):
if str.isspace(quote[x]) == True:
counter = counter + 1
print("The Length of the sentence is",a - counter,"characters long (excluding space...)!")
for x in range(0,a):
if str.isupper(quote[x]) == True:
counter1 = counter1 + 1
print("The number of Upper Case Characters in the sentence is",counter1,"characters!")
print("The number of Lower Case Characters in the sentence is",a-counter1,"characters long!\n")
while reverse >= 1:
r = reverse
print(quote[r])
r = r - 1
It's aim is to find everything about that sentence, but the only problem is the 'While' loop at the bottom. It doesn't seem to work, and it's aim is to 'inverse' the sentence. However, it gives my an error which looks a bit like this:
Traceback (most recent call last):
File "C:\Documents and Settings\ususer\My Documents\Downloads\StringStuff.py", line 27, in <module>
print(quote[r])
IndexError: string index out of range
What Am I doing wrong? Please help!

Python is 0-indexed, so the first character of a string is str[0] and the last is str[len(str) - 1]. So, since you start with reverse = len(quote), at the end you are doing quote[len(quote)], which is one past the end of the string.
So, you should probably start with reverse = a - 1 and your loop at the end should look something like:
while reverse >= 0:
print(quote[reverse])
reverse = reverse - 1

You have run into the common problem that Python starts indexing from 0, but returns the lenght of a list as a valid integer counted from 1. This results that for any list, l[len(l)] will give you IndexError, because a list of length 10 will only have indexes 0...9.
All you have to do is to initialize reverse = len(quote)-1.
You also have to descend your loop variable inside the while loop, so use reverse-=1 instead of r=r-1.

Related

Error in a loop which prints string from last index to first index

I have written this loop to print any input string from its last index to its first index on each separate line. But when I run it, technically, it does work correctly only if the string is all lowercase. It does not work correctly for uppercase strings. In both cases, either the input string is uppercase or lowercase, the following output displays with a traceback which I do not know what for:
OUTPUT :
C:\Users\CM-Ajk\PycharmProjects\Pract\venv\Scripts\python.exe C:/Users/CM-Ajk/PycharmProjects/Pract/main.py
Enter: emadd
d
d
a
m
e
Traceback (most recent call last):
File "C:\Users\CM-Ajk\PycharmProjects\Pract\main.py", line 166, in <module>
print(name[i-1])
IndexError: string index out of range
Process finished with exit code 1
CODE:
i = 0
name = input("Enter: ")
while True:
print(name[i-1])
i = i-1
for i in name[::-1]: print(i)
Try above instead, [::-1] returns reversed string.
i think is better to define a condition for the name length
and start -1 on i
name = input("Enter: ")
i = len(name) - 1
while i > 0 :
print(name[i])
i = i - 1
You can refactor your code as below:
name = 'emadd'
j = len(name)-1
while j>= 0:
print(name[j])
j-= 1
Or optionally handle int with for loop like this:
for i in range(len(enter)-1,-1,-1):
print(enter[i])

String index out of range (Python)

I'm writing a program to encode, decode and crack with the Caesar Cipher.
I have this function that shifts the letters in a string along by a specified amount:
def shift(data, shifter):
alphabet = "abcdefghijklmnopqrstuvwxyz"
data = list(data)
counter = 0 #  we will use this to modify the list while we iterate over it
for letter in data:
letter = letter.lower()
if letter not in alphabet:
counter += 1
continue
lPos = alphabet.find(letter)
if shifter >= 0:
shiftedPos = lPos + (0 - shifter)
else:
shiftedPos = lPos + abs(shifter)
if shiftedPos >= len(alphabet) - 1: shiftedPos -= len(alphabet)
data[counter] = alphabet[shiftedPos] #  update the letter
counter += 1 # advance
data = ''.join(data) # make it into a string again
return data
And I have this function to crack a ciphered string:
def crack(decryptor=None, tries=None):
if decryptor is None and tries is None:
task = getValidInput("Get data from a [f]ile or [s]tdin? >", "Please give either 'f' or 's'.", 'f', 's')
if task == "f": # it's a file
dataFile = getValidFile() # get an open file object
data = dataFile.read() # get the data from the text file. hopefully it's ascii text!
elif task == "s": # we need to get data from stdin
data = input("Enter data to crack >")
tries = getValidInt("Enter tries per sweep >")
else:
data = decryptor
retry = True
shifter = 0
while retry:
for i in range(0, tries):
oput = "Try " + str(i) + ": "
posData = shift(data, shifter)
negData = shift(data, 0 - shifter)
# semitry 1 - positive
oput += posData + ", "
# semitry 2 - negative
negData = ''.join(negData) # make it into a string again
oput += negData
print(oput)
shifter += 1
doRetry = getValidInput("Keep trying (y/n)? > ", "Invalid!", 'y', 'n')
if doRetry == 'n': retry = False
However, after selecting 'y' to continue a few times, I get the following IndexError:
Traceback (most recent call last):
File "CeaserCypher.py", line 152, in <module>
crack()
File "CeaserCypher.py", line 131, in crack
negData = shift(data, 0 - shifter)
File "CeaserCypher.py", line 60, in shift
print(alphabet[shiftedPos])
IndexError: string index out of range
Why am I getting this error and how can I fix it?
IndexError means that the index you are trying to access does not exist. In a string, that means you're trying to get a character from the string at a given point. If that given point does not exist, then you will be trying to get a character that is not inside of the string.
"0123456"[7] tries to get the 7th character in the string, but that index does not exist so "IndexError" is raised.
All valid indexes on a string are less than the length of the string (when you do len(string)). In your case, alphabet[shiftedPos] raises IndexError because shiftedPos is greater than or equal to the length of the string "alphabet".
To my understanding, what you want to do is loop back over the string when you go out of bounds like this. "z" (character 25) gets incrimented by say 2 and becomes character 27. You want that to now become character 2 (letter "b") in this case. Hence, you should use modulo. replace "alphabet[shiftedPos]" with "alphabet[shiftedPos%len(alphabet)]" and I believe this will solve this problem.
Modulo, btw, divides a number by n and gives you the remainder. Effectively, it will subtract n until the number is less than n (so it will always be in the range you want it to be in).

List Index Error on Python

Im writing a program to try to calculate how many times the most repeated word in a list occurs. I keep getting an error that says: index error. Even though when I print the list of my word_list, it shows there are 108 elements. Could someone point me in the right direction as to where my error is?
length = len(word_list)
num = 0
print(length)
while num <= length:
ele = word_list[num]
if ele in wordDict:
wordDict[ele] = wordDict[ele] +1
repeat = repeat + 1
if repeat > highestRepeat:
highestRepeat = repeat
else:
wordDict[ele] = 1
repeat = 1
num = num+1
List indexing goes from 0 to length-1.
In your while loop, you've told the num to go from 0 to length. That's why you have an index error.
Simply change num <= length to num < length. That should fix your code for you.
As an aside, there are much better ways to do this particular task. A simple two liner:
from collections import Counter
print(Counter(word_list).most_common(1))
Counter will calculate the frequencies of each element in your list for you, and most_common(1) will return the element with the highest frequency in your list.
Just to mention that there is a more compact solution to your problem:
word_list =['this' ,'is', 'a', 'test', 'is']
for word in set(word_list):
print word, ": ", word_list.count(word)

Loop Issue with Local Variable

I'm using Python (3.x) to create a simple program for an assignment. It takes a multiline input, and if there is more than one consecutive whitespace it strips them out and replaces it with one whitespace. [That's the easy part.] It must also print the value of the most consecutive whitespaces in the entire input.
Example:
input = ("This is the input.")
Should print:
This is the input.
3
My code is below:
def blanks():
#this function works wonderfully!
all_line_max= []
while True:
try:
strline= input()
if len(strline)>0:
z= (maxspaces(strline))
all_line_max.append(z)
y= ' '.join(strline.split())
print(y)
print(z)
if strline =='END':
break
except:
break
print(all_line_max)
def maxspaces(x):
y= list(x)
count = 0
#this is the number of consecutive spaces we've found so far
counts=[]
for character in y:
count_max= 0
if character == ' ':
count= count + 1
if count > count_max:
count_max = count
counts.append(count_max)
else:
count = 0
return(max(counts))
blanks()
I understand that this is probably horribly inefficient, but it seems to almost work. My issue is this: I would like to, once the loop is finished appending to all_lines_max, print the largest value of that list. However, there doesn't seem to be a way to print the max of that list without doing it on every line, if that makes sense. Any ideas on my convoluted code?
Just print the max of all_line_max, right where you currently print the whole list:
print(max(all_line_max))
but leave it at the top level (so dedent once):
def blanks():
all_line_max = []
while True:
try:
strline = input()
if strline:
z = maxspaces(strline)
all_line_max.append(z)
y = ' '.join(strline.split())
print(y)
if strline == 'END':
break
except Exception:
break
print(max(all_line_max))
and remove the print(z) call, which prints the maximum whitespace count per line.
Your maxspaces() function adds count_max to your counts list each time a space is found; not the most efficient method. You don't even need to keep a list there; count_max needs to be moved out of the loop and will then correctly reflect the maximum space count. You also don't have to turn the sentence into a list, you can directly loop over a string:
def maxspaces(x):
max_count = count = 0
for character in x:
if character == ' ':
count += 1
if count > max_count:
max_count = count
else:
count = 0
return max_count

noob python question, extract letter from list

not sure why this isn't working.
error I'm getting: ord() expected a character, but string of length 0 found
code:
phrase = 'test'
number = 0
text = 0
random1 = ''
while (number <= len(phrase)):
letter = phrase[number:number+1]
text = ord(letter) - ord('a')
....
number = number + 1
if a print letter, i get the t for the first iteration
thanks,
You are failing on your last iteration. Because you let number take the value len(phrase), you are trying to slice your string beyond the end.
For example:
>>> "abc"[3:4]
''
String indices range from 0 to len(s)-1.
BTW: Python gives you much nicer ways to iterate over strings:
phrase = 'test'
for letter in phrase:
text = ord(letter) - ord('a')
....
You are iterating past the end of phrase, try this:
phrase = 'test'
number = 0
text = 0
random1 = ''
while (number < len(phrase)):
letter = phrase[number:number+1]
text = ord(letter) - ord('a')
Note the:
while (number < len(phrase)):
You do indeed have to show more code. What is i? Are you incrementing it each loop?
Typically, if you ARE incrementing i to act just like a for loop, you want to loop such that number < len(phrase), not <=.
Also, you can replace
letter = phrase[number:number+1]
with
letter = phrase[number]
Use for..in instead to process each letter in your string:
Code:
phrase = 'test'
for letter in phrase:
print letter
Output:
t
e
s
t
This would be the more "pythonic" way of doing character iteration. This way you're guaranteed to hit every letter without having to consider hitting the end, as what's happening in your code.
You want a char and not a string, right? Try to replace your
letter = phrase[number:number+1]
with
letter = phrase[number]

Categories