2d Array Python :list index out of range - python

I am new to Python programming and I am trying to write code to check if a DFA( Deterministic Finite Automata) has empty language or not.
I am using 2-d array to store state of the DFA.
On executing the code I keep getting list index out of range. How can I fix this?
Below is the code
top=-1
count=0
n=int(input("\nEnter the no of states"))
mat=[[]]
b=[]
print("\nEnter the transition table")
for i in range(0,n):
for j in range(0,n):
mat.append(input())
finalState=input("\nEnter the final state:")
startState=input("\nEnter the start state:")
for i in range(0,n):
for j in range(0,n):
if mat[i][j]:
b[++top]=j
for k in range(top):
if b[k]==finalState:
count+=1
if count>0:
print("\nLanguage is not empty")
else:
print("\nLanguage is empty")

when you make a 2x2 table, you want mat to be [[1,2],[3,4]], but you're getting [[],1,2,3,4] right now.
Instead, try:
mat = []
for i in range(n):
row = []
for j in range(n):
row.append(input())
mat.append(row)
Also, Python does not have a "++" operator, so b[++top]=j is the same as b[top] = j. If you want to increment top, you have to do that on its own line before you use it to index the list.
On top of that, b has zero elements, so indexing it in any way will cause a crash. If you're trying to increase the size of b by adding new items to it, use append. Then you don't need a top variable at all.
b.append(j)

Related

How can I get this nested for loop skip the first and the last list in the 2D array in order to print out a board surrounded with +'s?

The goal of my Python program is printing out a user-specified N^N board surrounded with +'s using a 2D array. To do that I first created a 2D list with N+2 lines and rows of +'s. Then using a nested for loop, I tried to replace the +'s with " " on indices 1 to N+1(not including) on each row except the first and the last rows, so that my code would print out a N^N board on the inside, surrounded with +'s. However I could not get my program to skip the first and last lines when erasing the +'s, despite excluding their indices in the 2D List in the nested for loop.
Thank you for your help in beforehand!
Here is my code.
This is the desired output (for N=5)
And this is the output of my code.
In your code, you do:
board =[['+'] * (N+2)] * (N+2)
This makes a list with N+2 references to the same list.
So everytime you change a 'middle square' to a white space inside your code(board[x][y] = " ") for a particular row x, you're infact actually changing all the tiles in the column y in your board to the white space simultaneously, since all the rows refer to but one list.
Instead, you should use something like this which actually creates (N+2) separate lists:
board =[['+'] * (N+2) for _ in range(N+2)]
This has also been explained in greater detail in this stackoverflow answer
Making the above change in the code results in the output you desire.
Although, it is a good practice to think of your own approaches & code it out when you're learning, but reading other people's code along with that will give you some hints towards multiple better approaches that you should eventually try to come up with. Here, are my two cents. Keeping it simple!
# board dimension
N = 5
# print board
def print_board(board):
for i in range(N):
for j in range(N):
print(board[i][j], end='')
print()
# declare & populate the board
board = []
for i in range(N):
row = []
for j in range(N):
row.append('+')
board.append(row)
# state of board initially
print_board(board)
print()
# Your logic of removing the plus sign, simply don't include the first & last
# row and column for converting into space
for i in range(1,N-1):
for j in range(1,N-1):
board[i][j] = ' '
print_board(board)
to make this pattern you can simply use for loops.
N = int(input())
for i in range(N+2):
for j in range(N+2):
if(i == 0 or i == N+1 or j == 0 or j == N+1):
print('+', end = '')
else:
print(' ', end = '')
print()

How to avoid counting numbers when do calculation in a for loop in python

I am working on a python algorithm. I have built a for loop to generate the numbers i want. I am going to use these numbers as indices to generate a string called constraint_sty3.
Here is a part of my code:
def constraint():
val=4
ind=[]
for i in range(1,7):
for j in range(val,val+i):
val = val+1
ind.append(j)
if(i < 6):
boundNode.insert(j, 'x%d' % (j-(2*i+1)))
constraint_sty3 = str(boundNode[(j+1])]
My problem is when calculating j+1 , it appears it is not doing the right calculation but doing the counting at the same time. Like a j=j+1. All the other j ,i -related str(boundNode[])like str(boundNode[j]) work well but only this contains j+1 return a problematic result.
You have an error on the last line of your code:
constraint_sty3 = str(boundNode[(j+1])]
it should be:
constraint_sty3 = str(boundNode[(j+1)])
But i dont think this is the error
But by putting (j+1) inside brackets [ ] it will count plus one on that array/list
You should do the calculation before and then append it.

