List index out of range in lists and matrix - python

I am a beginner to programming. I always encounter this problem for matrices. Please help me to correct this code and understand the concept behind this. Thank you.
def new_matrix(matrix_size, center_num):
c = matrix_size / 2
if matrix_size % 2 != 0:
p = matrix_size
print("enter a valid size for matrix")
else:
matrix = [[0] * matrix_size for z in range(matrix_size)]
for counting in range(center_num, (matrix_size ** 2) + center_num):
for i in range(2, matrix_size+1):
row = int(c)
column = int(c)
if (i % 2 == 0):
for k in range(1, i + 1): # moving right
column += 1
matrix[column][row] = counting
for k in range(1, i + 1): # moving up
row += 1
matrix[column][row] = counting
else:
for k in range(1, i + 1): # moving left
column -= 1
matrix[column][row] = counting
for k in range(1, i + 1): # moving down
row -= 1
matrix[column][row] = counting
print(matrix)
new_matrix(6, 2)

This issue here seems to be that your indexing is off. The end value in range(n) is n-1, which means that in your for loop when i = matrix_size and then you try to increment the column beyond this, you're trying to assign a value to an index in the matrix that doesn't exist.
You can either try and fix your loop, i.e. reduce it by one, or you can do something like the following,
try:
<your code goes here>
except IndexError:
pass
And then anytime the loop hits an index error it will skip that index and try the next. It's better to fix the code though!

Related

Appearing animation for spiral matrix

