Error in below python code - python

I am new to python program. the below code has some error with list.
len = []
def collatz_length(n,count):
++count
if len[n]:
return len[n]
if n == 1:
len[n] = count
elif n & 1:
len[n] = count + collatz_length(3 * n + 1,0)
else:
len[n] = count + collatz_length(n >> 1,0)
return len[n]
print collatz_length(13,0)
i am trying to figure out the length.But the gives error
OUTPUT
Traceback (most recent call last):
File "collatz.py", line 21, in <module>
print collatz_length(13,0)
File "collatz.py", line 9, in collatz_length
if len[n]:
IndexError: list index out of range

It means that n is beyond the length of the list (which is initially zero). Rather than doing len[n], you want to see if n is in your list:
# Renaming your array to my_array so that it doesn't shadow the len() function,
# It's also better to put it as a parameter, not a global
def collatz_length(n, count, my_array):
if n < len(my_array):
return my_array[n]
# ... all your elses

If you have an array with 5 things in it, and try to access array[5], you are reading outside the bounds of the array. I think that is what is happening, but your code is also very hard to understand. If that's not what is happening, you may need to add some comments or otherwise clarify what you are doing. It looks like you have an empty array and are trying to access location 13 in it, which makes no sense.

Related

Beginner trying to debug an easy program

I'm a student and am just beginning to learn code. Right now I'm working with Python and have a program I think should work, but just returns some errors that I don't understand:
Traceback (most recent call last): File "C:\Program
Files\Notepad++\1913lab3.py", line 23, in print(most(odd,
[]))
File "C:\Program Files\Notepad++\1913lab3.py", line 9, in most N =
S[i] UnboundLocalError: local variable 'i' referenced before
assignment
I don't understand what the first error tells me, but the I think I understand the second one, but I don't understand why I'm getting it. I don't think i is a local variable as I defined it right away in the beginning. Here's the code:
t = 0
f = 0
i = 0
def odd(N):
return N % 2 != 0
def most(P, S):
N = S[i]
if P == True:
t += 1
else:
f += 1
i += 1
if i < len(S):
most(P, S)
else:
if t > f:
return 'True'
else:
return 'False'
print(most(odd, []))
print(most(odd, [0]))
print(most(odd, [1]))
print(most(odd, [1, 2]))
print(most(odd, [1, 2, 3]))
The assignment is to define a recursive function (most()). The function takes one function and one list as its arguments (P and S). I can't use loops or local variables. Here's a quote from the assignment:
"P is a function of one argument that returns either True or False,
and S is a list. The function most calls P on each element of S. It
must return True if P returns True more often than it returns False.
It must return False otherwise."
The 5 print commands are just 5 examples that I need to work for credit, but this program needs to work for all lists. If anyone can help me fix these errors, that'd be great. (Also, any general Python tips would be welcome.)
By default any variable that is modified within a function is assumed to be local to that function. So if you have i += 1, i must be defined within the function first. Or you have to declare i as a global first (global i) so that python knows it is refering to the i you have defined (first) outside the function. But beware with globals, they are often dangerous (as they make it hard to keep track what is going on) and should be avoided if possible.

Q: list assignment index out of range

>>> def lcm(a,b):
if a<<b:
c=a
a=b
b=c
c=0
lit=[a,b,c]
n=3
while (not lit[n%3]%lit[(n%3)+1]==0):
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
if lit[(n%3)+2]==0:
d=lit[(n%3)+2]
print d
else:
n=n+1
This is the code, trying to build a function lcm that finds the least common multiplier of a and b. Not really the cleanest code of the bunch, but sadly this was all I could do. It would really be nice if this lump of code could be a little lighter.
So, err, back to the point, I called for lcm, and it just blurts out error messages.
This is what it says:
>>> lcm(78696,19332)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
lcm(78696,19332)
File "<pyshell#1>", line 10, in lcm
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
IndexError: list assignment index out of range
Aaaaand I have got absolutely no idea what I am supposed to do now.
What can I do now?
Python lists are zero-indexed.
So lit[0] = a, lit[1] = b, and lit[2] = c.
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
If n = 1, then (n%3)+2 equals 3. If n = 2, then (n%3)+2 equals 4.
If you want to guarantee that you're accessing your list at a valid index, then you want to % by the length of the list- which you're doing, just not at the right place.
Without looking too deeply into your code, I think it's just another lesson that order of operations matters. Try (n+2)%3 instead of (n%3)+2.
x%3 will always be within the range [0, 2]- so that's why you want to mod at the very end. (x%3+n ends up in the range [n, 2+n].)
n%3 can be as big as 2. so n%3 + 1 could be as much as 3. The list lit has only 3 items, so at this line,
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
if n%3 == 2, then accessing lit[(n%3)+1] will lead to index out of range error.

Python 3 Index Error

