python matrix multiplication check if number of rows of 1st matrix is equal to number of columns of 2nd matrix - python-3.x

I need to perform a matrix multiplication between 2 matrices by taking user input. The below code works fine for the multiplication part but if the no. of rows of 1st matrix are not equal to the no. of columns of the 2nd matrix then it should print NOT POSSIBLE and exit. But it still goes on to add the elements of the matrices. What could possibly be wrong in this code & what could be the solution for the same. Any help would be greatly appreciated
def p_mat(M,row_n,col_n):
for i in range(row_n):
for j in range(col_n):
print(M[i][j],end=" ")
print()
def mat_mul(A_rows,A_cols,A,B_rows,B_cols,B):
if A_cols != B_rows:
print("NOT POSSIBLE")
else:
C = [[0 for i in range(B_cols)] for j in range(A_rows)]
for i in range(A_rows) :
for j in range(B_cols) :
C[i][j] = 0
for k in range(B_rows) :
C[i][j] += A[i][k] * B[k][j]
p_mat(C, A_rows, B_cols)
if __name__== "__main__":
A_rows = int(input("Enter number of rows of 1st matrix: "))
A_cols = int(input("Enter number of columns of 1st matrix: "))
B_rows = int(input("Enter number of rows of 2nd matrix: "))
B_cols = int(input("Enter number of columns of 2nd matrix: "))
##### Initialization of matrix A and B #####
A = [[0 for i in range(B_cols)] for j in range(A_rows)]
B = [[0 for i in range(B_cols)] for j in range(A_rows)]
print("Enter the elements of the 1st matrix: ")
for i in range(A_rows):
for j in range(A_cols):
A[i][j] = int(input("A[" + str(i) + "][" + str(j) + "]: "))
print("Enter the elements of the 2nd matrix: ")
for i in range(B_rows):
for j in range(B_cols):
B[i][j] = int(input("B[" + str(i) + "][" + str(j) + "]:"))
##### Print the 1st & 2nd matrices #####
print("First Matrix : ")
p_mat(A,A_rows,A_cols)
print("Second Matrix : ")
p_mat(B,B_rows,B_cols)
### Function call to multiply the matrices ###
mat_mul(A_rows,A_cols,A,B_rows,B_cols,B)

For matrix multiplication, the number of columns in the first matrix must be equal to the number of rows in the second matrix.
If you want to check the no of rows of 1st matrix and the no. of columns of the 2nd matrix then change the if A_cols != B_rows to if A_rows != B_cols
With your current code, it will print NOT POSSIBLE when A_cols != B_rows which is right.
Ex.
Enter number of rows of 1st matrix: 2
Enter number of columns of 1st matrix: 3
Enter number of rows of 2nd matrix: 2
Enter number of columns of 2nd matrix: 3
Enter the elements of the 1st matrix:
A[0][0]: 1
A[0][1]: 2
A[0][2]: 3
A[1][0]: 4
A[1][1]: 5
A[1][2]: 6
Enter the elements of the 2nd matrix:
B[0][0]:1
B[0][1]:2
B[0][2]:3
B[1][0]:4
B[1][1]:5
B[1][2]:6
First Matrix :
1 2 3
4 5 6
Second Matrix :
1 2 3
4 5 6
NOT POSSIBLE
Another mistake in the code is when you are initialize the Matrices.You are doing
A = [[0 for i in range(B_cols)] for j in range(A_rows)]
B = [[0 for i in range(B_cols)] for j in range(A_rows)]
If the B_cols are smaller than the A_cols when you adding elements in A it will raise IndexError
The same if the B_cols are greater than A_cols when you are adding elements to B will raise IndexError.
Change it to
A = [[0 for i in range(A_cols)] for j in range(A_rows)]
B = [[0 for i in range(B_cols)] for j in range(B_rows)]

Related

Sum of two square matrixes code keeps failing

I have this task: 'Write a program that adds two square matrices. The program will read the dimension of the matrix, N, and will then read N*N numbers representing the first matrix, row by row. It will then read another N*N numbers representing the second matrix. The program will output the resulting matrix, one row per line. ' for which I wrote the code below. However, the platform I am doing the task on keeps saying that 1 of 2 tests failed...It works just fine for me. Maybe the problem is on their side?
from operator import add
#Enter a digit for you matrix, e.g if you want it to be 2x2 enter 2
n = int(input())
#Input digits for both matrixes rows one at a time
matrix1_r1 = [int(input()) for x in range(n)]
matrix1_r2 = [int(input()) for x in range(n)]
matrix2_r1 = [int(input()) for x in range(n)]
matrix2_r2 = [int(input()) for x in range(n)]
final1 = list(map(add, matrix1_r1, matrix2_r1))
final2 = list(map(add, matrix1_r2, matrix2_r2))
print(final1)
print(final2)
Their sample innput is:
2
1
2
3
4
5
6
7
8
their sample output is:
[6, 8]
[10, 12]
Your code works for the example, and for any input that is 2 by 2. It will fail for any other sized matrix, because your code only computes two rows for each matrix. Rather than hard-coding something so fundamental, you should be using nested loops and a list of lists to get the right number of rows. Or, if you want to be a little fancy, list comprehensions can do it all really neatly:
n = int(input())
matrix1 = [[int(input()) for col in range(n)] for row in range(n)]
matrix2 = [[int(input()) for col in range(n)] for row in range(n)]
matrix_sum = [[a + b for a, b in zip(row1, row2)] for row1, row2 in zip(matrix1, matrix2)]
print(*matrix_sum, sep='\n')