I'm trying to make a spiral matrix, but when I tried to make the numbers appear one by one, it only shows the lines one by one.
Please help!
import numpy as np
from time import sleep
n = int(input("Width : "))
k = int(input("Space : "))
a = np.zeros((n,n))
print(a/n)
i = 0 #i line
j = 0 #j column
it = -1 #it upper line
id = n #id downer line
jt = -1 #jt left column
jp = n #jp right column
x = k #x starter number
while j < jp:
while j < jp:
a[i][j] = x
x += k
j +=1
it +=1
i=it+1
j=jp-1
while i< id:
a[i][j] = x
x += k
i +=1
jp -=1
j=jp-1
i=id-1
while j > jt:
a[i][j] = x
x += k
j -=1
id -=1
i=id-1
j=jt+1
while i>it:
a[i][j] = x
x += k
i -=1
jt +=1
i=it+1
j=jt+1
for x in a:
print(x)
sleep(0.1)
Here's an example:
Each number is suppose to appear one by one.
(I'm just putting this here so I can post this since I need to add more details)
Not quite trivial.
I found a solution using an empty character array and cursor-manipulation.
This should result in the desired output:
# replace your last "for x in a" loop by the following
def print_array(arr, block_size=4):
"""
prints a 2-D numpy array in a nicer format
"""
for a in arr:
for elem in a:
print(elem.rjust(block_size), end="")
print(end="\n")
# empty matrix which gets filled with rising numbers
matrix_to_be_filled = np.chararray(a.shape, itemsize=3, unicode=True)
for _ in range(a.size):
# find position of minimum
row, col = np.unravel_index(a.argmin(), a.shape)
# add minimum at correct position
matrix_to_be_filled[row, col] = f'{a.min():.0f}'
# write partially filled matrix
print_array(matrix_to_be_filled)
# delete old minimum in a-matrix
a[row, col] = a.max()+1
sleep(0.1)
# bring cursor back up except for last element
if _ < a.size-1:
print('\033[F'*(matrix_to_be_filled.shape[0]+1))
If you are using pycharm, you need to edit the run/debug configuration and active "emulate terminal in output console" to make the special "move up" character work

Advanced Hailstone - Nested loop / combination

Generating a hailstone sequence that follows the pattern below:
if x is even -> x/2
if x is odd -> [a]x+[b]
where a and b are integer values {0,...,10}, allowing for 121 possible combinations of a and b. I need to list whether the sequence converges for all 1000 x values
I am using python to solve the problem, I'm a beginner at coding with python but am a quick learner and need guidance on how to resolve
`for n in range(1,1001):
for i in a:
for j in b:
while j != 1 & i != 1:
print ("a:", i, "b:", j)
if j % 2 == 0:
j = j / 2
length = length + 1
else:
n = (n * j) + i
if n == 1:
print (n)
'
the above works in that it runs but it doesn't do what I want. It just keeps looping integer one and wont move past it
I see following problems in your code:
range usage, range does not accept list as argument, you should use for i in a: when a is list, rework all your fors accordingly.
broken while syntax: you have too many :s in your while, should be one : (at end)
possibly broken indentation: note that if is not aligned with corresponding else, keep in mind that in Python language indentation is crucial
j = j / b will produce error - you can't divide int by list
you never define n, thus n = (n * a) + 1 and all other lines with n, will produce errors
Keep in mind that my list of problems might be incomplete
'a = [0,1,2,3,4,5,6,7,8,9,10]
b = [0,1,2,3,4,5,6,7,8,9,10]
for n in range(1,1001):
for i in a:
for j in b:
while j != 1 & i != 1:
print ("a:", i, "b:", j)
if j % 2 == 0:
j = j / 2
length = length + 1
else:
n = (n * j) + i
if n == 1:
print (n)'
updates...I want to still be able to understand when it converges and it won't move to the next value

python error - "IndexError: list index out of range"

I'm really new at Python so I apologize in advance if this is a really dumb question. Pretty much, I'm writing a longest common subsequence algorithm with dynamic programming.
Whenever I try to run it, I get the IndexError: list index out of range, and I don't know why because the array I'm adding values to never changes in size. Code snippet for clarity:
def LCS(sequence1, sequence2):
n = len(sequence1)
m = len(sequence2)
D = [[0 for num in range(0,n)]for number in range(0, m)]
for i in range(1, n):
for j in range(1, m):
if(sequence1[i] == sequence2[j]):
D[i][j] = D[i-1][j-1] + 1
else:
D[i][j] = max(D[i-1][j], D[i][j-1])
print D[n][m]
There seem to be two problems:
In the definition of D, you should swap n and m
D = [[0 for num in range(0, m)] for number in range(0, n)]
You have to print (or better: return) the last element of the matrix
return D[n-1][m-1] # or just D[-1][-1]
The issue is with total rows and columns of the matrix(D). Size should be (m+1)*(n+1) and then loop over the matrix. Otherwise you need to return D[m-1][n-1].
def LCS(sequence1, sequence2):
n = len(sequence1)
m = len(sequence2)
D = [[0 for num in range(0,n+1)]for number in range(0, m+1)]
for i in range(1, n+1):
for j in range(1, m+1):
if(sequence1[i-1] == sequence2[j-1]):
D[i][j] = D[i-1][j-1] + 1
else:
D[i][j] = max(D[i-1][j], D[i][j-1])
print D[n][m]
LCS('abcdef' , 'defjkl')

What will be the big-O notation for this code?

Will it be O(n) or greater?
n = length of list
a is a list of integers that is very long
final_count=0
while(n>1):
i=0
j=1
while(a[i+1]==a[i]):
i=i+1
j=j+1
if i==n-1:
break
for k in range(j):
a.pop(0)
final_count=final_count+j*(n-j)
n=n-j
The way I see it, your code would be O(n) if it wasn’t for the a.pop(0) part. Since lists are implemented as arrays in memory, removing an element at the top means that all elements in the array need to moved as well. So removing from a list is O(n). You do that in a loop over j and as far as I can tell, in the end, the sum of all js will be the same as n, so you are removing the item n times from the list, making this part quadratic (O(n²)).
You can avoid this though by not modifying your list, and just keeping track of the initial index. This not only removes the need for the pop, but also the loop over j, making the complexity calculation a bit more straight-forward:
final_count = 0
offset = 0
while n > 1:
i = 0
j = 1
while a[offset + i + 1] == a[offset + i]:
i += 1
j += 1
if i == n - 1:
break
offset += j
final_count += j * (n - j)
n = n - j
Btw. it’s not exactly clear to me why you keep track of j, since j = i + 1 at every time, so you can get rid of that, making the code a bit simpler. And at the very end j * (n - j) is exactly j * n if you first adjust n:
final_count = 0
offset = 0
while n > 1:
i = 0
while a[offset + i + 1] == a[offset + i]:
i += 1
if i == n - 1:
break
offset += i + 1
n = n - (i + 1)
final_count += (i + 1) * n
One final note: As you may notice, offset is now counting from zero to the length of your list, while n is doing the reverse, counting from the length of your list to zero. You could probably combine this, so you don’t need both.

Implementing Median of Median Selection Algorithm in Python

Okay. I give up. I've been trying to implement the median of medians algorithm but I am continually given the wrong result. I know there is a lot of code below, but I can't find my error, and each chunk of code has a fairly process design. Quicksort is what I use to sort the medians I get from the median of medians pivot selection. Should be a straightforward quicksort implementation. getMean simply returns the mean of a given list.
getPivot is what I use to select the pivot. It runs through the list, taking 5 integers at a time, finding the mean of those integers, placing that mean into a list c, then finding the median of c. That is the pivot I use for the dSelect algorithm.
The dSelect algorithm is simple in theory. The base case returns an item when the list is 1 item long. Otherwise, much like in quickSort, I iterate over the list. If the number I am currently on, j, is less than the pivot, I move it to the left of the list, i, and increment i. If it is larger, I move it to the right of the list, i + 1, and do not increment i. After this loops through the entire list, I should have the pivot in its proper index, and print statements indicate that I do. At this point, I recurse to the left or the right depending on whether the pivot is greater than or less than the position I am trying to find.
I am not sure what other print statements to test at this point, so I'm turning to anyone dedicated enough to take a stab at this code. I know there are related topics, I know I could do more print statements, but believe me, I've tried. What should be a simple algo has got me quite stumped.
def quickSort(m, left, right):
if right - left <= 1:
return m
pivot = m[left]
i = left + 1
j = left + 1
for j in range(j, right):
if m[j] < pivot:
m[j], m[i] = m[i], m[j]
i += 1
elif m[j] == pivot:
m[j], m[i] = m[i], m[j]
print m
m[left], m[i-1] = m[i-1], m[left]
m = quickSort(m, left, i-1)
m = quickSort(m, i, right)
print m
return m
def getMedian(list):
length = len(list)
if length <= 1:
return list[0]
elif length % 2 == 0:
i = length/2
return list[i]
else:
i = (length + 1)/2
return list[i]
def getPivot(m):
c = []
i = 0
while i <= len(m) - 1:
tempList = []
j = 0
while j < 5 and i <= len(m) - 1:
tempList.append(m[i])
i = i + 1
j = j + 1
tempList = quickSort(tempList, 0, len(tempList) - 1)
c.append(getMedian(tempList))
c = quickSort(c, 0, len(c) - 1)
medianOfMedians = getMedian(c)
return medianOfMedians
def dSelect(m, position):
pivot = getPivot(m)
i = 0
j = 0
if len(m) <= 1:
return m[0]
for j in range(0, len(m)):
if m[j] < pivot:
m[j], m[i] = m[i], m[j]
i += 1
elif m[j] == pivot:
m[j], m[i] = m[i], m[j]
print "i: " + str(i)
print "j: " + str(j)
print "index of pivot: " + str(m.index(pivot))
print "pivot: " + str(pivot) + " list: " + str(m)
if m.index(pivot) == position:
return pivot
elif m.index(pivot) > position:
return dSelect(m[0:i], position)
else:
return dSelect(m[i:], position - i)
The biggest issue is with this line here:
i = (length + 1)/2
if list = [1, 2, 3, 4, 5, 6, 7] the answer should be 4 which is list[3]. Your version looks like the following:
i = (7 + 1) / 2
and so i is equal to 4 instead of 3. Similar problem with the even length list part although that shouldn't be as big of an issue.

Categories