Consider the following code:
def anadist(string1, string2):
string1_list = []
string2_list = []
for i in range(len(string1)):
string1_list.append(string1[i])
for i in range(len(string2)):
string2_list.append(string2[i])
# Test returns for checking
# return (string1_list,string2_list)
# return len(string1_list)
# return len(string2_list)
for i in range(0,len(string1_list)):
try:
if (string1_list[i]) in string2_list:
com = string1_list.pop(i)
com_index = string2_list.index(com)
string2_list.pop(com_index)
else:
pass
except ValueError:
pass
return string1_list
def main():
str1 = input("Enter string #1 >>> ")
str2 = input("Enter string #2 >>> ")
result = anadist(str1, str2)
print(result)
#Boilerplate Check
if __name__ == "__main__":
main()
Running in Python 3.5.2 raises an IndexError:
Traceback (most recent call last):
File "E:\CSE107L\Practice\anadist.py", line 34, in <module>
main()
File "E:\CSE107L\Practice\anadist.py", line 29, in main
result = anadist(str1, str2)
File "E:\CSE107L\Practice\anadist.py", line 15, in anadist
if (string1_list[i]) in string2_list:
IndexError: list index out of range
And I can't find what is going wrong. I wrote another code similar and that works:
def main():
lst = [1,2,3,4,5]
lst2 = [5,6,7,8,9]
for i in range(len(lst)):
if lst[i] in lst2:
com = lst.pop(i)
lst2_index = lst2.index(com)
lst2.pop(lst2_index)
else:
pass
print(lst)
if __name__ == "__main__":
main()
I feel the error is coming from the way I am forming string1_list. This code is for how many steps it takes to form an anagram of a pair of words.
In some cases, you are shortening string_list1 while you're iterating over it:
if (string1_list[i]) in string2_list:
com = string1_list.pop(i) # string1_list gets shorter here
However, your range doesn't change. It's still going to go from 0 until it counts up to the original length of string1_list (exclusive). This will cause the IndexError any time string1_list.pop(i) is called.
One possible solution would be to use a while loop instead:
i = 0
while i < len(string1_list):
try:
if string1_list[i] in string2_list:
com = string1_list.pop(i)
com_index = string2_list.index(com)
string2_list.pop(com_index)
else:
pass
except ValueError:
pass
i += 1
This will cause the loop termination condition to be checked after each iteration. If you remove some elements from string1_list, it'll still be OK because the loop will terminate before i gets big enough to overrun the bounds of it's container.
Your issue is that you are mutating the string1_list within the for loop by performing string1_list.pop(i). The length of the list is being reduced within the for loop by doing string1_list.pop(i), but you are still iterating over the length of the original list.
Your second lot of code works only because you only pop on the last iteration of the loop.
Your second attempt works simply because a "match" is found only in the last element 5 and as such when you mutate your list lst it is during the last iteration and has no effect.
The problem with your first attempt is that you might remove from the beginning of the list. The counter doesn't get updated and at some point might reach a value that no longer exists in the list (it has been popped). Try running it with no matches in the input and see that it works.
In general, don't mutate your list while iterating through it. Instead of the:
for i in range(len(lst)):
# mutate list
'idiom', you should opt for the:
for i in list(list_object): # or for i in list_object[:]:
which makes a copy first and allows you to mutate the original list_object by keeping mutating and looping separate.

Variation of suffix array in python

I'm relatively new to computer science, and I'm learning how to code in python. I'm trying to figure out how to make a function that takes a list and returns a list of suffixes from the inputted list, in order from shortest length to longest length. For example, entering
[3,4,2,-9,7,6,1]
to the function would return
[[],[1],[6,1],[7,6,1],[-9,7,6,1],[2,-9,7,6,1],[4,2,-9,7,6,1],[3,4,2,-9,7,6,1]]
I've tried several approaches, but so far I'm not having much luck. Here is what I have so far:
def h(m):
newlist = []
x = 0
y = (len[m])-1
while x in range(y):
sublist = []
sublist = sublist + m[x:y]
newlist.append(sublist)
x += 1
return new list
When I try to run the function by entering something like
a = [3,4,2,-9,7,6,1]
h(a)
I get an error:
Traceback (most recent call last):
File "<pyshell#239>", line 1, in <module>
h(a)
File "<pyshell#238>", line 4, in h
y = (len[m])-1
TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
My objective with this bit of code was simply to create a the list of suffixes without sorting them by length. After I figure out how to create this new list I will add the sorting bit of the code. Keep in mind this is not a homework assignment. Any help would be greatly appreciated!
Possible solution is using list comprehension:
[l[i:] for i in range(len(l), -1, -1)]
This code uses slicing and list comprehension to simply return a list of slices from the end. Using your code, small modification is required - len is a function and not a dictionary, therefore you need to use the call operator () instead of subscript operator [].
y = len(m) - 1
That will not yield correct result though, because you will not get the last suffix and empty suffix. In order to cover these two, you will need to modify y or the loop to cover them
y = len(m) + 1
or better
while x in range(y + 1):
use parenthesis to get the length of the list:
y = len(m) - 1
Your error is in your len:
(len[m]) - 1
len is a function, and you can't index or slice or the what not. Do this instead:
y = len(m) - 1
There's also one other error:
return new list
Should be: (You can't have spaces in variables)
return newlist

Convert tuple to concatenating the digits by recursion

def untuplify(tpl):
if len(tpl) == 0:
return 0
n = 0
while n <= len(tpl) - 1 :
x += str(tpl[n])
n += 1
return x
Why am I getting this error UnboundLocalError: local variable 'x' referenced before assignment ??
untuplify((1, 2, 3, 4, 5))
Should give me 12345
You are getting that error because in the line x+=str(tpl[n]) your compiler don't know x
First, there is no recursion here, you never call untuplify from within itself.
Second, the error message is because of the line
x += str(tpl[n])
You've never used x before, and now you want to add to it. That doesn't work.
Place a
x = ''
before the loop?
There are vastly easier ways to do this, but I think you're doing this as an exercise and aren't interested in them.
Edit: also, are you sure it makes sense to return the number 0 if the tuple is empty? Isn't the function supposed to return a string?
Because you are not initializing x:
n, x = 0, ''

Categories

Resources