Why am i getting a list index out of range error in my code? - python-3.x

The error occurs in line if data[l][0] == value:
def binary_pairs(data, value):
l = 0
h = len(data) - 1
while l < h and data[l]!= value:
m = (h + l) // 2
if data[m][0] == value:
l = m
elif data[m][0] < value:
l = m + 1
else:
h = m - 1
print("done")
if data[l][0] == value:
return l
else:
return -1
example input:
[ [ "dead", ["brian.txt","grail.txt"] ],
[ "eunt", ["brian.txt"] ],
[ "spank", ["grail.txt"] ]
]

I can see two potential issues with your code:
It seems odd that you use both data[l] and data[l][0] in comparisons.
If, for example, l==0 and h==1 and you end up taking the else (h = m - 1), you'd end up with h==-1, which is out of bounds. There could be other similar issues.

I can't run your code right now but here are a few ideas.
If you are trying to solve a problem, rather than trying to learn to write a binary search, consider using Python's bisect module.
http://docs.python.org/2/library/bisect.html
It is best practice in Python to comply with the coding standard called PEP 8; this recommends not using lower-case L as a variable name, or upper-case I.
http://www.python.org/dev/peps/pep-0008/
It would be cleaner to have the loop immediately return the index when it finds the value, rather than having the loop test at the top to make sure the value hasn't been found yet, causing the loop to end and then the value to be returned from the bottom of the function. If the loop ends, you can return -1 at the end of the function.
Your loop checks that the index is < h but does not check that the index is I >= 0. I suspect that this could be your problem.
When debugging a loop like this, it is often helpful to add print statements that log what is going on. You should print the value of the index, and print enough other lines to know whether it is being increased or decreased, and by how much.

Related

IndexError: list index out of range while using nested loops

A = [34,23,1,24,75,33,54,8]
K = 60
solution=[]
for i in range(len(A)):
for j in range(i+1,len(A)):
v=solution[(A[i]+A[j])]
print(v)
Hi, I am trying to get the list with result of individual sums like: 34+23 34+1 34+24 and so on then next 23+1,23+24 and so on.
Your code fails since it's trying to set v to the (A[i]+A[j])th element of solution, which is empty, so that value doesn't exist.
If I understand what you're trying to do, then this should give the desired result.
A = [34,23,1,24,75,33,54,8]
v = [[A[x] + A[i] for i in range(x + 1, len(A))] for x in range(len(A))]
As you can see here,
List index starts from 0 to the (n-1), where n is the len(list).
So A(len(A)) doesn't exist. Which results in the error.
So to fix this replace
len(A)
by
len(A) - 1
inside all instances of range function.

When I try to run my code, I seem to run with an IndexError

