How to determine the maximum,minimum and average values of the matrix - python-3.x

I need to create a matrix, where the user can input his values and determine the maximum value of the matrix, the minimum value and the average value of all matrix's data
I created the matrix, where I can input my own values and I tried to write which could determine the maximum and minimum value. However, after several checks, I understood, that my piece of code, which determines max and min values, doesn't work.
line = int(input('Enter the amount of lines:'))
columns = int(input('Enter the amount of columns:'))
matrix = []
for i in range(0, columns):
matrix.append([])
for i in range(0, line):
for j in range(0, columns):
matrix[i].append(j)
matrix[i][j] = 0
for i in range(0, line):
for j in range(0,columns):
matrix[i][j] = int(input('Enter the value:'))
avg = matrix
for i in range(0, line):
for j in range(0, columns):
max_val = matrix[j]
min_val = matrix[j]
for j in range(0, len(matrix[j]), 1):
max_val = max(max_val, matrix[j])
min_val = min(min_val, matrix[j])
maxVal = max_val[0]
minVal = min_val[0]
for i in range(0, len(max_val), 1):
maxVal = max(maxVal, max_val[i])
minVal = min(minVal, min_val[i])
print(matrix)
print('The maximum value is ' + str(maxVal))
print('The minimum value is ' + str(minVal))
I excepted the result, which will print me the matrix, maximum value, minimum value and average value