A variable will be changed for every iteration and I want to print it into a dictionary as key

for i in range(N):
k1,k2,k3,k4 = input().split(' ')
k2 = float(k2)
k3 = float(k3)
k4 = float(k4)
score = (k2+k3+k4)/3
a = {print(k1) : score}
The input has 4 values: string, int, int, int.
I want to set the value of k1 as key and the score as value.
When I tried the above code, this was the output:
1
You first need to initialise the dictionary and then you can insert items into it with dictionary[key] = value
# Initialise a dictionary where we can store values to
a = {}
# How many times we will ask for values
n = int(input('number of values: '))
for i in range(n):
k1,k2,k3,k4 = input('give input: ').split(' ')
k2 = float(k2)
k3 = float(k3)
k4 = float(k4)
score = (k2+k3+k4)/3
# Store the score value to k1 key
a[k1] = score
# Print the dictionary after the loop has been completed
print(a)
This will do the following:
number of values: 3
give input: first 1 2 3
give input: second 4 5 6
give input: third 10 20 30
{'first': 2.0, 'second': 5.0, 'third': 20.0}
Here's the code that work (very small modification from your original code)
for i in range(4):
k1, k2, k3, k4 = input().split(" ")
k2 = float(k2)
k3 = float(k3)
k4 = float(k4)
score = (k2 + k3 + k4) / 3
print({k1: score})
If you run it with the value of 1 10 20 30 the script returns:
{'1': 20.0}

Inserting Elements into a 2 Dimensional List

elements = []
i,j = 0,0
while(i<3):
while(j<3):
elements[i][j] = int(input())
j+=1
i+=1
j=0
print(elements)
I'm trying to insert elements into 2 dimensional list by getting the input from the user. I'm unable to do so, its giving me a IndexError.
IndexError: list assignment index out of range
I'm expecting a 3x3 list.
Something like :
elements = [
[0,1,2],
[3,4,5],
[6,7,8]
]
What am I doing wrong here? [I do not wish to use Numpy or other libraries atm]
Problem with your case is that the list is initialized with size 0 and as a empty list. So, when you have to set value at some index it throws up error saying that the specified index is out of range because the index doesn't exist.
My approach mutates the existing list in-place or in other words appends a value.
Get size as input first
>>> rows = int(input("Enter no. of rows: "))
Enter no. of rows: 2
>>> cols = int(input("Enter no. of Columns: "))
Enter no. of Columns: 2
Create a list and loop through ranges
>>> l = []
>>> for i in range(rows):
... row_vals = []
... for j in range(cols):
... row_vals.append(int(input(f"Enter value at {i}th row and {j}th column: ")))
... l.append(row_vals)
...
Enter value at 0th row and 0th column: 0
Enter value at 0th row and 1th column: 1
Enter value at 1th row and 0th column: 1
Enter value at 1th row and 1th column: 0
>>> l
[[0, 1], [1, 0]]
This will sove your problem:
elements = []
i, j = 0,0
while(i<3):
elements.append([])
while(j<3):
elements[i].append(int(input()))
j+=1
i+=1
j = 0
print(elements)
The points:
Lists in python are not automatically appended when you access an index, you have to build the list.
You forgot to zero the "j" counter, so that it starts correctly in each row.
Cheers!

pascal number using while loop

I need to print the pascal number
1
1 1
1 2 1
1 3 3 1
etc.
import math
i = 0
j = 1
while j<6:
while i<6:
print(int(math.factorial(5)/(math.factorial(i)*math.factorial(5-i))), end=" ")
i += 1
print(int(math.factorial(j)/(math.factorial(i)*math.factorial(j-i))))
j += 1
it is stated that factorial cannot be negative, although I don't think it is negative.
Take a look at this code, this gives the correct output, even though you can work on making it pretty
n = 5
for j in range(1, n + 1):
row = 1
for i in range(1, j + 1):
print(row)
row = row * (j - i) // i
print(" ")
We know that ith entry in a row of the triange is binomial coefficiant of (j, i) and that all the rows must start with the number 1, and that's why this works. And ofcourse we do integer division.
The for loops can be replace with while loops as you see fit.