Python: Finding all 6x6 matrices where each value occurs only once in each column and row

I want to generate all 6x6 matrices in Python where each value (integer 1-6) occurs only once in each column and row (like a sudoku puzzle, except for the subgrids). Generating all possible 6x6 matrices and filtering afterwards is not an option I believe as there are ~1.3*10^17 possibilities.
I found that when picking a permutation of the sequence 1-6 (720 in total), the 2nd row for the matrix will only have 265 possibilities, with 3rd-4th-5th row having even less. 6th row should have only 1 possibility if the previous 5 rows have been picked.
I have tried the code below for a 3x3 matrix and it works, however I feel adding more nested loops with more comparisons is not the best way (if a way at all) to tackle this issue. It sounds like it should be doable with a recursion or list comprehension but I can't lay my finger on it.
import itertools
input_list = []
for f in itertools.permutations([1,2,3],3):
input_list.append(f)
for i in input_list:
input_listcopy = input_list.copy()
result = []
result.append(i)
input_listcopy.remove(i)
for j in input_listcopy:
if (i[0] != j[0] and i[1] != j[1] and i[2] != j[2]):
result.append(j)
print(result)
Just to be clear, the output I expect is a 2D list where each element is one row of the matrix, starting from the top:
[[1,2,3],[2,3,1],[3,1,2]]
Thanks in advance!
What about this?
from itertools import permutations
# Define the permutations
length = 6
elements = range(1, length+1)
result = []
for perm in permutations(elements, length):
if not result: # The first permutation is added
result.append(perm)
continue
is_valid_list = []
for row in result:
is_valid = all(perm[idx] != row[idx] for idx in range(length))
is_valid_list.append(is_valid)
if all(is_valid_list):
result.append(perm)
print(result)

Assign numpy ndarray to list

Can someone help me with my question. I have created a loop which in every execution produce a numpy.ndarray of size (5,) but when the loop terminates and I want to print the results of my code it only print the last ndarry of size 5, I tried to assigned the results in a list but I get "too many indices for array"
k=0;
for i in range(M):
for j in range(N):
if table[i, j] != 0:
k=k+1;
inv=np.linalg.inv(np.dot(X.T,X));
theta[k,:] = np.dot(inv,X.T).dot(HSI[i,j,:])
I want to assign the results on theta[] so if I want to print the result from the second execution I will write theta[1] and so on.
Most likely my false is on the last line
A quick sketch, you can amend as necessary
import random
a=[] #start with an empty set
k=0
while k< 5:
b=random.sample(range(1,100), 5) #get a random sample of length 5 within range of 1-100
a.append(b) # add/'append' b to your currently empty set of 'a'
print a #print current contents of 'a'
k=k+1
I've not run this but it seems intuitive.
Good luck!

Getting values for matrix in python

I'm new to python and I tried to store integer values in a 2 dimensional list using loops(I use this logic in C for getting input for matrix). When I run this code, it shows IndexError: list assignment index out of range. What caused this error?
Code to print numbers from 1-9 in matrix form:
num=1
a=[[]]
for i in range(0,3):
for j in range(0,3):
a[i][j]=num
++num
for i in range(0,3):
for j in range(0,3):
print(a[i][j]+" ")
print("\n")
You need to allocate the memory dynamically using append. Also, ++num will not do what you think here and you need num += 1.
num=1
a = []
for i in range(0,3):
a.append([])
for j in range(0,3):
a[i].append(num)
num += 1
for i in range(0,3):
for j in range(0,3):
print(str(a[i][j]) + " ", end="")
print("\n")
Also, you should look at the numpy library which makes the matrix operations and linear algebra easy, efficient and optimized. The equivalent code in numpy would be:
import numpy as np
mat = np.arange(1,10).reshape(3,3)
print(mat)

Categories