One way of doing it with Python lists is this:
(I'll just do find_min(), as find_max() and compute_mean() would be pretty much the same.)
import random
def gen_random_matrix(rows, cols, min_val=1, max_val=100):
return [
[random.randint(min_val, max_val) for j in range(cols)]
for i in range(rows)]
def find_min(matrix):
rows = len(matrix)
cols = len(matrix[0])
min_i, min_j = 0, 0
min_val = matrix[min_i][min_j]
for i in range(rows):
for j in range(cols):
if matrix[i][j] < min_val:
min_i = i
min_j = j
min_val = matrix[i][j]
return min_val, min_i, min_j
random.seed(0)
matrix = gen_random_matrix(3, 4)
print(matrix)
# [[50, 98, 54, 6], [34, 66, 63, 52], [39, 62, 46, 75]]
print(find_min(matrix))
# (6, 0, 3)

Related

How is this possible? Maximum subarray sum

If there is arr = [1, 2, 3] so len(arr) is 3 right?
for i in range(0, len(arr)+1):
print(arr[i])
It is no secret that you can not do that, simply IndexError: list index out of range.
So how is this possible?
def max_sequence(arr):
if arr:
li = []
x = {sum(arr[i:j]): arr[i:j] for i in range(0, len(arr))
for j in range(1, len(arr)+1)}
li.append(max(x.items()))
for ii in li:
print(ii)
return li[0][0]
else:
return 0
print(max_sequence([26, 5, 3, 30, -15, -7, 10, 20, 22, 4]))
I simply had to find the maximum sum of a contiguous subsequence in a list of integers.
If I write this part:
x = {sum(arr[i:j]): arr[i:j] for i in range(0, len(arr))
for j in range(1, len(arr))}
It shows that maximum sum is 94, that is incorrect.
If I write this:
x = {sum(arr[i:j]): arr[i:j] for i in range(0, len(arr))
for j in range(1, len(arr)+1)}
Maximum sum is 98, it is correct. But why is so? If I write "for j in range(1, len(arr)+1)" why there is no IndexError?
We can generate a sequence of numbers using range() function. Range(10) will generate numbers from 0 to 9 (10 numbers).
We can also define the start, stop and step size as range(start, stop,step_size).
Here in your example, "for j in range(1, len(arr)+1)"
len(arr) is 10.
So range will generate numbers from 1 to 10.
Also, your li is an empty array so its length can be varied. You are storing the result i.e. the sum in li array as well as it will store the original array and this j will help it to store it.

Start counting indexes from 1 instead of 0 of a list

I created a program to get the the max value of a list and the position of its occurrences (list starting at indexing with 1 not 0) but I can't manage to find any useful solutions.
The input is always a string of numbers divided by zero.
This is my code:
inp = list(map(int,input().split()))
m = max(inp)
count = inp.count(m)
print(m)
def maxelements(seq): # #SilentGhost
return [i for i, j in enumerate(seq) if j == m]
print(maxelements(inp))
I expect to output the maximum value and then all the positions of its occurrences. (also is it possible to do without brackets as in the example below?)
Input: 4 56 43 45 2 56 8
Output: 56
2 6
If you want to shift index values, you could just do
return [i + 1 for i, j in enumerate(seq) if j == m]
more generally any transformation of i or j!
def f(i, j):
# do whatever you want, and return something
return i + 1
return [f(i, j) for i, j in enumerate(seq) if j == m]
Without brackets, as a string:
return " ".join(str(i + 1) for i, j in enumerate(seq) if j==m)
Specifiy start=1 with enumerate():
>>> l = [4, 56, 43, 45, 2, 56, 8]
>>> max_num = max(l)
>>> [i for i, e in enumerate(l, start=1) if e == max_num]
[2, 6]
By default enumerate() uses start=0, because indices start at 0.

How to compare the elements of a nested list?

I have some kind of matrix:
[[1,2,3],[1,2,3],[0,2,1],[1,2,3]] and I would like to be able to determine how many times I have the sequence 1,2,3 diagonally, vertically and horizontally but I have problems of index out of range for the last two loops. Thank you in advance for your answers!!
lista = [[1,2,3],[1,2,3],[0,2,1],[1,2,3]]
compteur_horizontal = 0
for i in range(len(lista)):
for c in range(len(lista[i])-2):
if lista[i][c] == 1 and lista[i][c+1] == 2 and lista[i][c+2] == 3:
compteur_horizontal += 1
print("ok")
compteur_vertical = 0
for c in range(len(lista)):
for j in range(len(lista[c])):
print(lista[j][c])
compteur_diagonale = 0
for j in range(len(lista)):
print(lista[i][i])
For the first counter, I would like it to be 3 since we have 3 times the sequence 1,2,3 horizontally. For the second counter, I would like it to be 0 because vertically there is no 1,2,3 sequence. And I'm waiting for a counter with 0 also since there's no 1,2,3 sequence in diagonal
Your code will not work even if you correct the current error. You need to change j and c in the second loop to resolve the error.
For horizontal and vertical here's the code. I'll add how to count diagonal ones later.
#lista = [[1, 2, 3],[1, 2, 3],[0, 2, 1],[1, 2, 3]]
lista = [[1,2,2],
[1,2,4],
[4,2,3],
[5,6,3]]
ptrn = [1, 2, 3]
# returns True is lst (1d array) has ptrn (1d array).
# e.g. lst[1,2,4,6,1,2,3,7], ptrn=[1,2,3] return True
# e.g. lst[1,2,4,6,1,4,3,7], ptrn=[1,2,3] return False
def is_pattern_in_a_list(lst, ptrn):
if ptrn[0] in lst:
idx = lst.index(ptrn[0])
for i in range(1, len(ptrn)):
if idx + i < len(lst):
if ptrn[i] != lst[idx+i]:
return False
else:
return False
return True
else:
return False
# counting horizontal occurances
count_h = 0
for row in lista:
if is_pattern_in_a_list(row, ptrn):
count_h += 1
# counting vertical occurances
# we first transpose the 2d array and use the same
# method of counting horizontal occurances.
def transpose_2d_array(a):
return [[a[j][i] for j in range(len(a))] for i in range(len(a[0]))]
lista_transpose = transpose_2d_array(lista)
count_v = 0
for row in lista_transpose:
if is_pattern_in_a_list(row, ptrn):
count_v += 1
# for diagonal occurances first we need to extract the diagonals
# with len >= len(ptrn).
# diagonals for the upper right triangle of the matrix:
count_d = 0
for i in range(len(lista[0])):
diag = []
j = 0
k = i
while j < len(lista)-i and k < len(lista[0]):
diag.append(lista[j][k])
j += 1
k += 1
if is_pattern_in_a_list(diag, ptrn):
count_d += 1
# diagonals for the lower left triangle of the matrix
i = len(lista) - 1
while i >= 1:
j = i
k = 0
diag = []
while j < len(lista) and k <= len(lista)+1-i:
diag.append(lista[j][k])
j += 1
k += 1
i -= 1
if is_pattern_in_a_list(diag, ptrn):
count_d += 1
print(diag)
print("Horizontal %d" % count_h)
print("Vertical %d" % count_v)
print("Diagonal %d" % count_d)

Optimization of CodeWars Python 3.6 code: Integers: Recreation One

I need help optimizing my python 3.6 code for the CodeWars Integers: Recreation One Kata.
We are given a range of numbers and we have to return the number and the sum of the divisors squared that is a square itself.
"Divisors of 42 are : 1, 2, 3, 6, 7, 14, 21, 42. These divisors squared are: 1, 4, 9, 36, 49, 196, 441, 1764. The sum of the squared divisors is 2500 which is 50 * 50, a square!
Given two integers m, n (1 <= m <= n) we want to find all integers between m and n whose sum of squared divisors is itself a square. 42 is such a number."
My code works for individual tests, but it times out when submitting:
def list_squared(m, n):
sqsq = []
for i in range(m, n):
divisors = [j**2 for j in range(1, i+1) if i % j == 0]
sq_divs = sum(divisors)
sq = sq_divs ** (1/2)
if int(sq) ** 2 == sq_divs:
sqsq.append([i, sq_divs])
return sqsq
You can reduce complexity of loop in list comprehension from O(N) to O(Log((N)) by setting the max range to sqrt(num)+1 instead of num.
By looping from 1 to sqrt(num)+1, we can conclude that if i (current item in the loop) is a factor of num then num divided by i must be another one.
Eg: 2 is a factor of 10, so is 5 (10/2)
The following code passes all the tests:
import math
def list_squared(m, n):
result = []
for num in range(m, n + 1):
divisors = set()
for i in range(1, int(math.sqrt(num)+1)):
if num % i == 0:
divisors.add(i**2)
divisors.add(int(num/i)**2)
total = sum(divisors)
sr = math.sqrt(total)
if sr - math.floor(sr) == 0:
result.append([num, total])
return result
It's more the math issue. Two maximum divisors for i is i itself and i/2. So you can speed up the code twice just using i // 2 + 1 as the range stop instead of i + 1. Just don't forget to increase sq_divs for i ** 2.
You may want to get some tiny performance improvements excluding sq variable and sq_divs ** (1/2).
BTW you should use n+1 stop in the first range.
def list_squared(m, n):
sqsq = []
for i in range(m, n+1):
divisors = [j * j for j in range(1, i // 2 + 1 #speed up twice
) if i % j == 0]
sq_divs = sum(divisors)
sq_divs += i * i #add i as divisor
if ((sq_divs) ** 0.5) % 1 == 0: #tiny speed up here
sqsq.append([i, sq_divs])
return sqsq
UPD: I've tried the Kata and it's still timeout. So we need even more math! If i could be divided by j then it's also could be divided by i/j so we can use sqrt(i) (int(math.sqrt(i)) + 1)) as the range stop. if i % j == 0 then append j * j to divisors array. AND if i / j != j then append (i / j) ** 2.

Python3 QR Factorization

I am fairly new to python3. I am trying to learn it on my free time before I take a class in the fall. This exercise has been the hardest I've tried. I am trying to take the code and rewrite it in simple form using for loops and not using NUMPY. The end game is to write the code that take a matrix as an argument and computes and prints the QR factorization using the modified schmidt algorithm. Any help would be appreciated. Thank you in advance.
#sample matrix
A = [[80,75,85],
[75,80,75],
[80,80,80]]
#function to find QR factorization of a square matrix
#parameter - matrix to be factorized
def findQRFactorization(A):
#check if A is a matrix
if any(isinstance(i,list) for i in A):
print("Is a matrix")
#number of rows and columns in A
rows = len(A)
cols = len(A[0])
print("rows:",rows," cols:",cols)
#check if A is square matrix
if rows != cols:
print("Not a square matrix. Aborting...")
else:
print("A square matrix. proceeding...")
#create an Identiry matrix of size rows x cols
I = [[0]*cols for i in range(rows)]
for i in range(rows):
I[i][i] = 1
#print(I)
#calculation of QR factorization based on householder reflection method
#QR factorization represents A as A = QR where Q is a orthogonal matrix
#while R is a upper triangular matrix.
#Initialize Q and R
Q = [[0.0] * cols for i in range(rows)]
R = A
#print("Q:",Q)
#print("R:",R)
#loop to perform QR factorization
for k in range(rows-1):
#calculate x, e
x = [row[k] for row in R[k:]]
e = [row[k] for row in I[k:]]
#calculate norm of x
norm_x = math.sqrt(sum([i**2 for i in x]))
#print("norm x:",norm_x)
#calculate alpha
sign = lambda x: (1, -1)[x < 0]
alpha = -sign(x[0])*norm_x
#print('alpha:',alpha)
#calculate minor matrix of u and v
u = list(map(lambda i,j: i + alpha * j, x, e))
norm_u = math.sqrt(sum([i**2 for i in u]))
v = list(map(lambda i: i/norm_u, u))
#calculate Q
Q_minor = [ [float(i==j) - 2.0 * v[i] * v[j] for i in range(rows-k)] for j in range(cols-k) ]
def Q_identity(Q_minor,i,j,k):
if i < k or j < k:
return float(i == j)
else:
return Q_minor[i-k][j-k]
Q_padded = [[Q_identity(Q_minor,i,j,k) for i in range(rows)] for j in range(cols)]
#update Q and R
def multiply(P,Q):
return [[sum(elemp * elemq for elemp, elemq in zip(rowp, colq)) for colq in zip(*Q)] for rowp in P]
if k == 0:
Q = Q_padded
R = multiply(Q_padded,A)
else:
Q = multiply(Q_padded,Q)
R = multiply(Q_padded,R)
#calculate transpose of Q
Q_dash = [[Q[i][j] for i in range(cols)] for j in range(rows)]
print("QR factorization of ",A)
print("Q: ",Q_dash)
print("R: ",R)
else:
print("Not a matrix. QR factorization not possible.")
#call function
findQRFactorization(A)

Resources