Max Value in List Array

The following code creates a list with entered values:
def locateLargest():
matrix = []
numberOfRows = int(input("Enter the number of rows: "))
numberOfColumns = 2
for row in range(0, numberOfRows):
matrix.append([])
for column in range(0, numberOfColumns):
value = int(input("Enter a value: "))
matrix[row].append(value)
max_value = None
for value in matrix:
if not max_value:
max_value = value
elif value > max_value:
max_value = value
print(max_value)
locateLargest()
The issue I am running into is that it is asking for each value individual in the row, and is returning the maximum pair of values in the row, not the maximum value's index.
The sample run of what I should be getting is:
Enter the number of rows in the list: 3
Enter a row: 23.5 35 2 10
Enter a row: 4.5 3 45 3.5
Enter a row: 35 44 5.5 11.6
The location of the largest element is at (1,2)
Any ideas?
My current output is:
Enter the number of rows: 2
Enter the number of columns: 6
Enter a value: 2
Enter a value: 2
Enter a value: 2
Enter a value: 2
Enter a value: 2
Enter a value: 2
Enter a value: 7
Enter a value: 6
Enter a value: 4
Enter a value: 3
Enter a value: 6
Enter a value: 2
[7, 6, 4, 3, 6, 2]
This is not very 'pythonic' but will help you achieve your end goal and hopefully understand the process. As Ɓukasz mentioned, you need to do an iteration for each row, and for each column in each row:
First declare the variable to store your location:
maxPoint = [0,0]
Then enumerate your matrix such that you can get the list from each row, but also retrieve the index of the currently active row:
for idx, row in enumerate(matrix):
Find the max value in the current list of values, ie: [10, 20, 30]
maxRowValue = max(row)
Find which column this maximum value lives in, ie: [0, 1, 2, ...]
maxRowIndex = row.index(maxRowValue)
Determine if max row value is in fact greater than any other previously located points, if it is less discard it:
if maxRowValue <= matrix[maxPoint[0]][maxPoint[1]]:
continue
If the value is greater, save it to the maxPoint variable:
maxPoint = [idx, maxRowIndex]
EDIT
For the sake of completeness, here is the complete code sample with AChampion's performance improvements added:
def locateLargest():
matrix = []
numberOfRows = int(input("Enter the number of rows: "))
numberOfColumns = 2
for row in range(0, numberOfRows):
matrix.append([])
for column in range(0, numberOfColumns):
value = int(input("Enter a value: "))
matrix[row].append(value)
maxPoint = [0,0]
for rIndex, row in enumerate(matrix):
cIndex, maxRowValue = max(enumerate(row), key=lambda x: x[1])
if maxRowValue <= matrix[maxPoint[0]][maxPoint[1]]:
continue
maxPoint = [rIndex, cIndex]
print(maxPoint)
locateLargest()
EDIT 2
Here is the same algorithm without using enumerate:
currentRow = 0
for row in matrix:
maxRowValue = max(row)
maxRowIndex = row.index(maxRowValue)
if maxRowValue > matrix[maxPoint[0]][maxPoint[1]]:
maxPoint = [currentRow, maxRowIndex]
currentRow += 1
Using enumerate() and some generator expressions, you can reduce this code quite a bit:
Generate the rows
Generate the maximum for each row
Find the maximum across all rows
More complex perhaps than some would like:
numberOfRows = int(input("Enter the number of rows: "))
# Generate the rows
rows = (map(int, input("Enter a row: ").split()) for _ in range(numberOfRows))
# Generate the maximum for each row
max_row = (max(enumerate(data), key=lambda x: x[1]) for data in rows)
# Find the maximum across all rows
i, (j, v) = max(enumerate(max_row), key=lambda x: x[1][1])
print("The location of the largest element is at {} [{}]".format((i, j), v))
Input / Output:
Enter the number of rows: 3
Enter a row: 1 2 3
Enter a row: 3 6 3
Enter a row: 1 2 3
'The location of the largest element is at (1, 1) [6]'
If you want to see what is going on change the generators to list comprehensions:
>>> rows = [list(map(int, input("Enter a row: ").split())) for _ in range(numberOfRows)]
Enter a row: 1 2 3
Enter a row: 3 6 3
Enter a row: 1 2 3
>>> rows
[[1, 2, 3], [3, 6, 3], [1, 2, 3]]
>>> max_row = [max(enumerate(data), key=lambda x: x[1]) for data in rows]
>>> max_row
[(2, 3), (1, 6), (2, 3)]
>>> list(enumerate(max_row))
[(0, (2, 3), (1, (1, 6)), (2, (2, 3))]
^^^^^^^^^
i, (j, v)

Resources