Why is this giving me an index error in python? - python

In the code below, s refers to a string (although I have tried converting it to a list and I still have the same problem).
s = "".join(s)
if s[-1] == "a":
s += "gram"
I the last item in the string is the letter "a", then the program needs to add the string "gram" to the end of the string 's' represents.
e.g. input:
s = "insta"
output:
instagram
But I keep getting an IndexError, any ideas why?

If s is empty string s[-1] causes IndexError:
>>> s = ""
>>> s[-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
Instead of s[-1] == "a", you can use s.endswith("a"):
>>> s = ""
>>> s.endswith('a')
False
>>> s = "insta"
>>> s.endswith('a')
True

If s is empty, there is no last letter to test:
>>> ''[-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
Use str.endswith() instead:
if s.endswith('a'):
s += 'gram'
str.endswith() does not raise an exception when the string is empty:
>>> 'insta'.endswith('a')
True
>>> ''.endswith('a')
False
Alternatively, using a slice would also work:
if s[-1:] == 'a':
as slices always return a result (at minimum an empty string) but str.endswith() is more self-evident as to what it does to the casual reader of your code.

Related

list index out of range in my coding

Can anyone help me fix this error I keep getting please. I have tried to look for a solution but I can't find any. Below is the error message and also part of my coding
Please enter your class Y or X or Z: Y
Traceback (most recent call last):
File "/Volumes/LIAM'S USB/DEV6 FINAL.py", line 118, in <module>
score=int(items[1])
IndexError: list index out of range
results={
start=True
while (start):
pupil_class=input("\nPlease enter your class Y or X or Z: ")
if pupil_class == ("Y"):
classfile="Class_Y_results.txt"
elif pupil_class == ("X"):
classfile="Class_X_results.txt"
elif pupil_class == ("Z"):
classfile="Class_Z_results.txt"
f=open(classfile,'r')
for line in f:
items=line.split(',')
name=items[0]
score=int(items[1])
if name in results:
results[name].append(score)
else:
results[name]=[]
results[name].append(score)
f.close()
A certain line in your Class_Y_Results.txt only has one entry (not separated by commas), hence the list returned by items=line.split(',') only has a length of 1 (or maybe 0), causing score=int(items[1]) to throw an IndexError.
Sample:
>>> a = "foo,bar"
>>> b = "foo"
>>> len(a.split(','))
2
>>> len(b.split(','))
1
>>> a.split(',')[1]
'bar'
>>> b.split(',')[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
There is probably an empty like in one of your files. This will not contain a comma, so you will not have an item[1], and this produces the error message you see.
Check how many fields you get back from the split to solve this.

Why am I getting this error - searching

I have the following code based on Python School:
EDIT: fixed the indentation of "position" and "return found", and used "raw_input
def linearSearch(item,my_list):
found = False
position = 0
while position < len(my_list) and not found:
if my_list(position) == item:
found = True
position = position + 1
return found
bag = ['book','pencil','pen','note book','sharpner','rubber']
item = raw_input('What item do you want to check for in the bag?')
itemFound = linearSearch(item,bag)
if itemFound:
print('Yes, the item is in the bag')
else:
print('Your item seems not to be in the bag')
When I ran the program, I got the following:
What item do you want to check for in the bag?pencil
Traceback (most recent call last):
File "test.py", line 11, in <module>
item = input('What item do you want to check for in the bag?')
File "<string>", line 1, in <module>
NameError: name 'pencil' is not defined
EDIT: Getting the following error after the edits, although tried to put the item name between quotes
Traceback (most recent call last):
File "test.py", line 12, in <module>
itemFound = linearSearch(item,bag)
File "test.py", line 5, in linearSearch
if my_list(position) == item:
TypeError: 'list' object is not callable
Why am I getting this error?
Thanks.
my_list is a list, index it not call it as a function, so it should be :
if my_list[position] == item:
Another thing, if you are looking for one particular item in my_list, than just return from linearSearch as soon as you found it, no need to keep iterating through the rest of my_list:
if my_list[position] == item:
found = True
return found
The problem is, that you are using python2 and this is python3 code. So it would be best for you to install python3 and this code should run OK. Or in python2 you could you the raw_input function instead of input.
Replace input with raw_input to get a string: input tells Python 2 to evaluate the input string.
That said, your code has more problems: for instance, you increment the position in the wrong place.
I guess this some kind of homework, otherwise there is no need to implement this function just do item in bag. Anyway about the function, there is no need to keep track of the index like that, use range or xrange for that, or having a variable found, just do return True when found and at the end of the function do return False
def linearSearch(item,my_list):
for position in xrange(len(my_list)):
if my_list[position] == item:
return True
return False
you can also use the fact that a list is iterable and do
def linearSearch(item,my_list):
for elem in my_list:
if elem == item:
return True
return False

Using str.replace to replace letters in a string at different placeholders of the string

I have a problem that I am working on. The goal of the problem is to take the string placeholder i. If i is an even placeholder, replace the letter at i with the letter at i -1. If the i place holder is odd, then replace the letter i with the letter at i +1.
Here is my code so far:
def easyCrypto (s):
for i in range (0,len(s)-1):
if i % 2 == 0:
str(s).replace(i,((i-1)))
if i % 2 != 0:
str(s).replace(i,((i+2)))
print (s)
My error:
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
easyCrypto('abc')
File "C:/Python/cjakobhomework7.py", line 4, in easyCrypto
str(s).replace(i,((i-1)))
TypeError: Can't convert 'int' object to str implicitly
update!!
New code based on answers:
def easyCrypto (s):
for i in range (0,len(s)-1):
if i % 2 == 0:
s = str(s).replace(s(i),(s(i-1)))
else:
s = s.replace(s(i), s(i + 1))
print (s)
However I still have the following errors:
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
easyCrypto('abc')
File "C:/Python/cjakobhomework7.py", line 4, in easyCrypto
s = str(s).replace(s(i),(s(i-1)))
TypeError: 'str' object is not callable
Any ideas? thank you
Use s[i] instead of s(i), and likewise for the other indexes.
There are two things here:
str.replace does not automatically stringify its arguments. You need to manually convert them into strings. Remember that: "Explicit is better than implicit."
str.replace does not work in-place because strings are immutable in Python. You need to reassign s to the new string object returned by str.replace.
Your code should be:
s = s.replace(str(i), str(i-1))
Also, you can replace if i % 2 != 0: with else: since the condition of the second if-statement can only be true if the first is false:
if i % 2 == 0:
s = s.replace(str(i), str(i-1))
else:
s = s.replace(str(i), str(i+1))
Regarding your edited question, you are trying to call the string s as a function by placing parenthesis after it. You need to use square brackets to index the string:
>>> 'abcde'[0]
'a'
>>> 'abcde'[3]
'd'
>>>
In your case it would be:
s = s.replace(s[i], s[i-1])
As a general rule of thumb, parenthesis (...) are for calling functions while square brackets [...] are for indexing sequences/containers.

Error trying to strip "0x'

I am trying to strip of "0x" form the hex value using below code and running into error,can anyone suggest how to fix it?
with open(r'\\Network\files\build_ver.txt','r+') as f:
value = int(f.read(), 16)
f.seek(0)
write_value = hex(value + 1)
final_value = format(write_value, 'x')
f.write(final_value)
Error:-
Traceback (most recent call last):
File "build_ver.py", line 5, in <module>
final_value = format(write_value, 'x')
ValueError: Unknown format code 'x' for object of type 'str'
The hex built-in returns a string value:
>>> hex(123)
'0x7b'
>>> type(hex(123))
<class 'str'>
>>>
but format is expecting a hexadecimal value as its first argument:
>>> format('0x7b', 'x')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'x' for object of type 'str'
>>>
>>> format(0x7b, 'x')
'7b'
>>>
Thus, it cannot be used here. Instead, you can just strip off the 0x with slicing:
with open(r'\\Network\files\build_ver.txt','r+') as f:
value = int(f.read(), 16)
f.seek(0)
write_value = hex(value + 1)[2:]
f.write(write_value)
[2:] will get every character in the string except for the first two. See a demonstration below:
>>> hex(123)
'0x7b'
>>> hex(123)[2:]
'7b'
>>>

Python encoding key, minus one character if too long

Here is my code so far:
def code_block(text, key):
itext = int(text)
rkey = int(key)
res= itext + rkey
def last():
return res[-1:]
if res>=11111111:
last()
return res
Here is the task I've been set:
Now we need a function to take a block of code and a key as input, where both are assumed to be 8 digits long, and encrypts each digit of the number with the corresponding digit of the key:
>>> code_block('12341234','12121212')
'24462446'
>>> code_block('66554433','44556677')
'00000000'
Where am I going wrong? Could you point me in the right direction and indicate me how I was wrong?
You are going about this the wrong way. Treat this character by character:
def code_block(text, key):
res = [str(int(c) + int(k))[-1:] for c, k in zip(text, key)]
return ''.join(res)
which gives me:
>>> code_block('12341234','12121212')
'24462446'
>>> code_block('66554433','44556677')
'00000000'
The code sums each and every character separately, turning it back into a string and only using the last character of the result; 9 + 9 is 18, but the result would be '8'.
Your code would sum the whole numbers, but that would result in:
>>> 66554433 + 44556677
111111110
which is not the correct result. Neither did you ever turn your sum back into a string again, so your code, attempting to treat the sum result as a string by slicing it, gave an exception:
>>> code_block('12341234', '12121212')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in code_block
File "<stdin>", line 6, in last
TypeError: 'int' object has no attribute '__getitem__'

Categories