When I try to run my code, I seem to run with an IndexError.
def _init_trellis(self, observed, forward=True, init_func=identity):
trellis = [ [None for j in range(len(observed))]
for i in range(len(self.real_states) + 1) ]
if forward:
v = lambda s: self.transition(0, s) * self.emission(s, observed[1])
else:
v = lambda s: self.transition(s, self.end_state)
init_pos = 1 if forward else -1
for state in self.state_nums():
trellis[state][init_pos] = init_func( v(state) )
return trellis
ERROR:
v = lambda s: self.transition(0, s) * self.emission(s, observed[1]) IndexError: list index out of range
Add assertions to your code.
assert(len(observed) > 1)
will ensure that the array is long enough.
Update:
This happens when you try to access a list with an index, but the list does not have that many elements to show.
For example:
a_list = ['a', 'b', 'c']
print(a_list[0] # Prints a.
print(a_list[2] # Prints c.
print(a_list[3] # Gives IndexError.
'''Index of 3 means the 4th element of the list is being accessed.
Since the list only has 3 elements, it gives an index error.'''
In this case, observed[1] giving an index error means observed has only 1 element.
That is, len(observed) is 1.
Original Answer:
Based on the error, ensure that observed is an iterable with a minimum length of 2.

If elif one liner

if i == len(a):
tempList.extend(b[j:])
break
elif j == len(b):
tempList.extend(a[i:])
break
I am using this in a mergesort-program in Python. Is there any way to put this into a oneliner?
Maybe, but let's give a dedicated non-answer: don't even try.
You don't write your code to be short. You write it so that:
it gets the job done in a straight forward manner
it clearly communicates its meaning to human readers
The above code does that already.
In other words: of course being precise is a valuable property of source code. So, when you have to equally readable pieces of code doing the same thing, and one version is a one-liner, and the other is way more lengthy - then you go for the short version.
But I very much doubt that the above can be expressed as readable as above - with less code.
You can use and and or boolean operations to make a pretty readable one-liner:
l = []
a = [1,2,3,4]
b = [8,9,10]
i = 4
j = 2
l.extend(i == len(a) and b[j:] or j == len(b) and a[i:] or [])
l == [10]
i = 0
j = 3
l.extend(i == len(a) and b[j:] or j == len(b) and a[i:] or [])
l == [10, 1, 2, 3, 4]
This example uses next properties:
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.
We have to add or [] to mitigate TypeError: 'bool' object is not iterable exception raised when i == len(a) and j > len(b) (e.g. i == 4 and j == 5).
I'd still prefer an expanded version though.

Euler 4, Modulo issue

Newbie programmer fresh off of code academy. I wanted to keep going so I started the Euler examples. I've got to no.4, https://projecteuler.net/problem=4:
My program is getting to the number 980089 happily enough but decides that this number is divisible by 994. But the other value is actually 986.0050302. That isn't the answer that I'm looking for. So modulo isn't doing its job because there is a remainder of 0.0050302. Why is this happening?
Full code:
x = 999998
g = 2
while g < 99:
e = str(x)
if e[::-1] == str(x):
print(e)
for f in reversed(range(100, 1000)):
f = float(f)
h = x/f
if int(x) % f == 0.000000 and h < 1000:
print("%s and %s" % (f, h))
break
else:
x = x - 1
else:
x = x - 1
Tips on how I could improve my code would be great too, I don't think my while command was used how I originally imagined.
It looks like the general idea of what you're trying to do is to start at a number larger than anything two 3-digit numbers could multiply to, and then just start going down by one seeing if there are any possible 3-digit numbers that will multiply to your current number.
First thing I notice is that your while loop uses g, but you never modify it inside your loop, so it's rather useless. I also notice you're casting x to an int using int(x) at one point, which is not needed because x will always already be an int.
I'm going to try and rewrite your code to do the right thing - let me know if you have any questions about it!
x = 999998
found_an_answer = False
# We'll certainly find an answer before we get here
while x > 10000:
# get the string version of the number
x_string = str(x)
# See if its the same as its reverse
if x_string == x_string[::-1]:
# Print out the palindrome we're currently looking at
print ("Looking for 3-digit factors of " + x_string)
# Let's try all the factors from 999 to 100
for f in reversed(range(100, 1000)):
# First, check if f is a factor of x by checking if the
# remainder is 0 when we divide x by f.
# Then, check if the other factor, x/f, is less than 1000
# to make sure it is three digits
if x%f == 0 and x/f < 1000:
# If we made it here, we found the number!!
print("Found the number!")
print("Number: {}".format(x))
print("Factors: {}, {}".format(f, x/f))
# We set this to be true because using a "break"
# statement will only break out of the inner most
# loop (the one where we're modifying f
found_an_answer = True
break
# Now that we left the inner loop, we can check the
# found_an_answer variable to see if we should
# break out of the outer loop to.
if found_an_answer:
break
# Guess we didn't find an answer yet. LEt's look at the next
# smallest number.
x = x-1
One more little thing - instead of having using a while loop and manually decreasing x inside it, you could just do a for loop counting down, by changing the loop to be
for x in range(999998, 10000, -1):
Then you don't need the x=999998 line or the x = x-1 line.

power (a, n) in PYTHON

POwer in Python. How to write code to display a ^ n using funсtion?
why doesn't this code working?
a = int(input())
n = int(input())
def power(a, n):
for i in range (n):
a=1
a *= n
print(power (a, n))
Few errors:
Changing a will lose your power parameter, use result (or something else).
Move setting result = 1 outside your loop to do so once.
Multiply by a not by n.
Use return to return a value from the function
def power(a, n):
result = 1 # 1 + 2
for _ in range (n):
result *= a # 3
return result # 4
Style notes:
Setting/mutating a parameter is considered bad practice (unless explicitly needed), even if it is immutable as is here.
If you're not going to use the loop variable, you can let the reader know by using the conventional _ to indicate it (_ is a legal variable name, but it is conventional to use it when not needing the variable).
Tip: you can simple use a**n
It doesn't work because your function doesn't return the end value. Add return a to the end of the function.
ALSO:
That is not how a to the power of n is is calculated.
A proper solution:
def power(a,n):
pow_a = a
if n is 0:
return 1
for _ in range(n-1): # Substracting 1 from the input variable n
pow_a *= a # because n==2 means a*a already.
return pow_a
and if you want to be really cool, recursion is the way:
def power_recursive(a,n):
if n is 0:
return 1
elif n is 1:
return a
else:
a *= power_recursive(a,n-1)
return a

Resources